Bird
Raised Fist0
PyTesttesting~20 mins

Testing exception chains in PyTest - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Exception Chain Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of chained exception test with pytest
What is the output of this pytest test when run?
PyTest
import pytest

def func():
    try:
        raise ValueError("Initial error")
    except ValueError as e:
        raise RuntimeError("Chained error") from e

def test_exception_chain():
    with pytest.raises(RuntimeError) as excinfo:
        func()
    assert isinstance(excinfo.value.__cause__, ValueError)
    assert str(excinfo.value) == "Chained error"
ATest fails because excinfo.value.__cause__ is None
BTest fails because str(excinfo.value) is 'Initial error'
CTest passes with no assertion errors
DTest raises an unexpected TypeError during execution
Attempts:
2 left
💡 Hint
Remember that 'raise ... from ...' sets the __cause__ attribute of the exception.
❓ assertion
intermediate
1:30remaining
Correct assertion to verify exception cause in pytest
Which assertion correctly verifies that a caught exception has a cause of type KeyError?
PyTest
import pytest

with pytest.raises(RuntimeError) as excinfo:
    raise RuntimeError("Error") from KeyError("missing key")
Aassert isinstance(excinfo.value.__cause__, KeyError)
Bassert excinfo.value.__cause__ == KeyError
Cassert excinfo.value.__context__ is None
Dassert excinfo.value.__cause__.args == ('Error',)
Attempts:
2 left
💡 Hint
The __cause__ attribute holds the original exception instance, not the class.
🔧 Debug
advanced
2:00remaining
Why does this pytest test fail to detect the cause exception?
Given this test code, why does the assertion fail?
PyTest
import pytest

def func():
    try:
        raise IndexError("Index problem")
    except IndexError:
        raise RuntimeError("Runtime problem")

def test_chain():
    with pytest.raises(RuntimeError) as excinfo:
        func()
    assert excinfo.value.__cause__ is not None
ABecause the RuntimeError was raised without 'from', so __cause__ is None
BBecause the test should check __context__ instead of __cause__
CBecause the original exception was swallowed and replaced, causing a TypeError
DBecause pytest.raises does not capture __cause__ attribute
Attempts:
2 left
💡 Hint
Check how exception chaining works when 'from' is omitted.
🧠 Conceptual
advanced
1:30remaining
Understanding exception chaining attributes
Which statement about Python exception chaining is TRUE?
AUsing 'raise' without 'from' clears both __cause__ and __context__
B__context__ is always None when an exception is raised inside except block
C__cause__ and __context__ always point to the same exception instance
D__cause__ is set when an exception is raised with 'from', otherwise None
Attempts:
2 left
💡 Hint
Think about how explicit and implicit chaining differ.
❓ framework
expert
2:30remaining
Testing nested exception chains with pytest
Consider this nested exception chain. Which pytest assertion correctly verifies the root cause exception type?
PyTest
import pytest

def nested_func():
    try:
        raise KeyError("key missing")
    except KeyError as e:
        raise ValueError("value error") from e

def test_nested_chain():
    with pytest.raises(ValueError) as excinfo:
        nested_func()
    # Which assertion below correctly checks the root cause is KeyError?
Aassert isinstance(excinfo.value.__cause__.__cause__, KeyError)
Bassert isinstance(excinfo.value.__cause__, KeyError)
Cassert excinfo.value.__context__.__cause__ is None
Dassert excinfo.value.__cause__.args[0] == 'value error'
Attempts:
2 left
💡 Hint
Check the chain depth and which exception is caught by pytest.raises.

Practice

(1/5)
1. What is the main purpose of testing exception chains in pytest?
easy
A. To test if exceptions are ignored during execution
B. To check if the test function runs without any exceptions
C. To ensure the program does not raise any exceptions
D. To verify that an exception was raised and linked to its cause

Solution

  1. Step 1: Understand exception chains

    Exception chains link one error to another, showing the root cause of a failure.
  2. Step 2: Purpose of testing chains in pytest

    Testing exception chains ensures both the raised exception and its cause are correct.
  3. Final Answer:

    To verify that an exception was raised and linked to its cause -> Option D
  4. Quick Check:

    Exception chains test = verify raised exception and cause [OK]
Hint: Check both exception and cause to test chains correctly [OK]
Common Mistakes:
  • Ignoring the cause of the exception
  • Only checking if any exception was raised
  • Assuming no exceptions means success
2. Which of the following is the correct syntax to test an exception chain using pytest?
easy
A. with pytest.raises(ValueError) as excinfo: raise TypeError() from ValueError()
B. with pytest.raises(TypeError) as excinfo: raise TypeError() from ValueError()
C. with pytest.raises(TypeError) as excinfo: raise ValueError() from None
D. with pytest.raises(TypeError) as excinfo: raise ValueError() from TypeError()

Solution

  1. Step 1: Understand exception chaining syntax

    Python uses raise NewException() from OriginalException() to chain exceptions.
  2. Step 2: Match pytest.raises with the raised exception

    The pytest.raises() context must match the exception actually raised, here TypeError.
  3. Final Answer:

    with pytest.raises(TypeError) as excinfo: raise TypeError() from ValueError() -> Option B
  4. Quick Check:

    pytest.raises matches raised exception, not cause [OK]
Hint: pytest.raises matches raised exception, not the cause [OK]
Common Mistakes:
  • Matching pytest.raises to the cause exception
  • Swapping raised and cause exceptions
  • Using None as cause incorrectly
3. Given the code below, what will excinfo.value.__cause__ be?
def func():
    try:
        raise ValueError("original error")
    except ValueError as e:
        raise TypeError("new error") from e

def test_func():
    with pytest.raises(TypeError) as excinfo:
        func()
medium
A. None
B. AttributeError
C. ValueError('original error')
D. TypeError('new error')

Solution

  1. Step 1: Analyze exception chaining in func()

    ValueError is raised first, caught, then TypeError is raised from it, linking ValueError as cause.
  2. Step 2: Understand excinfo.value.__cause__

    It holds the original exception that caused the current one, so it will be the ValueError instance.
  3. Final Answer:

    ValueError('original error') -> Option C
  4. Quick Check:

    __cause__ stores original exception in chain [OK]
Hint: __cause__ holds the original exception object [OK]
Common Mistakes:
  • Expecting __cause__ to be None
  • Confusing __cause__ with the raised exception
  • Assuming __cause__ is a string
4. Identify the error in this pytest test for exception chains:
def test_chain():
    with pytest.raises(TypeError) as excinfo:
        raise TypeError("error") from ValueError("cause")
    assert isinstance(excinfo.value.__cause__, TypeError)
medium
A. The assertion checks wrong exception type for __cause__
B. The exception chaining syntax is invalid
C. The raised exception and pytest.raises do not match
D. No error, test is correct

Solution

  1. Step 1: Check raised exception and pytest.raises

    pytest.raises expects TypeError, but TypeError is raised from ValueError, so this is valid.
  2. Step 2: Analyze assertion on __cause__

    __cause__ is the original exception, here ValueError, but assertion checks for TypeError incorrectly.
  3. Final Answer:

    The assertion checks wrong exception type for __cause__ -> Option A
  4. Quick Check:

    __cause__ is original exception, check its correct type [OK]
Hint: Assert __cause__ type matches original exception, not raised one [OK]
Common Mistakes:
  • Confusing raised exception with __cause__
  • Assuming __cause__ is None
  • Ignoring mismatch between pytest.raises and raised exception
5. You want to test a function that raises a RuntimeError caused by a KeyError. Which pytest test code correctly verifies both exceptions?
hard
A. with pytest.raises(RuntimeError) as excinfo: func() assert isinstance(excinfo.value.__cause__, KeyError)
B. with pytest.raises(KeyError) as excinfo: func() assert isinstance(excinfo.value.__cause__, RuntimeError)
C. with pytest.raises(RuntimeError) as excinfo: func() assert excinfo.value.__cause__ is None
D. with pytest.raises(Exception) as excinfo: func() assert isinstance(excinfo.value.__cause__, RuntimeError)

Solution

  1. Step 1: Match pytest.raises to the raised exception

    The function raises RuntimeError, so pytest.raises must expect RuntimeError.
  2. Step 2: Check the cause exception

    The cause is KeyError, so assert __cause__ is instance of KeyError.
  3. Final Answer:

    with pytest.raises(RuntimeError) as excinfo: func() assert isinstance(excinfo.value.__cause__, KeyError) -> Option A
  4. Quick Check:

    pytest.raises matches raised, assert __cause__ matches cause [OK]
Hint: pytest.raises for raised, assert __cause__ for cause exception [OK]
Common Mistakes:
  • Swapping raised and cause exceptions in pytest.raises
  • Asserting __cause__ is None incorrectly
  • Using too broad exception in pytest.raises
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard