一、对异常类型进行断言
对捕获的异常进行断言主要用于在比如异常测试时,当我们给定了特殊的数据时,程序如果产生了我们期望的异常那么对测试而言是正确的,此时就可以通过对捕获的异常类型进行断言,当然对捕获的异常类型进行断言完全可以使用python语言中的try…except 结构进行判断,比如对一个除法函数,当我们给定除数为0时,那么程序报除数为0的异常是正确的,如下为使用python语法中的try…except结构实现的测试代码
def div(a,b):
return a/b
def test_demo():
try:
c=div(10,0)
except Exception as e:
assert isinstance(e,ZeroDivisionError)
执行结果如下,即此用例通过。
$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\redrose2100-book\ebooks\Pytest企业级应用实战\src
collected 1 item
test_demo.py . [100%]
========================================================================== 1 passed in 0.07s ===========================================================================
通过上面的测试代码也看得出,通过try…except结构对异常类型进行断言显得优点繁琐,pytest提供了一种更加便捷的方式,使用with pytest.raise(异常类型)的格式,如下代码
import pytest
def div(a,b):
return a/b
def test_demo():
with pytest.raises(ZeroDivisionError):
c=div(10,0)
执行结果如下,可以看得出,此时用例通过,即此时异常类型确实与期望的一致。
$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\redrose2100-book\ebooks\Pytest企业级应用实战\src
collected 1 item
test_demo.py . [100%]
========================================================================== 1 passed in 2.11s ===========================================================================
二、对捕获的异常信息进行断言
对捕获的异常信息进行断言,同样可以使用Python语言中的try…except结构,如下代码
def div(a,b):
return a/b
def test_demo():
try:
c=div(10,0)
except Exception as e:
assert "division by zero" in str(e)
执行结果如下,可以看得出,此时捕获的异常的信息与期望是一致的。
$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\redrose2100-book\ebooks\Pytest企业级应用实战\src
collected 1 item
test_demo.py . [100%]
========================================================================== 1 passed in 2.03s ===========================================================================
虽然上面的代码可以对异常的信息进行断言,但是明显显得过于繁琐,在pytest框架中,同样也提供了一种比较方便的方式用于对捕获到的异常信息进行断言,如下代码,通过使用with pytest.raise(异常类型) as e,此时异常的信息均在对象e的value属性中,如下代码即断言期望的异常信息在e.value中
import pytest
def div(a,b):
return a/b
def test_demo():
with pytest.raises(ZeroDivisionError) as e:
c=div(10,0)
assert "division by zero" in str(e.value)
执行结果如下,即此时异常信息中包含division by zero字符串。
pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\redrose2100-book\ebooks\Pytest企业级应用实战\src
collected 1 item
test_demo.py . [100%]
========================================================================== 1 passed in 2.02s ===========================================================================
三、同时对捕获的异常类型和异常信息进行断言
这里同样还是不厌其烦首先使用python的语法中的try…except结构对捕获到的异常类型和异常信息进行断言,不小小看了这些基本的或者看上去不怎么高明的手段,其实很多时候在工作中,当我们并未掌握一个框架或者工具提供的巧妙的方法,并不是说我们不能工作了,而完全可以采用我们所掌握的手段的达到同样的目的。如下代码,这里采用了两次断言,分别对异常类型和异常信息进行了断言。
def div(a,b):
return a/b
def test_demo():
try:
c=div(10,0)
except Exception as e:
assert isinstance(e, ZeroDivisionError)
assert "division by zero" in str(e)
执行结果如下,可以看出此时是完全可以对异常类型和异常信息进行断言的。
$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\redrose2100-book\ebooks\Pytest企业级应用实战\src
collected 1 item
test_demo.py . [100%]
========================================================================== 1 passed in 2.10s ===========================================================================
这里同样pytest也提供了一种更加简洁方便的方法,如下代码,通过指定异常类型以及通过正则表达式来匹配异常信息的方式同时对异常类型和异常信息进行断言
import pytest
def div(a,b):
return a/b
def test_demo():
with pytest.raises(ZeroDivisionError,match=r"division\s*by\s*zero"):
c=div(10,0)
执行结果如下,即用例通过,即捕获的异常类型时ZeroDivisionError,而且异常信息也能匹配到正则表达式"division\sby\szero",这样就显得整洁多了。而且用起来也非常的方便。
$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\redrose2100-book\ebooks\Pytest企业级应用实战\src
collected 1 item
test_demo.py . [100%]
========================================================================== 1 passed in 2.00s ===========================================================================
四、对一个函数可能产生的异常进行断言
通过pytest.raise还可以对一个函数可能产生的异常进行断言,在如下格式的调用中,会执行func函数,并将args和**kwargs传入func函数,然后判断此时func中报出的异常是否与第一个参数异常一致。
pytest.raises(ExpectedException, func, args, **kwargs)
如下代码展示了两个用例分别去调用除法计算函数div,均断言会产生除数为零的异常。
import pytest
def div(a,b):
return a/b
def test_demo01():
pytest.raises(ZeroDivisionError,div,10,0)
def test_demo02():
pytest.raises(ZeroDivisionError,div,10,5)
执行结果如下,显然test_demo02中不会产生除数为零的异常,因此此用例会失败。
pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\redrose2100-book\ebooks\Pytest企业级应用实战\src
collected 2 items
test_demo.py .F [100%]
=============================================================================== FAILURES ===============================================================================
_____________________________________________________________________________ test_demo02 ______________________________________________________________________________
def test_demo02():
> pytest.raises(ZeroDivisionError,div,10,5)
E Failed: DID NOT RAISE <class 'ZeroDivisionError'>
test_demo.py:10: Failed
======================================================================= short test summary info ========================================================================
FAILED test_demo.py::test_demo02 - Failed: DID NOT RAISE <class 'ZeroDivisionError'>
===================================================================== 1 failed, 1 passed in 2.14s ======================================================================