Pytest的用例执行顺序控制

pytest默认测试用例执行顺序

  • 先按照py文件名进行查找,按照ASCLL码进行排序执行
  • py文件内按照至上而下的顺序执行

控制执行顺序前提:

  • 安装:pip install pytest-ordering

只有一个py文件

  • 默认执行顺序:从上往下依次执行
    class TestUser(object):
    
        def test_user_case1(self):
            print("test_user_case1")
    
        def test_user_case2(self):
            print("test_user_case2")
    
        def test_user_case3(self):
            print("test_user_case3")
    
    class TestOrder(object):
    
        def test_order_case1(self):
            print("test_order_case1")
    
        def test_order_case2(self):
            print("test_order_case2")
    
        def test_order_case3(self):
            print("test_order_case3")

    示例中执行顺序:从上往下,先执行TestUser中的方法在执行TestOrder中的方法

    • 具体顺序为:test_user_case1->test_user_case2->test_user_case3->test_order_case1->test_order_case2->test_order_case3

  • 加入执行用例顺序控制
    • 语法:在需要执行的函数或方法或类的上方加入@pytest.mark.run(order=x),roder表示执行顺序,x表示第几个执行
    • x,可以是正数,也可以是负数,值大的在前面执行
    • x的执行顺序:先执行正数(值大的先执行,例如:1>2),在执行没有添加执行顺序的,然后执行负数(值打的在前面执行,例如:-1>-2),0是最大的数。案例:如果一个py文件只有一个类的情况
      import pytest
      
      class TestUser(object):
      
          @pytest.mark.run(order=-1)
          def test_user_case1(self):
              print("test_user_case1")
      
          @pytest.mark.run(order=1)
          def test_user_case2(self):
              print("test_user_case2")
      
          def test_user_case3(self):
              print("test_user_case3")

      执行顺序为:test_user_case2->test_user_case3->test_user_case1,先执行正数,在执行没有控制的,最后在执行负数

    • 如果当一个py文件由多个类,类中的方法都加了控制执行顺序
      • 如果两个类中的方法都加了执行顺序,并且都执行顺序都为1时,就会交叉执行,先执行第一个类中的,然后再执行第二个类中的,在执行第一个类中没有加执行顺序的,然后再执行第二个类中没有加执行顺序的
      • 如果两个类中的方法都加了执行顺序,并且执行顺序为1,2,3··,例如第一个类中的方法加了执行顺序为1,2,第二个类中的方法也加了执行顺序3,4,这时会先执行第一个类中的1,2,然后再执行第二个类中的3,4,在执行第一个类中方法没有加执行顺序的,最后执行第二个类中方法没有加执行顺序的
        import pytest
        
        class TestUser(object):
        
            def test_user_case1(self):
                print("test_user_case1")
        
            @pytest.mark.run(order=1)
            def test_user_case2(self):
                print("test_user_case2")
        
            @pytest.mark.run(order=2)
            def test_user_case3(self):
                print("test_user_case3")
        
        
        class TestOrder(object):
        
            def test_order_case1(self):
                print("test_order_case1")
        
            @pytest.mark.run(order=1)
            def test_order_case2(self):
                print("test_order_case2")
        
            @pytest.mark.run(order=3)
            def test_order_case3(self):
                print("test_order_case3")

        执行顺序为:test_user_case2->test_order_case2->test_user_case3->test_order_case3->test_user_case1->test_order_case1

  建议:如果是单个py文件的话,在使用pytest-order情况下,order=x的值不要相同

  注意:如果有多个py文件,按照py文件名称的ASCLL码顺序执行,一个py文件中多个类或多个方法时,如果都使用了@pytest.mark.run(order=x),就会按照定义的执行顺序交叉进行执行。

多个py文件,一个py文件多个类和方法

  • 上面已经知道,多个py文件按照ASCLL码顺序执行py文件,py文件中的类或方法按照定义的@pytest.mark.run(order=x)进行执行,这样不符合我们的预期
  • 如果需要符合我们预期的执行顺序有以下两种解决方法:
    1. 每个order=x的值都不要相同,下一个py文件中的类或方法order=x的值必须要大于上一个py文件中类或方法的值
    2. 通过pytest提供的勾子方法pytest_collection_modifyitems对py文件中的类进行控制执行顺序
      • 用例文件:
        class TestUser(object):
        
            def test_user_case1(self):
                print("test_user_case1")
        
            def test_user_case2(self):
                print("test_user_case2")
        
            def test_user_case3(self):
                print("test_user_case3")
        
        class TestStock(object):
        
            def test_stock_case1(self):
                print("test_stock_case1")
        
            def test_stock_case2(self):
                print("test_stock_case2")
        
            def test_stock_case3(self):
                print("test_stock_case3")
      • 在conftest.py文件中创建钩子函数如下:
        def pytest_collection_modifyitems(config, items)
            # 期望用例顺序按照.py文件中类执行
            appoint_classes = {"TestStock": [],"TestUser": []}
         
            for item in items:
                for cls_name in appoint_classes:
                    if item.parent.name == cls_name:
                        appoint_classes[cls_name].append(item)
            items.clear()
            for cases in appoint_classes.values():
                items.extend(cases)

        注:创建了pytest_collection_modifyitems后,就会按照类的执行顺序进行执行,例如上面代码,会先执行TestStock类中的方法,然后执行TestUser类中的方法;注意:如果有多个py文件,多个py文件中的类顺序也是按照上面代码设置的顺序执行

posted @ 2023-04-14 17:14  A熙  阅读(1113)  评论(0)    收藏  举报