如何让pytest dependency仅在依赖测试实际运行时生效?
解决方法
咱们可以用pytest的钩子函数pytest_collection_modifyitems来实现你要的效果:在测试收集阶段检查本次运行的测试里有没有test_a,如果没包含,就把test_b的依赖标记去掉,让它能正常跑。
第一步:添加conftest.py文件
在你的测试文件所在目录新建conftest.py,把下面的代码放进去:
def pytest_collection_modifyitems(config, items): # 检查本次要运行的测试中是否包含test_a has_test_a = any(item.name == "test_a" for item in items) if not has_test_a: # 找到test_b并移除它的dependency依赖参数 for item in items: if item.name == "test_b": for marker in item.iter_markers(name="dependency"): marker.kwargs.pop("depends", None)
第二步:原测试代码保持不变
你的测试代码不用做任何修改,依然是:
import pytest @pytest.mark.dependency @pytest.mark.test_a def test_a(): # 你的测试逻辑 assert True @pytest.mark.dependency(depends=["test_a"], reason="Skipped since test_a failed") @pytest.mark.test_b def test_b(): # 你的测试逻辑 assert True
实际效果
- 正常运行所有测试(不带标记),或者用
-m test_a运行时,test_b的依赖规则正常生效:如果test_a失败,test_b会被跳过。 - 用
-m test_b单独运行test_b时,因为本次运行集合里没有test_a,钩子函数会移除test_b的依赖参数,test_b会直接执行,不会被跳过。
更贴合标记场景的写法
如果你想严格针对-m test_b的场景处理,也可以把钩子函数改成下面这样:
def pytest_collection_modifyitems(config, items): # 获取本次运行指定的标记表达式 mark_expr = config.getoption("-m") # 只有当明确指定只跑test_b标记的测试时,才移除依赖 if mark_expr == "test_b": for item in items: if item.name == "test_b": for marker in item.iter_markers(name="dependency"): marker.kwargs.pop("depends", None)
内容的提问来源于stack exchange,提问作者Avi Elgal
相关产品推荐
相关产品推荐

