How do I properly assert that an exception gets raised in pytest?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In pytest, the standard way to assert that code raises an exception is pytest.raises. It is simple, but getting the details right matters. Good exception tests should prove both that the right exception type is raised and that the failure happens for the reason you expect.
The Core Pattern: pytest.raises
The basic form is a context manager around the exact line or block that should fail.
This test passes only if divide(10, 0) raises ValueError. If no exception is raised, or if a different exception type appears, the test fails.
That is already better than a try/except block because pytest produces clearer failure output and avoids hand-written assertion plumbing.
Assert on the Message Too
Checking the exception type alone is often not enough. If your function can raise the same exception type for multiple reasons, assert on the message or some other attribute.
The match= argument applies a regular expression to the exception text. That makes the test both readable and precise.
You can also capture the exception object for more detailed checks:
Keep the with Block Small
A subtle best practice is to keep only the failure-triggering code inside the with pytest.raises(...) block.
Bad shape:
If this test passes, you do not know which line actually raised the exception.
Better shape:
Now the intent is explicit and the test is easier to trust.
Testing Custom Exceptions
pytest.raises works the same way for your own exception classes.
The pattern stays the same: specific type first, optional message or attribute checks second.
What Not to Do
Avoid broad exception assertions such as pytest.raises(Exception) unless the code genuinely may raise several unrelated exceptions and that is what you are testing. Broad catches make tests pass when the code fails for the wrong reason.
Also avoid manual try/except patterns like this:
It works, but it is noisier and weaker than the built-in pytest tool.
Common Pitfalls
The most common mistake is putting too much code inside the with pytest.raises(...) block, which makes it unclear what actually failed.
Another mistake is asserting only on the exception type when multiple branches can raise that type for different reasons.
A third pitfall is using a broad base exception, which can hide regressions by accepting the wrong failure mode.
Summary
- Use
pytest.raisesto assert that code raises an exception. - Keep the
withblock focused on the exact line or call that should fail. - Use
match=orexc_infowhen you need to verify the message or attributes. - Prefer specific exception classes over broad ones such as
Exception. - Avoid manual
try/exceptassertion patterns when pytest already provides the right tool.

