如何使用pytest.raises捕获sqlite3.IntegrityError?测试失败排查
问题分析与解决:pytest.raises无法捕获sqlite3.IntegrityError
嘿,我一眼就看出问题出在哪了——你的func函数自己把异常给“吞掉”了,导致pytest.raises根本没机会捕获到它!
问题根源
你在func里写了try-except块,捕获到sqlite3.IntegrityError之后只是打印了错误信息,但没有重新抛出这个异常。这就相当于异常在func内部就被处理完了,不会再向上传递到测试代码里,pytest.raises自然检测不到它的存在,所以才会提示Failed: DID NOT RAISE <class 'sqlite3.IntegrityError'>。
两种修正方案
根据你的业务需求,选下面其中一种方式就行:
方案1:让func重新抛出异常
如果你希望func既要打印错误信息,又要让外部能捕获到这个异常,只需要在except块里加一句raise:
import sqlite3 import pytest def func(cursor): try: cursor.execute("INSERT INTO Test (Name) VALUES ('Entry1')") except sqlite3.IntegrityError as e: print(e) raise # 关键:重新抛出异常,让测试代码能捕获到 def test_func(): connection = sqlite3.connect(":memory:") c = connection.cursor() c.execute( """ CREATE TABLE IF NOT EXISTS Test ( ID INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT UNIQUE NOT NULL) """ ) c.execute("INSERT INTO Test (Name) VALUES ('Entry1')") with pytest.raises(sqlite3.IntegrityError) as e: func(cursor=c) assert str(e.value) == "UNIQUE constraint failed: Test.Name"
方案2:移除func内部的异常捕获
如果func不需要自行处理这个异常,直接删掉try-except块,让异常自然向上传递给测试代码:
import sqlite3 import pytest def func(cursor): # 去掉try-except,让异常直接抛出 cursor.execute("INSERT INTO Test (Name) VALUES ('Entry1')") def test_func(): connection = sqlite3.connect(":memory:") c = connection.cursor() c.execute( """ CREATE TABLE IF NOT EXISTS Test ( ID INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT UNIQUE NOT NULL) """ ) c.execute("INSERT INTO Test (Name) VALUES ('Entry1')") with pytest.raises(sqlite3.IntegrityError) as e: func(cursor=c) assert str(e.value) == "UNIQUE constraint failed: Test.Name"
测试验证
不管选哪种方案,运行测试后pytest.raises都能成功捕获到预期的sqlite3.IntegrityError,测试用例会顺利通过。
内容的提问来源于stack exchange,提问作者Andi
相关产品推荐
相关产品推荐

