pytest
是 Python 中一个功能强大且灵活的测试框架,它允许开发者编写简洁、可读性高的测试代码。在运行测试时,pytest
遵循一定的顺序规则来执行测试函数、测试类和测试模块。以下是 pytest
运行顺序的详细解析:
1. 默认运行顺序
pytest
默认按照以下顺序执行测试:
- 按文件名的字母顺序:
pytest
会按照测试文件的文件名(ASCII 顺序)依次加载和执行。- 例如:
test_a.py
会先于test_b.py
执行。
- 按测试函数/方法的定义顺序:
- 在同一个文件中,
pytest
会按照测试函数或测试方法的定义顺序依次执行。 - 例如:
会先执行def test_first(): pass def test_second(): pass
test_first
,再执行test_second
。
- 在同一个文件中,
2. 控制运行顺序
如果希望自定义测试的运行顺序,可以使用以下方法:
2.1 使用 pytest-ordering
插件
pytest-ordering
插件允许通过装饰器@pytest.mark.run
指定测试的执行顺序。- 安装:
pip install pytest-ordering
- 使用:
会先执行import pytest @pytest.mark.run(order=2) def test_first(): pass @pytest.mark.run(order=1) def test_second(): pass
test_second
,再执行test_first
。
2.2 使用 pytest
的 -k
参数
-k
参数允许通过表达式选择要运行的测试。- 示例:
pytest -k "test_first or test_second"
2.3 使用 pytest
的 -m
参数
-m
参数允许通过标记(mark)选择要运行的测试。- 示例:
运行标记为import pytest @pytest.mark.slow def test_slow(): pass @pytest.mark.fast def test_fast(): pass
slow
的测试:pytest -m slow
3. 测试类的运行顺序
在测试类中,pytest
会按照以下顺序执行:
-
按测试方法的定义顺序:
- 在同一个测试类中,测试方法会按照定义顺序执行。
- 例如:
会先执行class TestExample: def test_method_a(self): pass def test_method_b(self): pass
test_method_a
,再执行test_method_b
。
-
按测试类的定义顺序:
- 如果有多个测试类,
pytest
会按照类的定义顺序依次执行。
- 如果有多个测试类,
4. 依赖关系与测试顺序
pytest
本身不直接支持测试之间的依赖关系,但可以通过以下方式实现:
4.1 使用 pytest-dependency
插件
pytest-dependency
插件允许定义测试之间的依赖关系。- 安装:
pip install pytest-dependency
- 使用:
如果import pytest @pytest.mark.dependency() def test_first(): pass @pytest.mark.dependency(depends=["test_first"]) def test_second(): pass
test_first
失败,test_second
会被跳过。
4.2 手动控制依赖
- 通过共享状态(如全局变量或 fixture)手动控制测试的执行逻辑。
- 示例:
status = {} def test_first(): status["first"] = True def test_second(): if not status.get("first"): pytest.skip("test_first must pass first")
5. Fixture 的运行顺序
pytest
中的 fixture
是测试的依赖注入机制,它们的运行顺序可以通过 scope
参数控制:
scope
参数:function
:每个测试函数运行一次(默认)。class
:每个测试类运行一次。module
:每个模块运行一次。session
:整个测试会话运行一次。
autouse
参数:- 如果
autouse=True
,fixture
会自动应用于所有测试,无需显式调用。
- 如果
- 依赖关系:
fixture
可以依赖其他fixture
,pytest
会自动解析依赖关系并按正确顺序执行。
6. Hook 函数的运行顺序
pytest
提供了多种 Hook 函数,可以在测试运行的不同阶段执行自定义逻辑。以下是一些常见的 Hook 函数及其运行顺序:
pytest_configure
:在测试开始前运行。pytest_sessionstart
:在测试会话开始时运行。pytest_collection
:在收集测试用例时运行。pytest_runtest_protocol
:在每个测试用例运行前后运行。pytest_sessionfinish
:在测试会话结束时运行。pytest_unconfigure
:在测试结束后运行。
7. 总结
pytest
的默认运行顺序是按文件名和测试函数/方法的定义顺序执行。如果需要自定义顺序,可以使用插件(如 pytest-ordering
或 pytest-dependency
)或通过参数(如 -k
和 -m
)控制。此外,fixture
和 Hook