pytest

作者: 小圆圈Belen | 来源:发表于2020-11-02 10:44 被阅读0次

基础

在pytest框架中,有如下约束:
  • 所有的单测文件名都需要满足test_XXX.py格式或XXX_test.py格式。
  • 在单测文件中,测试类以Test开头,并且不能带有 init 方法(注意:定义class时,需要以T开头,不然pytest是不会去运行该class的)
  • 在单测类中,可以包含一个或多个test_开头的函数。
Pytest运行方式

1.测试类主函数模式

if __name__ == "__main__":
       pytest.main("-s  test_login.py")

2.命令行模式

  pytest 文件路径/测试文件名
  例如:pytest ./test_normal_login.py
Pytest Exit Code 含义清单

1.Exit code 0 所有用例执行完毕,全部通过
2.Exit code 1 所有用例执行完毕,存在Failed的测试用例
3.Exit code 2 用户中断了测试的执行
4.Exit code 3 测试执行过程发生了内部错误
5.Exit code 4 pytest 命令行使用错误
6.Exit code 5 未采集到可用测试用例文件

重试运行case

在做接口测试时,有事会遇到503或短时的网络波动,导致case运行失败,而这并非是我们期望的结果,此时可以就可以通过重试运行case的方式来解决。

  • 安装pytest-rerunfailures:
    pip install -U pytest-rerunfailures
  • 运行模式:
pytest test_normal_login.py --reruns NUM --reruns-delay time    #NUM为重试的次数,time为延时多少秒之后重试

Pytest的setup和teardown函数

功能:

(1)setup()主要是进行测试前的初始化工作
(3)teardown()是测试后的清除工作

函数级别setup()/teardown()

不管setup()和teardown()在哪个位置,都会在函数的开始执行setup(),在函数的结束执行teardown()

import pytest
class Test_ABC:
  # 函数级开始
  def setup(self):
      print("------->setup_method")
  # 函数级结束
  def teardown(self):
      print("------->teardown_method")
  def test_a(self):
      print("------->test_a")
      assert 1
  def test_b(self):
      print("------->test_b")
if __name__ == '__main__':
      pytest.main("-s  test_abc.py")
执行结果:
  test_abc.py 
  ------->setup_method # 第一次 setup()
  ------->test_a
  ------->teardown_method # 第一次 teardown()
  ------->setup_method # 第二次 setup()
  ------->test_b
  ------->teardown_method # 第二次 teardown()
类级别setup()/teardown()

运行于测试类的始末,即:在一个测试类只运行一次setup_class和teardown_class,不关心测试类内有多少个测试函数。

import pytest
class Test_ABC:
   # 测试类级开始
   def setup_class(self):
       print("------->setup_class")
   # 测试类级结束
   def teardown_class(self):
       print("------->teardown_class")
   def test_a(self):
       print("------->test_a")
       assert 1
   def test_b(self):
       print("------->test_b")
if __name__ == '__main__':
      pytest.main("-s  test_abc.py")
执行结果:
  test_abc.py 
  ------->setup_class # 第一次 setup_class()
  ------->test_a
  ------->test_b
  ------->teardown_class # 第一次 teardown_class()

忽略某个测试函数

根据特定的条件,不执行标识的测试函数.

 方法:
     skipif(condition, reason=None)
 参数说明:
     condition:跳过的条件,必传参数
     reason:标注原因,必传参数
 使用方法:
     @pytest.mark.skipif(condition, reason="xxx") 

栗子:

import pytest
class Test_ABC:
    def setup_class(self):
        print("------->setup_class")
    def teardown_class(self):
        print("------->teardown_class")
    def test_a(self):
        print("------->test_a")
        assert 1
    @pytest.mark.skipif(condition=2>1,reason = "跳过该函数") # 跳过测试函数test_b
    def test_b(self):
        print("------->test_b")
            assert 0
执行结果:
   test_abc.py 
   ------->setup_class
   ------->test_a #只执行了函数test_a
   .
   ------->teardown_class
       s # 跳过函数```

标记为预期失败函数

标记测试函数为失败函数

 方法:
     xfail(condition=None, reason=None, raises=None, run=True, strict=False)
 常用参数说明:
     condition:预期失败的条件,必传参数
     reason:失败的原因,必传参数
 使用方法:
     @pytest.mark.xfail(condition, reason="xx")

栗子:

import pytest
class Test_ABC:
    def setup_class(self):
        print("------->setup_class")
    def teardown_class(self):
        print("------->teardown_class")
    def test_a(self):
        print("------->test_a")
        assert 1
    @pytest.mark.xfail(2 > 1, reason="标注为预期失败") # 标记为预期失败函数test_b
       def test_b(self):
           print("------->test_b")
          assert 0
   执行结果:
       test_abc.py 
       ------->setup_class
       ------->test_a
       .
       ------->test_b
       ------->teardown_class
       x  # 失败标记

函数数据参数化

方便测试函数对测试属于的获取。

 方法:
     parametrize(argnames, argvalues, indirect=False, ids=None, scope=None)
 常用参数:
     argnames:参数名
     argvalues:参数对应值,类型必须为list
                 当参数为一个时格式:[value]
                 当参数个数大于一个时,格式为:[(param_value1,param_value2.....),(param_value1,param_value2.....)]
 使用方法:
     @pytest.mark.parametrize(argnames,argvalues)
     ️ 参数值为N个,测试方法就会运行N次

单个参数示例:

import pytest
class Test_ABC:
    def setup_class(self):
        print("------->setup_class")
    def teardown_class(self):
        print("------->teardown_class")

@pytest.mark.parametrize("a",[3,6]) # a参数被赋予两个值,函数会运行两遍
def test_a(self,a): # 参数必须和parametrize里面的参数一致
    print("test data:a=%d"%a)
    assert a%3 == 0

    执行结果:
    test_abc.py 
    ------->setup_class
    test data:a=3 # 运行第一次取值a=3
    .
    test data:a=6 # 运行第二次取值a=6
    . 
    ------->teardown_class

多个参数示例:

import pytest
class Test_ABC:
    def setup_class(self):
        print("------->setup_class")
    def teardown_class(self):
        print("------->teardown_class")


@pytest.mark.parametrize("a,b",[(1,2),(0,3)]) # 参数a,b均被赋予两个值,函数会运行两遍
def test_a(self,a,b): # 参数必须和parametrize里面的参数一致
    print("test data:a=%d,b=%d"%(a,b))
    assert a+b == 3
    执行结果:
    test_abc.py 
    ------->setup_class
    test data:a=1,b=2 # 运行第一次取值 a=1,b=2
    .
    test data:a=0,b=3 # 运行第二次取值 a=0,b=3
    .
    ------->teardown_class

函数作为形参类型示例:

import pytest
def return_test_data():
    return [(1,2),(0,3)]
class Test_ABC:
    def setup_class(self):
        print("------->setup_class")
    def teardown_class(self):
            print("------->teardown_class")

@pytest.mark.parametrize("a,b",return_test_data()) # 使用函数返回值的形式传入参数值
def test_a(self,a,b):
    print("test data:a=%d,b=%d"%(a,b))
    assert a+b == 3
    
    执行结果:
    test_abc.py 
    ------->setup_class
    test data:a=1,b=2 # 运行第一次取值 a=1,b=2
    .
    test data:a=0,b=3 # 运行第二次取值 a=0,b=3
    .
        ------->teardown_class

参考文章:https://blog.csdn.net/lovedingd/article/details/98952868

相关文章

网友评论

      本文标题:pytest

      本文链接:https://www.haomeiwen.com/subject/ttxdvktx.html