解决@pytest.mark.dependency 执行先后顺序问题

需求场景: 如果A用例执行失败, 那么B用例直接跳过不执行

遇到问题: 如果pytest默认先执行B用例,再执行A用例, 那么在使用pytest-dependency插件后, B用例永远都不会被执行
 
解决思路: 用pytest-ordering插件来强制指定用例执行顺序; 用pytest-dependency插件设置用例依赖关系

一. 安装pytest插件
  # 改变测试用例的执行顺序
  pip install pytest-ordering
  # 管理测试用例的依赖关系
  pip install pytest-dependency

二. pytest-ordering插件的使用
  2.1 代码示例:
  # test_1.py文件

import pytest
  class Test1():
    
      @pytest.mark.run(order=5)
      def test_1(self): pass
      @pytest.mark.run(order=0)
      def test_2(self): pass
      @pytest.mark.run(order=1)
      def test_3(self): pass
      @pytest.mark.run(order=-1)
      def test_4(self): pass
      @pytest.mark.run(order=-5)
      def test_5(self): pass
      def test_6(self): pass
  if __name__ == '__main__':
      pytest.main(["-v", "-s", "test_1.py"])

2.2 执行结果:
  order为非负整数(值越小优先级越高) > 无排序装饰器 > order为负整数(负的值越大优先级越高)
  0(test_2) > 1(test_3) > 5(test_1) > 无(test_6) > -5(test_5) > -1(test_4)

collected 6 items
  test_1.py::Test1::test_2 PASSED
  test_1.py::Test1::test_3 PASSED
  test_1.py::Test1::test_1 PASSED
  test_1.py::Test1::test_6 PASSED
  test_1.py::Test1::test_5 PASSED
  test_1.py::Test1::test_4 PASSED
   ============================== 6 passed in 0.04s ==============================

2.3 分析小结:
  1) 排序装饰器@pytest.mark.run(order=1)既可以装饰函数,也可以装饰类
  2) 用例优先级: order为负整数 < 无排序装饰器 < order为非负整数
  3) order为负整数时,值越小(负的值越大),优先级越高
  4) order为非负整数时,值越小, 优先级越高
  
  三. pytest-dependency插件的使用
  3.1 test_1用例 先执行, test_2用例 后执行
  3.1.1 代码示例:

# test_21
  import pytest
  class Test1():
      @pytest.mark.dependency(name="a")
      def test_1(self):
          assert True
      @pytest.mark.dependency(depends=['a'])   # 明确指出test_2用例依赖于test_1用例
      def test_2(self):
          assert True
  if __name__ == '__main__':
      pytest.main(["-v", "-s", "test_21.py"])
  3.1.2 执行结果:
  test_1.py::Test1::test_1 PASSED
  test_1.py::Test1::test_2 PASSED
  ============================== 2 passed in 0.04s ==============================

3.1.3 分析小结
  1) 如果test_1用例执行失败,则test_2用例会直接跳过执行
  2) 通过name="a"来给test_1用例定义一个别名,方便其他用例来指定依赖
  3.2 test_2用例 先执行, test_1用例 后执行
  3.2.1 代码示例

import pytest
  class Test1():
      @pytest.mark.dependency(depends=['b'])
      def test_1(self):
          assert True
      @pytest.mark.dependency(name="b")
      def test_2(self):
          assert True
  if __name__ == '__main__':
      pytest.main(["-v", "-s", "test_1.py"])
  3.2.2 执行结果:
  test_1.py::Test1::test_1 SKIPPED
  test_1.py::Test1::test_2 PASSED
  ======================== 1 passed, 1 skipped in 0.05s =========================

3.2.3 问题分析:
  1) pytest默认会先执行test_1用例, 然后执行test_2用例
  2) 上述代码的意图是想让test_2用例作为test_1用例的前置用例, 但是在pytest默认情况下,先执行了test_1用例,最后导致test_1用例跳过
  3) 若想解决上述问题,需要使用pytest-ordering来指定用例的执行顺序, 让test_2先执行
  3.2.4 改进代码:

import pytest
  class Test1():
      @pytest.mark.dependency(depends=['b'])
      def test_1(self):
          assert True
      @pytest.mark.run(order=0)
      @pytest.mark.dependency(name="b")
      def test_2(self):
          assert True
  if __name__ == '__main__':
      pytest.main(["-v", "-s", "test_1.py"])

3.4.5 分析小结:
  1) 通过@pytest.mark.run(order=0)装饰器, 让test_2用例优先于test_1用例执行
  2) 通过@pytest.mark.dependency装饰器来定义用例的依赖关系
  3.3 跨模块或文件来指定用例依赖
  3.3.1 代码示例:

# test_31.py文件
  import pytest
  @pytest.mark.run(order=-5)
  @pytest.mark.dependency(depends=["test_32.py::test_32"], scope='session')
  def test_31():
      assert True
  # test_32.py文件
  import pytest
  @pytest.mark.run(order=-10)
  @pytest.mark.dependency()
  def test_32():
      assert True
  # run.py文件
  import pytest
  pytest.main(["-v", "-s", "."])
  3.3.2 执行结果:
  test_32.py::test_32 PASSED
  test_31.py::test_31 PASSED
  ============================== 2 passed in 0.04s ==============================

3.3.3 分析小结:
  1) 被@pytest.mark.run(order=-10)修饰的用例执行优先级高于被@pytest.mark.run(order=-5)修饰的用例
  2) @pytest.mark.dependency装饰器的depends值为一个nodeid列表. e.g:形如test_32.py::test_32就是一个nodeid
  3) 如果需要跨文件来指定依赖用例, 可以设置@pytest.mark.dependency的scope参数为"session"

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值