使用pytest-order时如何重复运行完整pytest测试会话?
如何在保留pytest-order标记的同时,让pytest-repeat按会话级重复(123123顺序)执行测试?
问题描述
我需要用pytest-repeat重复整个测试会话,让测试按1→2→3→1→2→3的顺序执行,但结合pytest-order的@pytest.mark.order标记时,即使加了--repeat-scope=session参数,得到的执行顺序却是1→1→2→2→3→3。移除pytest-order标记后能正常得到预期顺序,但我不能移除这些标记。
根据pytest-repeat文档:
"您可以使用--repeat-scope命令行选项……session作用域会重复整个测试会话,即先执行所有收集到的测试一次,再重复执行所有测试,以此类推。"
带pytest-order的测试代码
import pytest @pytest.mark.order(1) def test_one(): assert False, "1" @pytest.mark.order(2) def test_two(): assert False, "2" @pytest.mark.order(3) def test_three(): assert False, "3"
异常运行结果(命令:pytest test_repeat.py --no-header --tb=no --count 2 --repeat-scope session)
... ======================== short test summary info ======================== FAILED test_repeat.py::test_one[1-2] - AssertionError: 1 FAILED test_repeat.py::test_one[2-2] - AssertionError: 1 FAILED test_repeat.py::test_two[1-2] - AssertionError: 2 FAILED test_repeat.py::test_two[2-2] - AssertionError: 2 FAILED test_repeat.py::test_three[1-2] - AssertionError: 3 FAILED test_repeat.py::test_three[2-2] - AssertionError: 3 ======================== 6 failed in 0.03s ========================
移除pytest-order后的正常结果
======================== test session starts ======================== FAILED test_repeat.py::test_one[1-2] - AssertionError: 1 FAILED test_repeat.py::test_two[1-2] - AssertionError: 2 FAILED test_repeat.py::test_three[1-2] - AssertionError: 3 FAILED test_repeat.py::test_one[2-2] - AssertionError: 1 FAILED test_repeat.py::test_two[2-2] - AssertionError: 2 FAILED test_repeat.py::test_three[2-2] - AssertionError: 3 ======================== 6 failed in 0.04s ========================
解决办法
冲突根源是插件执行顺序:pytest-repeat先复制测试用例,pytest-order再对所有复制后的用例整体排序,导致同一测试的多次重复实例被排在一起。下面是几种可行的解决方案:
方案1:修改pytest-order的排序作用域
在项目根目录的pytest.ini或tox.ini中添加以下配置,让pytest-order在pytest-repeat复制用例前就完成会话级排序:
[pytest] pytest_ordering_sort_scope = session
之后再用原来的命令运行,就能得到123123的执行顺序。
方案2:添加命令行参数临时修改排序作用域
不想改配置文件的话,直接在运行命令里加--order-scope=session参数:
pytest test_repeat.py --no-header --tb=no --count 2 --repeat-scope session --order-scope=session
方案3:自定义钩子手动实现排序+重复(兼容旧版本插件)
如果上面的方案无效,在项目的conftest.py中添加以下代码,手动先按pytest-order标记排序,再复制测试序列:
import pytest def pytest_collection_modifyitems(items): # 按order标记排序 items.sort(key=lambda x: x.get_closest_marker("order").args[0] if x.get_closest_marker("order") else float('inf')) # 处理重复逻辑 count = int(pytest.config.getoption("--count", 1)) if count > 1: repeated_items = [] for _ in range(count): repeated_items.extend(items.copy()) items[:] = repeated_items
然后运行时不需要加--repeat-scope,直接用--count参数即可:
pytest test_repeat.py --no-header --tb=no --count 2
验证结果
使用上述任一方案后,运行结果会变成预期的顺序:
======================== test session starts ======================== FAILED test_repeat.py::test_one[1-2] - AssertionError: 1 FAILED test_repeat.py::test_two[1-2] - AssertionError: 2 FAILED test_repeat.py::test_three[1-2] - AssertionError: 3 FAILED test_repeat.py::test_one[2-2] - AssertionError: 1 FAILED test_repeat.py::test_two[2-2] - AssertionError: 2 FAILED test_repeat.py::test_three[2-2] - AssertionError: 3 ======================== 6 failed in 0.04s ========================
内容的提问来源于stack exchange,提问作者D.Pod
相关产品推荐
相关产品推荐

