0
0
PyTesttesting~15 mins

Testing exception chains in PyTest - Build an Automation Script

Choose your learning style9 modes available
Verify exception chaining in a function
Preconditions (2)
Step 1: Call the function that raises the chained exception
Step 2: Catch the exception using pytest.raises
Step 3: Verify that the exception is of the expected type
Step 4: Verify that the exception's __cause__ attribute is set to the original exception
Step 5: Verify the messages of both exceptions
✅ Expected Result: The test should pass confirming the exception chain is correctly raised and accessible
Automation Requirements - pytest
Assertions Needed:
Assert the raised exception type
Assert the __cause__ attribute is not None
Assert the message of the original exception matches expected text
Assert the message of the raised exception matches expected text
Best Practices:
Use pytest.raises context manager to catch exceptions
Check exception chaining via __cause__ attribute
Use clear and descriptive assertion messages
Keep test code simple and readable
Automated Solution
PyTest
import pytest

class CustomError(Exception):
    pass

def function_that_raises():
    try:
        raise ValueError("Original error message")
    except ValueError as e:
        raise CustomError("Chained error message") from e


def test_exception_chain():
    with pytest.raises(CustomError) as exc_info:
        function_that_raises()
    raised_exc = exc_info.value
    # Assert the raised exception message
    assert str(raised_exc) == "Chained error message", "Raised exception message mismatch"
    # Assert the cause is set
    assert raised_exc.__cause__ is not None, "Exception cause should not be None"
    # Assert the original exception type and message
    assert isinstance(raised_exc.__cause__, ValueError), "Cause exception type mismatch"
    assert str(raised_exc.__cause__) == "Original error message", "Cause exception message mismatch"

This test defines a function function_that_raises which raises a CustomError chained from a ValueError. The test test_exception_chain uses pytest.raises to catch the CustomError. It then asserts the message of the raised exception, checks that the __cause__ attribute is set (meaning the exception was chained), and verifies the type and message of the original exception. This confirms the exception chaining behavior works as expected.

Common Mistakes - 4 Pitfalls
Not using pytest.raises context manager and catching exceptions manually
Checking exception chaining by comparing string messages only
Not verifying the original exception type in the chain
{'mistake': "Raising exceptions without chaining (missing 'from' keyword)", 'why_bad': "Without 'from', the exception chain is lost and __cause__ is None, so tests for chaining will fail.", 'correct_approach': "Use 'raise NewException() from original_exception' to preserve chaining."}
Bonus Challenge

Now add data-driven testing with 3 different original exception messages and verify chaining for each

Show Hint