Pytest进阶之运行顺序

pytest 是 Python 中一个功能强大且灵活的测试框架,它允许开发者编写简洁、可读性高的测试代码。在运行测试时,pytest 遵循一定的顺序规则来执行测试函数、测试类和测试模块。以下是 pytest 运行顺序的详细解析:


1. 默认运行顺序

pytest 默认按照以下顺序执行测试:

  1. 按文件名的字母顺序
    • pytest 会按照测试文件的文件名(ASCII 顺序)依次加载和执行。
    • 例如:test_a.py 会先于 test_b.py 执行。
  2. 按测试函数/方法的定义顺序
    • 在同一个文件中,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 会按照以下顺序执行:

  1. 按测试方法的定义顺序

    • 在同一个测试类中,测试方法会按照定义顺序执行。
    • 例如:
      class TestExample:
          def test_method_a(self):
              pass
      
          def test_method_b(self):
              pass
      
      会先执行 test_method_a,再执行 test_method_b
  2. 按测试类的定义顺序

    • 如果有多个测试类,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 参数控制:

  1. scope 参数
    • function:每个测试函数运行一次(默认)。
    • class:每个测试类运行一次。
    • module:每个模块运行一次。
    • session:整个测试会话运行一次。
  2. autouse 参数
    • 如果 autouse=Truefixture 会自动应用于所有测试,无需显式调用。
  3. 依赖关系
    • fixture 可以依赖其他 fixturepytest 会自动解析依赖关系并按正确顺序执行。

6. Hook 函数的运行顺序

pytest 提供了多种 Hook 函数,可以在测试运行的不同阶段执行自定义逻辑。以下是一些常见的 Hook 函数及其运行顺序:

  1. pytest_configure:在测试开始前运行。
  2. pytest_sessionstart:在测试会话开始时运行。
  3. pytest_collection:在收集测试用例时运行。
  4. pytest_runtest_protocol:在每个测试用例运行前后运行。
  5. pytest_sessionfinish:在测试会话结束时运行。
  6. pytest_unconfigure:在测试结束后运行。

7. 总结

pytest 的默认运行顺序是按文件名和测试函数/方法的定义顺序执行。如果需要自定义顺序,可以使用插件(如 pytest-orderingpytest-dependency)或通过参数(如 -k-m)控制。此外,fixture 和 Hook

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fro.Heart

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值