Pytest框架 —— Pytest断言

(1)什么是断言

对于测试来讲,不管是功能测试,自动化测试,还是单元测试,一般都会预设一个正确的预期结果,而在测试执行的过程中会得到一个实际的结果。

测试的成功与否就是拿实际的结果与预期的结果进行比较,这个比的过程就是断言(assert)

(2)Pytest断言

  • 与Unittest不同,Pytest使用的是Python自带的assert关键字来进行断言。
  • assert关键字后面可以接一个表达式,只要表达式的最终结果为True,那么断言通过,用例执行则为成功,否则用例执行失败。

(3)Pytest的断言方式及应用场景

1)使用assert语句

Pytest里面的断言实际上就是Python里面的assert断言方法。

比较大小与是否相等:

  • assert a == b:判断a等于b
  • assert a !=b:判断a不等于b

判断包含或不包含:

  • assert a in b:判断b包含a
  • assert a not in b:判断b不包含a

提示:b可以是字符串,可以是列表,元组等都可以。

对类型的判断:

  • assert isinstance(a,int):判断a是否是int类型数据。

判断方法或者函数的返回值是否为真:

  • assert xx:判断xx结果为真。
  • assert not xx:判断xx结果不为真。

例如:

扫描二维码关注公众号,回复: 17622265 查看本文章
 
 
  1. #用于判断素数

  2. def is_prime(n):

  3. if n <= 1:

  4. return False

  5. for i in range(2, n):

  6. if n % i == 0:

  7. return False

  8. return True

  9. # 判断是否为素数

  10. def test_true():

  11. assert is_prime(13)

  12. # 或者不为素数

  13. assert not is_prime(13)

基本上常用的就这么几种。

2)断言预期的异常

将异常信息存储到一个变量中,变量的类型则为异常类,包含异常的typevaluetraceback等信息

 
 
  1. import pytest

  2. def test_exception_value():

  3. with pytest.raises(ZeroDivisionError) as zero:

  4. 1 / 0 # 此处可以是方法,也可以是表达式

  5. # print(zero) <ExceptionInfo ZeroDivisionError('division by zero') tblen=1>

  6. # print(zero.tb)# <traceback object at 0x0000021B6068BD48>

  7. # print(zero.typename) # 字符串"ZeroDivisionError"

  8. # print(zero.type) # 异常类型<class 'ZeroDivisionError'>

  9. print(zero.traceback)

  10. assert "division by zero" in str(zero.value)

  11. assert zero.type == ZeroDivisionError

  12. assert zero.typename == "ZeroDivisionError"

  13. if __name__ == '__main__':

  14. pytest.main()

注意:在上下文管理器的作用域中,raises代码必须是最后一行,否则其后面的代码将不会执行。

拓展:

如果我们不知道预期异常的是什么,我们可以使用 match 和 raise 进行自定义异常。

pytest.raises()函数传递一个关键字参数match,通过match设置的字符串正则表达式匹配异常信息。

Unittest中的TestCase.assertRaisesRegexp方法类似。

示例:

 
 
  1. import pytest

  2. # myfunc函数会抛出一个异常,

  3. def myfunc():

  4. raise ValueError("Exception 123 raised")

  5. def test_match():

  6. # pytest.raises()函数,

  7. # 可以用元组的形式传递参数,只需要触发其中任意一个即可。

  8. # 通过match可以设置通过正则表达式匹配异常。

  9. with pytest.raises((ValueError, RuntimeError), match=r'.* 123 .*') as ve:

  10. myfunc()

  11. # 说明:myfunc()抛出的异常被match设置的字符串匹配到

  12. # 也就是捕获到了该异常。

  13. # 然后下面是断言,123是否包含在捕获异常的说明中。

  14. assert "123" in str(ve.value)

  15. if __name__ == '__main__':

  16. pytest.main()

(4)优化断言

我们可以在异常的时候,输出一些提示信息,这样报错后,可以方便我们来查看原因。

示例如下:

 
 
  1. import pytest

  2. def func():

  3. return 100

  4. def test_case_666():

  5. a = func()

  6. assert a % 3 == 0, "判断a是否能被3整除,当前a的值为:%s" %a

  7. if __name__ == '__main__':

  8. pytest.main()

  9. """

  10. 运行结果:

  11. ========没加注释的测试结果==========

  12. Expected :0

  13. Actual :1

  14. <Click to see difference>

  15. def test_case_666():

  16. a = 100

  17. > assert a % 3 == 0

  18. E assert 1 == 0

  19. test_01.py:55: AssertionError

  20. Assertion failed

  21. ========添加注释的测试结果==========

  22. Expected :0

  23. Actual :1

  24. <Click to see difference>

  25. def test_case_666():

  26. a = 100

  27. > assert a % 3 == 0, "判断a是否能被3整除,当前a的值为:%s" %a

  28. E AssertionError: 判断a是否能被3整除,当前a的值为:100

  29. E assert 1 == 0

  30. test_01.py:53: AssertionError

  31. Assertion failed

  32. """

(5)使用标记检查异常

@pytest.mark.xfail(raises=ZeroDivisionError)

示例:

 
 
  1. import pytest

  2. @pytest.mark.xfail(raises=ZeroDivisionError)

  3. def test_exception_value():

  4. 1 / 0

  5. if __name__ == '__main__':

  6. pytest.main()

  7. # 说明代码:

  8. # 预期抛出ZeroDivisionError异常,

  9. # 实际测试用例执行也抛出了ZeroDivisionError异常。

  10. # 测试结果:该用例是xfailed

感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取