使用pytest

时间:2016-09-25 11:24:19

标签: python testing pytest fixture

可以从命令行参数中参数化测试函数。 可以将作用域限定为类。 我想把这两件事结合起来,这样每个类都会接收给出类中fixture的参数化参数。

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

换句话说,我正在寻找与pytest_generate_tests(metafunc)相当的东西,它可以用于动态地参数化一个灯具,而不是一个测试函数。

我已经尝试过的一件事就是读取请求参数并通过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 个答案:

答案 0 :(得分: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),然后抓住我的脑袋,想知道为什么driver()永远不会被召唤。假人的意思是,"嘿,这里有一个合法的固定装置,不要抱怨你找不到它!"然后总是抢先一步用一些实际上有用的东西。

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