在pytest中管理许多会话范围的灯具

时间:2016-03-08 13:07:04

标签: python pytest fixtures

我的conftest.py中有以下代码

import pytest

@pytest.fixture(scope="class")
def fix1():
   print("i am in fix1")
   a = 10
   return a

@pytest.fixture(scope="class")
def fix2():
   print("i am in fix2")
   b = 20
  return b

@pytest.fixture(scope="session",autouse=True)
def setup_session(request):
    tp = TestSetup(fix1)
    tp.setup()
    def teardown_session():
      tp.teardown()
    request.addfinalizer(teardown_session)

class TestSetup(object):
    def __init__(self, fix1, fix2):
        self.fix1 = fix1
        self.fix2 = fix2
    def setup(self):
        print("i am in setup")
        print(self.fix1)
   def teardown(self):
       print("I am in teardown")
       print(self.fix2)

   # py.test -s test1.py 
   =========== test session starts ===========
   platform linux2 -- Python 2.7.5, pytest-2.8.5, py-1.4.31, pluggy-0.3.1
   rootdir: /tmp/test, inifile: 
   collected 2 items 

   test1.py i am in setup
   <function fix1 at 0x2948320>
   i am in test1
   .i am in test2
   .I am in teardown

当我使用pytest执行上述操作时,从不调用fixtures fix1和fix2。在我的任何测试运行之前,我需要一种方法来调用fix1和fix2作为设置和拆卸的一部分。

我试图实现的是在我的任何测试运行之前,我需要创建一个设置,fix1和fix2是固定设置的东西。我希望在我的任何测试运行之前调用这些夹具,并且一旦所有测试都运行,我就会调用拆卸功能来拆除我的设置。

1 个答案:

答案 0 :(得分:0)

如果您希望它创建一组每个会话创建一次的灯具,重复用于每个测试然后拆除,那么py.test方法就是:

import pytest

@pytest.fixture(scope="session")
def fix1(request):
    # setup code here
    print('creating fix1')
    a = 10
    def teardown_fix1():
        # teardown code here
        print('destroying fix1')
        a = None
    request.addfinalizer(teardown_fix1)
    return a

def testOne(fix1):
    print('in testOne')
    assert fix1 == 10

def testTwo(fix1):
    print('in testTwo')
    assert fix1 != 20

(您已经知道如何执行此操作,如您的代码所示,所以这里没有新内容)。

你可以使用这些会话作用域中的几个,并且它们是会话作用域的事实保证它们将被创建一次,然后在测试运行结束时被拆除。

没有必要设置一个主设置功能来设置每个夹具,而另一个设置功能会将它们拆掉,而不是需要将这些功能分离到他们自己的小工厂功能中,并使用如图所示的终结器。

修改

但也许有很多灯具看起来几乎相同,你想重用一些代码。在这种情况下,您可以拥有一个管理灯具的类,并使其成为pytest灯具。然后你声明依赖于管理器的其他pytest灯具,每个灯具返回一个特定的灯具:

import pytest

class FixtureManager:
    def __init__(self):
        self.fixtures = {}

    def setup(self):
        print('setup')
        self.fixtures['fix1'] = self.createFixture('fix1')
        self.fixtures['fix2'] = self.createFixture('fix2')
        self.fixtures['fix3'] = self.createFixture('fix3')

    def get(self, name):
        return self.fixtures[name]

    def teardown(self):
        print('teardown')
        for name in self.fixtures.keys():
            # whatever you need to do to delete it
            del self.fixtures[name]

    def createFixture(self, name):
        # whatever code you do to create it
        return 'Fixture with name %s' % name

@pytest.fixture(scope="session")
def fixman(request):
    fixman = FixtureManager()
    fixman.setup()
    request.addfinalizer(fixman.teardown)
    return fixman

@pytest.fixture
def fix1(fixman):
    return fixman.get('fix1')

@pytest.fixture
def fix2(fixman):
    return fixman.get('fix2')

def testOne(fix1):
    print('in testOne')
    assert fix1 == 'Fixture with name fix1'

def testTwo(fix2):
    print('in testTwo')
    assert fix2 == 'Fixture with name fix2'

当然,您可以取消创建fix1fix2 pytest灯具,然后通过将fixman注入测试函数并调用get来获取这些灯具。那里。你可以判断什么更有意义并且产生最少的样板。