使用 pytest 参数化类测试

Com*_*sky 4 python pytest python-3.x

我有一组对象,我需要为我的测试类中的每个测试运行这些对象。我想参数化 TestClass 中的每个测试函数。最终目标是有类似的东西:

@pytest.mark.parametrize('test_input', [1, 2, 3, 4])
class TestClass:
    def test_something1(self, test_input):
        # test code here, runs each time for the parametrize
Run Code Online (Sandbox Code Playgroud)

但是根据我的理解,您不能传递输入参数,或者至少不能调用@pytest.mark.parametrize一个类,这些标记用于defsnot classs

我现在所拥有的:

class TestClass:
    def test_something1(self):
        for i in stuff:
            # test code here

    def test_something2(self):
        for i in stuff:
            # test code here
    ...
Run Code Online (Sandbox Code Playgroud)

有没有办法传递参数化类本身或 TestClass 中的每个函数?也许一个@pytest.mark.parametrize里面@pytest.fixture...(autouse=True).

我想将我的测试组织成一个类,因为它反映了我正在测试的文件。因为我在至少十几个不同的测试中循环这些对象,所以调用类的循环比在每个def.

lmi*_*asf 18

你可以申请parametrize上课。从文档

@pytest.mark.parametrize允许在测试函数或类中定义多组参数和装置。

相同的数据将发送到类中的所有测试方法。

@pytest.mark.parametrize('test_input', [1, 2, 3, 4])
class TestClass:
    def test_something1(self, test_input):
        pass


    def test_something2(self, test_input):
        pass
Run Code Online (Sandbox Code Playgroud)

如果您使用以下命令运行测试,pytest -v您将获得以下输出:

=========================================================================================== test session starts ============================================================================================
platform darwin -- Python 3.7.3, pytest-4.4.2, py-1.8.0, pluggy-0.11.0 -- /Users/user/.local/share/virtualenvs/stack-overlfow-pycharm-L-07rBZ9/bin/python3.7
cachedir: .pytest_cache
rootdir: /Users/user/Documents/spikes/stack-overlfow-pycharm
collected 8 items

test_class.py::TestClass::test_something1[1] PASSED                                                                                                                                                  [ 12%]
test_class.py::TestClass::test_something1[2] PASSED                                                                                                                                                  [ 25%]
test_class.py::TestClass::test_something1[3] PASSED                                                                                                                                                  [ 37%]
test_class.py::TestClass::test_something1[4] PASSED                                                                                                                                                  [ 50%]
test_class.py::TestClass::test_something2[1] PASSED                                                                                                                                                  [ 62%]
test_class.py::TestClass::test_something2[2] PASSED                                                                                                                                                  [ 75%]
test_class.py::TestClass::test_something2[3] PASSED                                                                                                                                                  [ 87%]
test_class.py::TestClass::test_something2[4] PASSED                                                                                                                                                  [100%]

========================================================================================= 8 passed in 0.03 seconds =========================================================================================
Run Code Online (Sandbox Code Playgroud)

这正是您想要的。

  • 不幸的是,如果您的测试类继承自“unittest.TestCase”(在某些情况下可能需要),则这不起作用。 (6认同)

Com*_*sky 5

我已经解决了。我把它过于复杂化了;我可以使用传入参数的固定功能,而不是使用标记。

在我找到答案之前(没有参数化):

class TestClass:
    def test_something(self):
        for i in example_params:
            print(i)
Run Code Online (Sandbox Code Playgroud)

答案是,使用 pytest 夹具。会做同样的事情,但只需要输入,而不是 for 循环:

import pytest
example_params = [1, 2, 3]

@pytest.fixture(params=example_params)
def param_loop(request):
    return request.param

class TestClass:
    def test_something(self, param_loop):
        print(param_loop)
Run Code Online (Sandbox Code Playgroud)

因此,要参数化所有defs:

  1. @pytest.fixture(params=[])在 a 上使用装饰器def my_function(request)
  2. 里面my_functionreturn request.param
  3. 将 添加my_function到您想要参数化的任何函数的输入