同一Python脚本两次调用pytest.main时参数化值未更新的问题求助
问题描述
我编写了一个会两次调用pytest.main()的脚本,其中有个测试用例需要在每次pytest会话中使用不同的参数化值。我在@pytest.mark.parametrize装饰器里调用get_time()函数生成参数:
测试代码:
import datetime import pytest def get_time(): time_list = [datetime.datetime.now().second, datetime.datetime.now().second + 1] return time_list @pytest.mark.parametrize('time',get_time()) def test_1(time): print(time)
主脚本:
import pytest sq = ["--collect-only", # pytest参数 "rx_setup_tests/test_twice_parametrize.py::test_1", ] pytest.main(sq) sq = ["--collect-only", # pytest参数 "rx_setup_tests/test_twice_parametrize.py::test_1", ] pytest.main(sq)
但get_time()仅被调用一次,第二次pytest会话的参数化值与第一次完全相同,求解决办法。
问题根源
@pytest.mark.parametrize是在模块导入阶段执行的——测试脚本第一次被加载时,get_time()就会运行并生成参数。由于两次pytest.main()在同一个Python进程里执行,测试模块只会被导入一次,因此参数不会重新生成。
解决方法
方法1:使用pytest_generate_tests钩子函数(推荐)
这是pytest官方支持的动态参数生成方式,钩子函数会在每次pytest会话的测试收集阶段触发,能确保每次都生成新参数。修改测试代码如下:
import datetime import pytest def get_time(): time_list = [datetime.datetime.now().second, datetime.datetime.now().second + 1] return time_list def pytest_generate_tests(metafunc): # 仅为包含time参数的测试用例生成参数 if "time" in metafunc.fixturenames: metafunc.parametrize("time", get_time()) def test_1(time): print(time)
方法2:每次调用前重新加载测试模块
如果不想修改测试代码,可以在主脚本中每次调用pytest.main()前,强制清除测试模块的缓存并重新导入:
import pytest import importlib import sys # 测试模块对应的模块名(根据路径转换) test_module_name = "rx_setup_tests.test_twice_parametrize" # 第一次执行pytest sq = ["--collect-only", "rx_setup_tests/test_twice_parametrize.py::test_1"] pytest.main(sq) # 卸载并重新加载测试模块 if test_module_name in sys.modules: del sys.modules[test_module_name] importlib.import_module(test_module_name) # 第二次执行pytest sq = ["--collect-only", "rx_setup_tests/test_twice_parametrize.py::test_1"] pytest.main(sq)
内容的提问来源于stack exchange,提问作者Nadav Chernin
相关产品推荐
相关产品推荐

