pytest--assert断言
前言
在自动化测试中,判断一个测试用例是否执行通过,通常使用assert去判断实际输出结果与预期结果是否一致。与unittest提供自己的断言方法(unittest_断言
)不同,在pytest中直接对python的assert关键字进行重写,能够输出更多的错误信息,来帮助定位出问题的测试用例以及代码行
pytest断言
那么直接写一个简单的断言测试用例,来看下会比平常python断言多输出哪些信息
demo_assert.py:
import pytest class Test_01: def add(self,x,y): c = x+y return c def test_01(self): a =2 b =3 c = self.add(a,b) assert c == 4
if __name__ == '__main__':
pytest.main()
在cmd中执行pytest test_assert.py,输出结果如下:
>这行打印的是python断言信息输出,E这行打印的则是pytest添加的断言信息输出,可以看到pytest直接将c的数值打印出来,很直观的可以看到数值上5不等于4,错误类型为AssertionError
当然如果你觉得输出的断言信息不够通俗易懂。那么pytest也保留了python断言的自定义断言输出,可以转换为通俗易懂的断言信息,或将一些参数信息打印输出。只需要再assert后面添加打印信息,用,进行分隔,代码如下:
import pytest class Test_01: def add(self,x,y): c = x+y return c def test_01(self): a =2 b =3 c = self.add(a,b) assert c == 4 ,f"a的值:{a}+b的值:{b},经过add计算得到{c},其结果不等于4" if __name__ == '__main__': pytest.main()
输出结果如下:
可以看到E多了一行,输出内容为错误类型:自定义断言输出,如:AssertionError: a的值:2+b的值:3,经过add计算得到5,其结果不等于4
可以看到输出的断言信息更加通俗易懂,将相关参数的数值都打印出来,方便后期测试用例的错误定位和维护
常用断言
pytest 里面断言实际上就是 python 里面的 assert 断言方法,常用的有以下几种
- assert xx :判断 xx 为真
- assert not xx :判断 xx 不为真
- assert a in b :判断 b 包含 a
- assert a == b :判断 a 等于 b
- assert a != b :判断 a 不等于 b
异常断言
当你执行一条错误用例时,已经知道它的错误类型时,可以通过pytest.raises(错误类型)作为上下文管理器来判断,如果运行抛出的错误类型与所确认的错误用例,那么这条测试用例就会判断通过,反之报错,打印出错误信息。
上面用例可以看到抛出的错误类型为AssertionError,那么就可以with pytest,raise(AssertionError)来判断
import pytest class Test_01: def add(self,x,y): c = x+y return c def test_01(self): a =2 b =3 with pytest.raises(AssertionError): c = self.add(a,b) assert c == 4 ,f"a的值:{a}+b的值:{b},经过add计算得到{c},其结果不等于4" if __name__ == '__main__': pytest.main()
重新执行,输出结果如下:
可以看到该用例抛出的错误类型确实是AssertionError,所以该用例测试通过
上面的异常断言,可以进行实例化,实例化过后存在三个可以用的方法,分别是.type,.value,.traceback
- type:错误类型
- value:错误的数值
- traceback:错误的测试用例以及代码行数
import pytest class Test_01: def add(self,x,y): c = x+y return c def test_01(self): a =2 b =3 with pytest.raises(AssertionError) as excinfo: c = self.add(a,b) assert c == 4 ,f"a的值:{a}+b的值:{b},经过add计算得到{c},其结果不等于4" print(f'错误的数值:{excinfo.value}') print(f'错误类型:{excinfo.type}') print(f'错误行数:{excinfo.traceback}') if __name__ == '__main__': pytest.main()
执行pytest test_assert.py -s,将其详细信息打印出来,执行结果如下
补充:
1、match参数
pytest.raises可以传入match参数,已测试正则表达式与异常的字符串表示形式是否匹配,这种方法只能断言value,不能断言type
例如,match传入正则表达式 .*其结果*. 如果value中包含这3个字,那么这个用例也可以通过,反之哪怕错误类型对应了,这个用例也会报错
import pytest class Test_01: def add(self,x,y): c = x+y return c def test_01(self): a =2 b =3 with pytest.raises(AssertionError,match='.*其结果*.') as excinfo: c = self.add(a,b) assert c == 4 ,f"a的值:{a}+b的值:{b},经过add计算得到{c},其结果不等于4" print(f'错误的数值:{excinfo.value}') print(f'错误类型:{excinfo.type}') print(f'错误行数:{excinfo.traceback}') if __name__ == '__main__': pytest.main()
当然,如果不使用正则表达式,match直接传入一个值,例如
with pytest.raises(AssertionError,match='其结果') as excinfo:
这样表示value只要包含“其结果”,用例也是可以通过的
2、@pytest.mark.xfail(raises=错误类型)检查断言修饰器
除了pytest.raises外,也提供了@pytest.mark.xfail(raises=错误类型)修饰器来判断预期错误类型与实际错误类型是否一致,代码如下:
import pytest class Test_01: def add(self,x,y): c = x+y return c @pytest.mark.xfail(raises=AssertionError) def test_01(self): a =2 b =3 c = self.add(a,b) assert c == 4 ,f"a的值:{a}+b的值:{b},经过add计算得到{c},其结果不等于4" if __name__ == '__main__': pytest.main()
如果结果一致,那么pytest运行结果会是xfailed的结果,如果不一致,那么结果是直接fail,输出如下: