总的来说有如下三种方法来实现多次执行同一个test function。
- 利用@pytest.fixture()的 params 功能
- 利用@pytest.mark.parametrize()
- 利用pytest hook pytest-generate-tests 的功能
请参照下面的例子来理解这三种方法。
利用@pytest.fixture()的 params 功能
#test_demo1.py
import pytest
@pytest.fixture(params=["data1", "data2", "data3"])
def test_data(request):
return request.param
@pytest.fixture(params=["id1", "id2", "id3"])
def testid(request):
return request.param
def test_1(test_data, testid):
print(f"test_data is {test_data}-- {testid}")
pass
如果执行`pytest test_demo1.py -s -v`, 上面这个例子`test_1` 函数将会执行9次, test_data list * testid list.
利用@pytest.mark.parametrize()
#test_demo2.py
import pytest
dlist = [
['data1', 'id1'], ['data2', 'id2'], ['data3', 'id3']
]
@pytest.mark.parametrize("test_data, testid", dlist)
def test_1(test_data, testid):
print(f"test_data is {test_data}-- {testid}")
pass
@pytest.mark.parametrize(["test_data", "testid"], dlist)
def test_2(test_data, testid):
print(f"test_data is {test_data}-- {testid}")
pass
help(metafunc.parametrize)
Help on method parametrize in module _pytest.python:
parametrize(argnames: Union[str, List[str], Tuple[str, ...]], argvalues: Iterable[Union[_pytest.mark.structures.ParameterSet, Sequence[object], object]], indirect: Union[bool, Sequence[str]] = False, ids: Union[Iterable[Optional[object]], Callable[[Any], Optional[object]], NoneType] = None, scope: 'Optional[_ScopeName]' = None, *, _param_mark: Optional[_pytest.mark.structures.Mark] = None) -> None
在test_demo2.py 的例子中, 有两种@pytest.mark.parametrize() 的用法, 具体可以支持的参数类型, 可以参见 mark.parametrize signature。
在test_demo2.py 的例子中, test_data", "testid" fixture 分别有三组参数。 所有test_1()和test_2() 都会被个执行3次。
利用pytest hook pytest-generate-tests 的功能
#test_demo3.py
def pytest_generate_tests(metafunc):
dlist = [
['data1', 'id1'],['data2','id2'],['data3','id3']
]
metafunc.parametrize(["test_data", 'testid'], dlist)
def test_1(test_data, testid):
print(f"test_data is {test_data}-- {testid}")
pass
-
metafunc.parametrize()的参数用法跟上面的@pytest.mark.parametrize() 是一样的。
-
pytest_generate_tests() hook的参数是metafunc。你一定很好奇metafunc 是啥, 哪里来的。metafunc是一个Metafunc class 的实例。下面是metafunc 的介绍
final class Metafunc
Objects passed to the pytest_generate_tests hook.
They help to inspect a test function and to generate tests according to test configuration or values specified in the
class or module where a test function is defined.
总结, 这三种方法都可以达到参数化执行test function的效果。 具体怎么选择, just a choice.