Assert Exception and Print Traceback in Pytest

What is the proper way to assert that an exception is raised in pytest and ensure that the traceback is printed?

Here’s an example code:

import pytest

def whatever(): return 9 / 0

def test_whatever(): try: whatever() except ZeroDivisionError as exc: pytest.fail(exc, pytrace=True)

When the exception is raised in the whatever function, I want pytest to print the traceback so I can see where exactly the exception occurred. What is the correct way to ensure that pytest raises the exception properly and shows the full traceback?

The most straightforward and recommended approach is to use pytest.raises. It’s built exactly for this, making your test concise while ensuring pytest automatically captures and prints the full traceback.

import pytest

def whatever():
    return 9 / 0

def test_whatever():
    with pytest.raises(ZeroDivisionError):
        whatever()

Here, pytest.raises not only asserts that the exception occurs but also prints the traceback, saving you from handling it manually. No need to call pytest.fail—pytest takes care of everything for you.

Building on Tim’s approach—if you want to go a step further and capture the exception details for logging or debugging, you can use pytest.raises with excinfo.

import pytest

def whatever():
    return 9 / 0

def test_whatever():
    with pytest.raises(ZeroDivisionError) as excinfo:
        whatever()
    pytest.fail(f"Exception raised: {excinfo.value}", pytrace=True)

This way, you not only assert that an exception occurs with pytest.raises, but also have access to excinfo, which lets you inspect and log the exception details before failing the test.

If you need even more control—say, you want to log the traceback separately while still failing the test—you can manually capture it using Python’s traceback module. This is useful when debugging or integrating with logging systems.

import pytest
import traceback

def whatever():
    return 9 / 0

def test_whatever():
    try:
        whatever()
    except ZeroDivisionError as exc:
        print(traceback.format_exc())  # Prints full traceback
        pytest.fail(f"Exception raised: {exc}", pytrace=True)

Here, traceback.format_exc() prints the traceback exactly as it appears in an unhandled exception, which can be useful for debugging while still failing the test with pytest.fail.