pytest:在测试用例不可见的灯具中分配属性

问题描述

为什么我不能在pytest固定装置中设置self.param值?


class TestClass:
    @pytest.fixture(scope='class',autouse=True)
    def setup_class(self,test_env):
        self.param = 2

    def teardown_method(self):
        remove_setting(self.param)
    
    def test_one(self):
        assert self.param == 2

    def test_two(self):
        assert len("hello") == 5

这导致

scratch.py::TestClass::test_one Failed                                 

    def test_one(self):
>       assert self.param == 2
E       AttributeError: 'TestClass' object has no attribute 'param'

    def teardown_method(self):
>       remove_setting(self.param)
E       AttributeError: 'TestClass' object has no attribute 'param'

我想在设置过程中设置此属性,因为我最终将使用该参数执行方法级拆解(不是类级拆解,因此我不使用yield)。在此示例中,我的测试看不到self.param值,我的拆卸函数也看不到。将self.param = 2移到我所有的测试中很麻烦。有什么更好的方法

解决方法

docs说:

要在类内部对测试进行分组时需要注意的一点是,每个测试都具有该类的唯一实例。每个测试共享同一个类实例将对测试隔离非常不利,并会导致不良的测试实践。

我建议使用这样的类作用域夹具:

import pytest

@pytest.fixture(scope='module')
def test_env():
    pass

@pytest.fixture(scope='class')
def param(test_env):
    return 2


class TestClass:
    def test_one(self,param):  # All tests methods share the same param
        assert param == 2

    def test_two(self,param):
        assert param == 3
,

您正在尝试实现classic xunit-style setup,因此我不太确定要将设置作为pytest固定装置的目的。因此,一种解决方案将是以下代码片段:

p.pop_back()

尽管您打算使用pytest fixtures,也可以制作一个固定装置并将其作为参数传递给所需的测试,我认为这与pytest的意图更加一致对于要使用的灯具:

vector<T> solution