(1)什么是断言
对于测试来讲,不管是功能测试,自动化测试,还是单元测试,一般都会预设一个正确的预期结果,而在测试执行的过程中会得到一个实际的结果。
测试的成功与否就是拿实际的结果与预期的结果进行比较,这个比的过程就是断言(assert)
(2)Pytest断言
- 与Unittest不同,Pytest使用的是Python自带的
assert
关键字来进行断言。 assert
关键字后面可以接一个表达式,只要表达式的最终结果为True,那么断言通过,用例执行则为成功,否则用例执行失败。
(3)Pytest的断言方式及应用场景
1)使用assert语句
Pytest里面的断言实际上就是Python里面的assert
断言方法。
比较大小与是否相等:
assert a == b
:判断a等于bassert a !=b
:判断a不等于b
判断包含或不包含:
assert a in b
:判断b包含aassert a not in b
:判断b不包含a
提示:b可以是字符串,可以是列表,元组等都可以。
对类型的判断:
assert isinstance(a,int)
:判断a是否是int类型数据。
判断方法或者函数的返回值是否为真:
assert xx
:判断xx结果为真。assert not xx
:判断xx结果不为真。
例如:

-
#用于判断素数
-
def is_prime(n):
-
if n <= 1:
-
return False
-
for i in range(2, n):
-
if n % i == 0:
-
return False
-
return True
-
# 判断是否为素数
-
def test_true():
-
assert is_prime(13)
-
# 或者不为素数
-
assert not is_prime(13)
基本上常用的就这么几种。
2)断言预期的异常
将异常信息存储到一个变量中,变量的类型则为异常类,包含异常的type
、value
和traceback
等信息
-
import pytest
-
def test_exception_value():
-
with pytest.raises(ZeroDivisionError) as zero:
-
1 / 0 # 此处可以是方法,也可以是表达式
-
# print(zero) <ExceptionInfo ZeroDivisionError('division by zero') tblen=1>
-
# print(zero.tb)# <traceback object at 0x0000021B6068BD48>
-
# print(zero.typename) # 字符串"ZeroDivisionError"
-
# print(zero.type) # 异常类型<class 'ZeroDivisionError'>
-
print(zero.traceback)
-
assert "division by zero" in str(zero.value)
-
assert zero.type == ZeroDivisionError
-
assert zero.typename == "ZeroDivisionError"
-
if __name__ == '__main__':
-
pytest.main()
注意:在上下文管理器的作用域中,raises代码必须是最后一行,否则其后面的代码将不会执行。
拓展:
如果我们不知道预期异常的是什么,我们可以使用 match 和 raise 进行自定义异常。
给pytest.raises()
函数传递一个关键字参数match
,通过match
设置的字符串正则表达式匹配异常信息。
和Unittest
中的TestCase.assertRaisesRegexp
方法类似。
示例:
-
import pytest
-
# myfunc函数会抛出一个异常,
-
def myfunc():
-
raise ValueError("Exception 123 raised")
-
def test_match():
-
# pytest.raises()函数,
-
# 可以用元组的形式传递参数,只需要触发其中任意一个即可。
-
# 通过match可以设置通过正则表达式匹配异常。
-
with pytest.raises((ValueError, RuntimeError), match=r'.* 123 .*') as ve:
-
myfunc()
-
# 说明:myfunc()抛出的异常被match设置的字符串匹配到
-
# 也就是捕获到了该异常。
-
# 然后下面是断言,123是否包含在捕获异常的说明中。
-
assert "123" in str(ve.value)
-
if __name__ == '__main__':
-
pytest.main()
(4)优化断言
我们可以在异常的时候,输出一些提示信息,这样报错后,可以方便我们来查看原因。
示例如下:
-
import pytest
-
def func():
-
return 100
-
def test_case_666():
-
a = func()
-
assert a % 3 == 0, "判断a是否能被3整除,当前a的值为:%s" %a
-
if __name__ == '__main__':
-
pytest.main()
-
"""
-
运行结果:
-
========没加注释的测试结果==========
-
Expected :0
-
Actual :1
-
<Click to see difference>
-
def test_case_666():
-
a = 100
-
> assert a % 3 == 0
-
E assert 1 == 0
-
test_01.py:55: AssertionError
-
Assertion failed
-
========添加注释的测试结果==========
-
Expected :0
-
Actual :1
-
<Click to see difference>
-
def test_case_666():
-
a = 100
-
> assert a % 3 == 0, "判断a是否能被3整除,当前a的值为:%s" %a
-
E AssertionError: 判断a是否能被3整除,当前a的值为:100
-
E assert 1 == 0
-
test_01.py:53: AssertionError
-
Assertion failed
-
"""
(5)使用标记检查异常
@pytest.mark.xfail(raises=ZeroDivisionError)
示例:
-
import pytest
-
@pytest.mark.xfail(raises=ZeroDivisionError)
-
def test_exception_value():
-
1 / 0
-
if __name__ == '__main__':
-
pytest.main()
-
# 说明代码:
-
# 预期抛出ZeroDivisionError异常,
-
# 实际测试用例执行也抛出了ZeroDivisionError异常。
-
# 测试结果:该用例是xfailed
感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取