何时使用 TestClass 实例变量与 Pytest Fixtures

When to use TestClass instance variables vs Pytest Fixtures

什么时候使用 Pytest fixture 与实例变量比较合适?

假设我有一个很大的预期 JSON 输出存储在本地,几个测试使用。以下哪种方法更合适?我可以看到对象的状态在测试之间保持不变。

@pytest.fixture
def expected_output():
    return <fixture>

def test_1(expected_output):
    <do something>
    assert output == expected_output

def test_2(expected_output):
    <do something>
    assert output == expected_output
class SomeTestClass(TestCase):
    def setUp(self):
        self.expected_output = <fixture>

    def test_1(self):
        <do something>
        self.assertEqual(output, self.expected_output)

    def test_2(self):
        <do something>
        self.assertEqual(output, self.expected_output)

我梳理了 Pytest 文档,但似乎不明白其中的区别。拥有实例变量似乎带来了固定装置的很多好处——即跨测试共享值。

您已经在示例中展示的第一个区别:夹具不需要测试 class。

如果使用测试class,也可以使用pytest中的setup方法,不需要使用unittest.TestCase:

class SomeTestClass:
    def setup_method(self):
        self.expected_output = <fixture>

    def test_1(self):
        <do something>
        assert output == self.expected_output

这在 pytest 中被描述为 classic xunit-style setup。来自该文档:

While these setup/teardown methods are simple and familiar to those coming from a unittest or nose background, you may also consider using pytest’s more powerful fixture mechanism which leverages the concept of dependency injection, allowing for a more modular and more scalable approach for managing test state, especially for larger projects and for functional testing. You can mix both fixture mechanisms in the same file but test methods of unittest.TestCase subclasses cannot receive fixture arguments.

一般来说,我建议不要将 unittestpytest 混合用于新的测试代码。 unittest 中没有什么是 pytest 无法完成的,但是您不能 运行 unittest 反对使用 pytest 功能的测试。

在您的具体示例中,您实际上不需要实例变量,因为预期输出不会随测试而改变。您可以静态声明变量并使用它(在 classes 内部或外部),或者您可以使用 class 变量(并使用 setup_class 将其设置为 pytest).

对于这个简单的例子,使用哪个概念可能没有真正的区别,但是如果您需要 setupteardown,fixture 会更有帮助,因为它们同时提供:

@pytest.fixture
def some_resource():
    resource = acquire_resource()
    yield resource
    free(resource)

最后,在可以使用两种变体的情况下没有 "appropriate" 选择,但使用固定装置总是感觉更一致 - 一种机制而不是两种不同的机制 - 它是 pytest 方式。并非最不重要的因素 - 大多数使用 pytest 的人在这些情况下都使用固定装置,因此如果您使用相同的装置,寻求帮助和共享代码会更容易。