Sometimes tests fail because of known bugs or unfinished features. @pytest.mark.xfail helps us mark these tests so they don't cause confusion.
@pytest.mark.xfail for expected failures
@pytest.mark.xfail(condition=True, reason="", strict=False) def test_function(): ...
condition is optional and decides when to mark the test as expected to fail.
reason helps explain why the test is expected to fail.
@pytest.mark.xfail def test_example(): assert 1 == 2
@pytest.mark.xfail(reason="Bug #123") def test_bug(): assert 3 > 5
@pytest.mark.xfail(condition=(3 > 5), reason="Condition false") def test_conditional(): assert 1 == 0
The first test is expected to fail because 1 + 1 is not 3.
The second test is also expected to fail and marked strict, so if it passes, pytest will mark it as an error.
The third test is marked strict but passes, so pytest will report an error because it was expected to fail but didn't.
import pytest @pytest.mark.xfail(reason="Known bug: wrong addition") def test_addition(): assert 1 + 1 == 3 @pytest.mark.xfail(strict=True) def test_strict_fail(): assert 2 * 2 == 5 @pytest.mark.xfail(strict=True) def test_strict_pass(): assert 2 + 2 == 4
Use @pytest.mark.xfail to keep track of tests that fail for known reasons without breaking your test suite.
The strict=True option makes pytest report an error if the test unexpectedly passes.
Always add a reason to explain why the test is expected to fail for better clarity.
@pytest.mark.xfail marks tests expected to fail.
It helps manage known bugs or unfinished features.
Use strict=True to catch unexpected passes.
Practice
@pytest.mark.xfail in a test?Solution
Step 1: Understand the purpose of @pytest.mark.xfail
This decorator is used to mark tests that are expected to fail because of known bugs or unfinished features.Step 2: Differentiate from other decorators
Unlike skipping tests, xfail runs the test but expects failure. It does not mark tests to always pass or run multiple times.Final Answer:
To mark tests that are expected to fail due to known issues -> Option AQuick Check:
@pytest.mark.xfail = expected failure [OK]
- Confusing xfail with skip
- Thinking xfail forces test to pass
- Assuming xfail reruns tests
Solution
Step 1: Recall correct decorator usage
The correct decorator is@pytest.mark.xfailwith parentheses for parameters.Step 2: Understand strict parameter
Settingstrict=Truemeans pytest will fail the test if it unexpectedly passes.Final Answer:
@pytest.mark.xfail(strict=True)\ndef test_example(): pass -> Option BQuick Check:
Correct syntax uses @pytest.mark.xfail(strict=True) [OK]
- Using @pytest.xfail instead of @pytest.mark.xfail
- Confusing skip with xfail
- Omitting parentheses for parameters
@pytest.mark.xfail(strict=True)
def test_divide():
assert 1 / 0 == 0What will be the test result when running pytest?
Solution
Step 1: Analyze the test code
The test asserts 1 divided by 0 equals 0, which raises a ZeroDivisionError, causing failure.Step 2: Understand xfail with strict=True
Since failure is expected, the test is marked as xfail and will pass the test suite. strict=True only fails if the test unexpectedly passes.Final Answer:
Test passes because failure is expected -> Option AQuick Check:
xfail with error = pass test [OK]
- Thinking strict=True fails on error
- Confusing xfail with skip
- Expecting test to fail pytest run
@pytest.mark.xfail(strict=True)
def test_sum():
assert sum([1, 2, 3]) == 5When you run pytest, the test fails. What is the most likely reason?
Solution
Step 1: Check the assertion logic
The sum of [1, 2, 3] is 6, but the test asserts it equals 5, so the assertion fails.Step 2: Understand strict=True effect
strict=True causes failure only if the test unexpectedly passes, but here the test fails as expected.Final Answer:
The test failed because the assertion is incorrect -> Option CQuick Check:
Wrong assertion causes failure, not strict=True [OK]
- Assuming strict=True causes failure on test fail
- Thinking test was skipped
- Believing decorator syntax is wrong
Solution
Step 1: Identify requirement for strict checking
You want pytest to fail the test run if the test unexpectedly passes, sostrict=Trueis needed.Step 2: Use xfail with reason for clarity
Marking the test with@pytest.mark.xfail(strict=True, reason='Flaky API')clearly documents the expected failure and enforces strict checking.Final Answer:
@pytest.mark.xfail(strict=True, reason='Flaky API')\ndef test_api():\n assert call_api() == 'OK' -> Option DQuick Check:
xfail with strict=True and reason = best practice [OK]
- Using skip instead of xfail
- Omitting strict=True when needed
- Not providing reason for clarity
Ready to prove it?
Pass the test and this pattern moves unknown
