2

为什么我无法在 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 移动到我的所有测试中很麻烦。有什么更好的方法来做到这一点?

4

2 回答 2

1

正如文档所说:

在类中对测试进行分组时需要注意的是,每个测试都有一个唯一的类实例。让每个测试共享相同的类实例对测试隔离非常不利,并且会促进不良的测试实践。

我建议像这样使用类范围夹具:

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
于 2020-08-24T09:28:08.930 回答
0

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

class TestClass:
    @classmethod
    def setup_class(cls):
        cls.param = 2

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

虽然如果您想使用pytest fixtures,您可以制作一个fixture 并将其作为参数传递给您需要的测试,我相信这更符合pytest 打算使用fixtures 的方式:

import pytest

@pytest.fixture
def my_param():
    return 2

class TestClass:
    def test_one(self, my_param):
        assert my_param == 2
于 2020-08-23T23:12:58.787 回答