Pytest断言的具体使用

发布时间:2023年12月26日

Pytest使用的断言是使用python内置的断言assert。Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。即pytest测试结果为False的断言为断言失败即测试用例执行失败,反之为断言成功即测试用例执行成功。

断言使用场景:

  • 为测试结果作断言
  • 为断言不通过的结果添加说明信息
  • 为预期异常作断言
  • 为失败断言作自定义说明信息

assert断言方法

assert关键字后面接表达式,常用的assert断言方法如下:

  • 判断xx为真:assert xx
  • 判断xx不为真:assert not xx
  • 判断b包含a:assert a in b
  • 判断b不包含a:assert a not in b
  • 判断a等于b:assert a == b
  • 判断a不等于b:assert a != b

示例:

1

2

3

4

5

6

7

8

# 为测试结果作断言

??

import pytest

from func import *

??

class TestFunc:

?def test_add_by_class(self):

??assert add(2,3) == 5

1

2

3

4

5

6

7

8

9

10

11

# 为断言不通过的结果添加说明信息

??

def test_login():

??? # 使用python内置的断言

????# "1是不等于2的"是断言失败后,抛出异常输出的自定义提示信息

??? assert 1 == 2, "1是不等于2的"

?????

test_login()

??

# 运行结果:

AssertionError: 1是不等于2

异常断言Excepiton

异常断言即为断言抛出的异常是预期的异常,执行的测试用例是成功的。

使用pytest.raises()作为上下文管理器。当抛出异常时,可获取到对应的异常实例,然后断言它抛出的异常是不是预期的异常。当代码抛出异常时,如果和raises指定的异常类相匹配,则断言不会失败。

官方文档:How to write and report assertions in tests — pytest documentation

?with pytest.raises()执行结束后会生成一个ExceptionInfo的实例对象,该对象包含type , value, traceback属性。

1

2

3

4

# 变量存储该异常的所有信息

with pytest.raises(TypeError) as 变量:

????# 获取变量的所有属性,即type、value、traceback

????print(变量.__dict__)

注意:断言type的时候,异常类型是不需要加引号的。断言value值的时候需转换str类型,value属性可作异常的说明信息。

示例如下:

1

2

3

4

5

6

7

8

9

10

import pytest

??

def test_zero_division_long():

????with pytest.raises(ZeroDivisionError) as excinfo:

????????1 / 0

??

????# 断言异常类型 type

????assert excinfo.type == ZeroDivisionError

????# 断言异常 value 值

????assert "division by zero" in str(excinfo.value)

with pytest.raise(ZeroDivisionError)用于对于故意测试异常代码的情况(已知异常),断言通过用例执行成功显示passed,不通过会显示failed。

示例如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

# 为预期异常作断言完整示例,执行用例为True

??

# ./func.py

def add(a,b):

????if isinstance(a,int) and isinstance(b,int):

????????return a+b

????else:

????????raise TypeError('数据类型错误')

??

# ./test_case/test_func.py

import pytest

from func import *

??

class TestFunc:

??

?# 正常测试用例

?def test_add_by_class(self):

????assert add(2,3) == 5

??

?# 异常测试用例,期望结果为抛出TypeError异常

?def test_add_by_func_aaa(self,*args, **kwargs):

????with pytest.raises(TypeError) as E:

????????add('3',4)

????print(E.type)

????print(E.value)

????print(E.traceback)?

??

# ./run_test.py

import pytest

??

if __name__ == '__main__':

?pytest.main(['-v'])

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

# 木有抛出预期异常的示例,执行用例为False

??

# ./func.py

def add(a,b):

?# 指定异常,从此处直接抛出异常

????raise NameError("名称错误")

????if isinstance(a,int) and isinstance(b,int):

????????return a+b

????else:

????????raise TypeError('数据类型错误')

??

# ./test_case/test_func.py

import pytest

from func import *

??

class TestFunc:

????# 异常测试用例,期望结果为爆出TypeError异常

????def test_add_by_func_aaa(self,*args, **kwargs):

????????with pytest.raises(TypeError):

????????????add('3',4)

???

# ./run_test.py

import pytest

??

if __name__ == '__main__':

?pytest.main(['-v'])

可将match关键字参数传递给上下文管理器pytest.raises(),来测试正则表达式与异常的信息表达形式是否匹配。match方法相当于re.search功能。

注意:这种方法只能断言value,不能断言type。

示例如下:

1

2

3

4

5

6

7

8

9

10

import pytest

??

def test_zero_division_long():

????with pytest.raises(ZeroDivisionError, match=".*zero.*") as excinfo:

????????1 / 0

??

# match方法相当于re.search功能,即match="zero"也是允许的

def test_zero_division_long():

????with pytest.raises(ZeroDivisionError, match="zero") as excinfo:

????????1 / 0

pytest. raised()函数还有另一种形式,在这里传递一个函数,该函数将使用给定的*args和**kwargs执行,并断言引发了给定的异常。在没有异常或错误异常的情况下,报告器将为您提供有用的输出。

1

pytest.raises(ExpectedException, func, *args, **kwargs)

断言某个测试用例中可能出现多个不同的预期异常的解决办法:

在with pytest.raises()中传入异常类型的参数,从传入一个异常类型,改变为传入一个异常类型组成的元组。同样只是传入一个参数。

示例如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

# ./func.py

def add(a,b):

????raise NameError('名字错了')

????if isinstance(a,int) and isinstance(b,int):

????????return a+b

????else:

????????raise TypeError('数据类型错误')

??

# ./test_case/test_func.py

import pytest

from func import *

??

class TestFunc:

????# 异常测试用例,期望结果为爆出TypeError异常

????def test_add_by_func_aaa(self,*args, **kwargs):

????# 将预期中多个错误信息组成一个元组

????????with pytest.raises((TypeError,NameError),match=r'.*错.*$') as E:

????????????add('3',4)

??

??

# ./run_test.py

import pytest

??

if __name__ == '__main__':

?pytest.main(['-v'])

检查断言装饰器

检查异常装饰器@pytest.mark.xfail():用于对于检查未修复的错误,即可能发生的异常。断言通过用例执行成功会显示xfailed,不通过显示failed。

作用:检查是否有异常,不确定是否有异常。

示例如下:

1

2

3

4

5

# 单个异常时断言装饰器使用

??

@pytest.mark.xfail(raises=ZeroDivisionError)

def test_f():

????1 / 0

1

2

3

4

# 多个异常时断言装饰器使用

@pytest.mark.xfail(raises=(TypeError, NameError))

def test_add_by_func_aaa2():

????add("3", 4)

?现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:485187702【暗号:csdn11】

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走!?希望能帮助到你!【100%无套路免费领取】

文章来源:https://blog.csdn.net/weixin_57794111/article/details/135221331
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。