使用 pytest 参数化 class 测试
Parametrize class tests with pytest
我的测试 class 中的每个测试都需要 运行 对象数组。我想参数化 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
但据我了解,您不能传递输入参数,或者至少不能在 class 上调用 @pytest.mark.parametrize
,这些标记是针对 defs
而不是 class
s
我现在拥有的:
class TestClass:
def test_something1(self):
for i in stuff:
# test code here
def test_something2(self):
for i in stuff:
# test code here
...
有没有办法传递参数化 a class 本身或 TestClass 中的每个函数? 也许 @pytest.mark.parametrize
inside a @pytest.fixture...(autouse=True).
我想将我的测试组织成 class,因为它反映了我正在测试的文件。因为我在至少十几个不同的测试中循环遍历这些对象,所以调用 class 的循环比在每个 def
.
中调用循环更容易
我已经解决了。我把它复杂化了;除了使用标记,我还可以使用传入参数的夹具函数。
在我找到答案之前(没有参数化):
class TestClass:
def test_something(self):
for i in example_params:
print(i)
回答,使用pytest fixture。会做同样的事情,但只需要输入,而不是 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)
因此,要参数化所有 def
s:
- 在
def my_function(request)
上使用 @pytest.fixture(params=[])
装饰器
- 里面
my_function
, return request.param
- 将
my_function
添加到要参数化的任何函数的输入中
您可以将 parametrize
应用于 classes。来自 the docs:
@pytest.mark.parametrize
allows one to define multiple sets of arguments and fixtures at the test function or class.
相同的数据将发送到 class 中的所有测试方法。
@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
如果您 运行 使用 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 =========================================================================================
这正是您想要的。
我的测试 class 中的每个测试都需要 运行 对象数组。我想参数化 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
但据我了解,您不能传递输入参数,或者至少不能在 class 上调用 @pytest.mark.parametrize
,这些标记是针对 defs
而不是 class
s
我现在拥有的:
class TestClass:
def test_something1(self):
for i in stuff:
# test code here
def test_something2(self):
for i in stuff:
# test code here
...
有没有办法传递参数化 a class 本身或 TestClass 中的每个函数? 也许 @pytest.mark.parametrize
inside a @pytest.fixture...(autouse=True).
我想将我的测试组织成 class,因为它反映了我正在测试的文件。因为我在至少十几个不同的测试中循环遍历这些对象,所以调用 class 的循环比在每个 def
.
我已经解决了。我把它复杂化了;除了使用标记,我还可以使用传入参数的夹具函数。
在我找到答案之前(没有参数化):
class TestClass:
def test_something(self):
for i in example_params:
print(i)
回答,使用pytest fixture。会做同样的事情,但只需要输入,而不是 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)
因此,要参数化所有 def
s:
- 在
def my_function(request)
上使用 - 里面
my_function
,return request.param
- 将
my_function
添加到要参数化的任何函数的输入中
@pytest.fixture(params=[])
装饰器
您可以将 parametrize
应用于 classes。来自 the docs:
@pytest.mark.parametrize
allows one to define multiple sets of arguments and fixtures at the test function or class.
相同的数据将发送到 class 中的所有测试方法。
@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
如果您 运行 使用 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 =========================================================================================
这正是您想要的。