首页 文章

使用pytest动态参数化类级别的灯具

提问于
浏览
1

可以从命令行参数中参数化测试函数 . 可以将作用域限定为类 . 我希望将这两个东西结合起来,以便每个类接收给出类中fixture的参数化参数 .

(基本上,根据命令行参数,我需要运行一个非常昂贵的操作,然后针对该操作的结果进行各种廉价,快速的测试,并且我不希望为每个便宜的测试重新运行昂贵的操作,所以我想要一种方法来保存它)

换句话说,我正在寻找一个等效于pytest_generate_tests(metafunc),它可以用于动态地参数化一个fixture,而不是一个测试函数 .

我已经尝试过的一件事就是读取请求参数并通过pytest_generate_tests钩子设置它们 .

conftest.py:
    def pytest_generate_tests(metafunc):
        metafunc.parametrize("result", [
                (1,0),(1,2)
            ])

test_thing.py:
    class TestThingy:
        @pytest.fixture(scope="class")
        def result(self, request):
            a,b=request.param
            return a+b

    #@pytest.mark.parametrize("result", [(0, 1), (1, 2)])
    def test_one(self, result):
        assert result!=2

运行此测试会导致出现以下错误(请注意,当我尝试使用没有conftest挂钩且注释行未注释时,测试运行正常):

@pytest.fixture(scope="class")
def result(self, request):
    a,b=request.param

AttributeError:'SubRequest'对象没有属性'param'

我也对任何其他方法感兴趣,以获得相同的结果 .

1 回答

  • 2

    我在基于命令行参数的参数化参数化方面做了一个丑陋的工作:

    # contents of conftest.py
    import pytest
    
    def pytest_addoption(parser):
        parser.addoption("--test-local", action="store_true", default=False)
    
    def pytest_generate_tests(metafunc):
        if "dummy" in metafunc.fixturenames:
            #driverParams sets dummy[0], dummy[1] parametrically (as seen below)
            if metafunc.config.getoption("--test-local"):
                driverParams = [(True, None)]
            else:
                driverParams = [(False, "seriousface setting 1"), 
                                (False, "seriousface setting 2")]
            metafunc.parametrize("dummy", driverParams)
    
    #driver can then be used as a standard fixture
    @pytest.fixture(scope="function")
    def driver(dummy):
        _driver = makeDriverStuff(dummy[0], dummy[1])
        yield _driver
        _driver.cleanup()
    
    @pytest.fixture(scope="function")
    def dummy():
        pass
    

    基本上这里发生的是当 metafunc.parametrize("dummy", driverParams) 运行时,它会将 driverParams 扔进任何依赖虚拟装置的东西 . 更重要的是,这意味着虚拟夹具功能永远不会实际执行 .

    最初,我尝试使用metafunc直接参数化我的驱动程序夹具,并注意到清理从未发生过,因为之前我做事的(错误的)方式是 metafunc.parametrize 直接用 makeDriverStuff(param1, param2) ,然后 grab 我的脑袋想知道为什么 driver() 永远不会得到调用 . 假人的意思是说"Hey, there's a legit fixture here, don't complain that you can't find it!",然后总是先用实际有用的东西抢占它 .

    就像我说的,这是一个丑陋的黑客 . 但是你应该能够适应它

相关问题