在断言一些代码块或者函数时会引发意料之中的异常或者其他失败的异常导致程序无法运行时,使用raises
捕获匹配到的异常可以让代码继续运行
Python的异常处理:try...except...else...finally...
try:
print("正常的操作")
except TypeError:
print("发生TypeError异常,执行这块代码")
raise # 并抛出这个异常
except:
print("发生未知异常,执行这块代码")
else:
print("如果没有异常执行这块代码有异常发生")
finally:
print("退出try时总会执行")
Pytest的异常处理:pytest.raises
pytest.raises
和with
语句一起使用,成功断言到期望异常则测试通过,未断言到期望异常则测试失败
如下代码中, with
语句范围断言到期望异常TypeError
- 测试通过
#!/usr/bin/python3.6
# coding=utf-8
# Author: 文
import pytest
def test_01():
with pytest.raises(TypeError) as e:
raise TypeError
print("1+2=3")
if __name__ == '__main__':
pytest.main(["test_exception.py", "-s"])
执行结果如下:
F:\xxx\python.exe D:/demo/test_exception.py
============================= test session starts =============================
platform win32 -- Python 3.6.5, pytest-6.1.2, py-1.9.0, pluggy-0.13.1
rootdir: D:\demo, configfile: pytest.ini
plugins: allure-pytest-2.8.22, assume-2.3.3, forked-1.3.0, html-3.0.0, metadata-1.11.0, ordering-0.6, repeat-0.9.1, rerunfailures-9.1.1, xdist-2.1.0
collected 1 item
test_exception.py 1+2=3
.
============================== 1 passed in 0.09s ==============================
Process finished with exit code 0
如下代码中, with
语句范围未断言到期望TypeError
- 测试失败
#!/usr/bin/python3.6
# coding=utf-8
# Author: 文
import pytest
def test_02():
with pytest.raises(TypeError) as e:
print("4-2=2")
print("1+2=3")
if __name__ == '__main__':
pytest.main(["test_exception.py", "-s"])
执行结果如下:
F:\xxx\python.exe D:/demo/test_exception.py
============================= test session starts =============================
platform win32 -- Python 3.6.5, pytest-6.1.2, py-1.9.0, pluggy-0.13.1
rootdir: D:\demo, configfile: pytest.ini
plugins: allure-pytest-2.8.22, assume-2.3.3, forked-1.3.0, html-3.0.0, metadata-1.11.0, ordering-0.6, repeat-0.9.1, rerunfailures-9.1.1, xdist-2.1.0
collected 1 item
test_exception.py 4-2=2
F
================================== FAILURES ===================================
___________________________________ test_02 ___________________________________
def test_02():
with pytest.raises(TypeError):
> print("4-2=2")
E Failed: DID NOT RAISE <class 'TypeError'>
test_10_exception.py:9: Failed
=========================== short test summary info ===========================
FAILED test_10_exception.py::test_02 - Failed: DID NOT RAISE <class 'TypeError'>
============================== 1 failed in 0.40s ==============================
Process finished with exit code 0
如果我们不知道预期异常的是什么,我们可以使用match
和raise
进行自定义异常,如下:
#!/usr/bin/python3.6
# coding=utf-8
# Author: 文
import pytest
def exc(x):
if x == 0:
raise ValueError("value not 0 or None")
return 2 / x
def test_raises():
with pytest.raises(ValueError, match="value not 0 or None"):
exc(0)
assert eval("1 + 2") == 3
if __name__ == '__main__':
pytest.main(["test_exception.py", "-s"])
match
还可以使用正则表达式进行匹配异常,如下:
with pytest.raises(ValueError, match=r"value not \d+$"):
raise ValueError("value not 0")
Tips: 使用正则时,等号后面有个 r
注:官方提示, raise 的异常应该是当前代码块最后一行,如果在其后面还有代码,那么将不会被执行