前言
在断言一些代码块或者函数时会引发意料之中的异常或者其他失败的异常导致程序无法运行时,使用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 - 测试通过示例代码如下:
import pytest
def test_01(): with pytest.raises(TypeError) as e: raise TypeError print("2+2=4")
if __name__ == '__main__': pytest.main(["test_a.py", "-s"])
----------执行结果如下:============================= test session starts =============================collecting ... collected 1 item
test_a.py::test_01 PASSED [100%]2+2=4
============================== 1 passed in 0.02s ==============================
复制代码
如下代码中, with语句范围未断言到期望TypeError - 测试失败
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_a.py", "-s"])-----------------运行结果如下:============================= test session starts =============================collecting ... collected 1 item
test_a.py::test_02 FAILED [100%]4-2=2
test_a.py:29 (test_02)def test_02(): with pytest.raises(TypeError) as e:> print("4-2=2")E Failed: DID NOT RAISE <class 'TypeError'>
test_a.py:32: Failed
============================== 1 failed in 0.05s ==============================
复制代码
如果我们不知道预期异常的是什么,我们可以使用 match 和 raise 进行自定义异常,如下:
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_a.py", "-s"])
复制代码
match还可以使用正则表达式进行匹配异常,如下:
with pytest.raises(ValueError, match=r"value not \d+$"): raise ValueError("value not 0")
复制代码
使用 assert 语句进行断言
assert是 Python 中用于检查条件是否满足的关键字。在 pytest 中,assert语句是异常断言的基础。当条件不满足时,assert会引发AssertionError异常,这有助于检测程序中的错误。例如:
def test_something(): assert 2 + 2 == 4, "计算错误"
复制代码
使用 try...except 块捕获异常
除了assert,try...except是另一种处理异常的重要方式。在测试中,try...except可以用来捕获并处理预期的异常。例如:
def test_exception_handling(): try: # 可能引发异常的代码 result = 10 / 0 except ZeroDivisionError: # 异常处理代码 assert True, "除数不能为零"
复制代码
使用 pytest.raises 检查异常
pytest.raises是 pytest 提供的一个工具,用于检查是否引发了预期的异常。它可以方便地验证函数是否抛出了特定类型的异常。例如:
import pytest
def test_exception(): with pytest.raises(ValueError): raise ValueError
复制代码
结合使用异常处理和断言进行测试
在实际的测试中,通常需要结合使用异常处理和断言来确保代码在异常情况下的行为符合预期。以下是一个结合使用try...except和assert的示例:
def divide(x, y): try: result = x / y except ZeroDivisionError: return None return result
def test_divide_by_zero(): assert divide(10, 0) is None, "除数不能为零时应返回None"
复制代码
在这个例子中,test_divide_by_zero测试函数使用assert来验证divide函数在除数为零时是否返回了 None。
总结
pytest 提供了多种方法来处理异常和断言,确保代码的正确性和稳定性。通过结合使用assert语句、try...except块和pytest.raises工具,你可以更有效地测试你的 Python 代码,并且在出现异常时能够进行适当的处理。
评论