首页 文章

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

提问于
浏览
1

我的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

    如果您希望它创建一组每个会话创建一次的灯具,重复用于每个测试然后拆除,那么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
    

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

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

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

    EDIT

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

    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 来获取它们 . 你可以判断什么更有意义并且产生最少的样板 .

相关问题