zoukankan      html  css  js  c++  java
  • Pytest中如何解决测试用例的依赖执行问题

     

    需求场景:  如果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"
  • 相关阅读:
    【Flutter 实战】1.20版本更新及新增组件
    【Flutter 实战】各种各样形状的组件
    【Flutter 实战】全局点击空白处隐藏键盘
    Flutter —布局系统概述
    【Flutter 实战】17篇动画系列文章带你走进自定义动画
    lvs负载简介,原理,常见使用案例及Keepalived高可用
    02 . MongoDB复制集,分片集,备份与恢复
    Go之Casbin简介,安装,模型,存储,函数
    govendor包管理及Go项目热加载
    教你三招快速文件批量重命名方法
  • 原文地址:https://www.cnblogs.com/Frank-guo/p/13873962.html
Copyright © 2011-2022 走看看