I am trying to catch a sqlite3.IntegrityError
error with pytest.raises()
. Here's some toy code to illustrate the behavior.
import sqlite3
import pytest
def func(cursor):
try:
cursor.execute("INSERT INTO Test (Name) VALUES ('Entry1')")
except sqlite3.IntegrityError as e:
print(e)
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"
The code of my func
actually throws the anticipated error and prints to stdout, because Entry1
is already in the table and violates the UNIQUE
restriction. However, the test fails. I don't understand why pytest
didn't raise a sqlite3.IntegrityError
. Here's the test's output:
FAILED [100%]UNIQUE constraint failed: Test.Name
err.py:12 (test_func)
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)
E Failed: DID NOT RAISE <class 'sqlite3.IntegrityError'>
err.py:28: Failed
The reason is that you have already defined a try-catch
block inside your function func
, when the sqlite3.IntegrityError
exception occurs, it is handled by the except
inside your function rather than letting it be raised by pytest.raises
. So just remove the try-except from your method and only keep the cursor.execute
statement (or create a new one without it and use it in your test methods) or instead of handling the exception inside your func
's except
block, you can raise
it again.
Simple reproducible example:
def f():
try:
print(1/0)
except ZeroDivisionError as e:
print(e)
def g():
print(1/0)
def a():
with pytest.raises(ZeroDivisionError) as e:
f()
# g()
This will raise the exception inside your f()
and then throw Failed: DID NOT RAISE <class 'ZeroDivisionError'>
. If you call g()
instead, it will execute normally.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.