51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 2407|回复: 1
打印 上一主题 下一主题

[转贴] Pytest中如何解决测试用例的依赖执行问题

[复制链接]
  • TA的每日心情
    无聊
    4 天前
  • 签到天数: 1050 天

    连续签到: 1 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2020-10-19 10:41:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    需求场景:如果A用例执行失败, 那么B用例直接跳过不执行
      遇到问题:如果pytest默认先执行B用例,再执行A用例, 那么在使用pytest-dependency插件后, B用例永远都不会被执行
      解决思路: 用pytest-ordering插件来强制指定用例执行顺序; 用pytest-dependency插件设置用例依赖关系
      一. 安装pytest插件
    1. # 改变测试用例的执行顺序

    2.   pip install pytest-ordering

    3.   # 管理测试用例的依赖关系

    4.   pip install pytest-dependency
    复制代码
     二. pytest-ordering插件的使用
      2.1 代码示例:

    1.  # test_1.py文件

    2.   import pytest

    3.   class Test1():

    4.     

    5.       @pytest.mark.run(order=5)

    6.       def test_1(self): pass

    7.       @pytest.mark.run(order=0)

    8.       def test_2(self): pass

    9.       @pytest.mark.run(order=1)

    10.       def test_3(self): pass

    11.       @pytest.mark.run(order=-1)

    12.       def test_4(self): pass

    13.       @pytest.mark.run(order=-5)

    14.       def test_5(self): pass

    15.       def test_6(self): pass

    16.   if __name__ == '__main__':

    17.       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)               

    1.  collected 6 items

    2.   test_1.py::Test1::test_2 PASSED

    3.   test_1.py::Test1::test_3 PASSED

    4.   test_1.py::Test1::test_1 PASSED

    5.   test_1.py::Test1::test_6 PASSED

    6.   test_1.py::Test1::test_5 PASSED

    7.   test_1.py::Test1::test_4 PASSED

    8.   ============================== 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 代码示例:

    1.  # test_21

    2.   import pytest

    3.   class Test1():

    4.       @pytest.mark.dependency(name="a")

    5.       def test_1(self):

    6.           assert True

    7.       @pytest.mark.dependency(depends=['a'])   # 明确指出test_2用例依赖于test_1用例

    8.       def test_2(self):

    9.           assert True

    10.   if __name__ == '__main__':

    11.       pytest.main(["-v", "-s", "test_21.py"])
    复制代码
    3.1.2 执行结果:
    1. test_1.py::Test1::test_1 PASSED

    2.   test_1.py::Test1::test_2 PASSED

    3.   ============================== 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 代码示例

    1.  import pytest

    2.   class Test1():

    3.       @pytest.mark.dependency(depends=['b'])

    4.       def test_1(self):

    5.           assert True

    6.       @pytest.mark.dependency(name="b")

    7.       def test_2(self):

    8.           assert True

    9.   if __name__ == '__main__':

    10.       pytest.main(["-v", "-s", "test_1.py"])
    复制代码
     3.2.2 执行结果:
    1. test_1.py::Test1::test_1 SKIPPED

    2.   test_1.py::Test1::test_2 PASSED

    3.   ======================== 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 改进代码:

    1. import pytest

    2.   class Test1():

    3.       @pytest.mark.dependency(depends=['b'])

    4.       def test_1(self):

    5.           assert True

    6.       @pytest.mark.run(order=0)

    7.       @pytest.mark.dependency(name="b")

    8.       def test_2(self):

    9.           assert True

    10.   if __name__ == '__main__':

    11.       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 代码示例:

    1. # test_31.py文件

    2.   import pytest

    3.   @pytest.mark.run(order=-5)

    4.   @pytest.mark.dependency(depends=["test_32.py::test_32"], scope='session')

    5.   def test_31():

    6.       assert True

    7.   # test_32.py文件

    8.   import pytest

    9.   @pytest.mark.run(order=-10)

    10.   @pytest.mark.dependency()

    11.   def test_32():

    12.       assert True

    13.   # run.py文件

    14.   import pytest

    15.   pytest.main(["-v", "-s", "."])
    复制代码
     3.3.2 执行结果:
    1. test_32.py::test_32 PASSED

    2.   test_31.py::test_31 PASSED

    3.   ============================== 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"


    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏1
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-25 04:05 , Processed in 0.065228 second(s), 22 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表