Bird
Raised Fist0
PyTesttesting~10 mins

Built-in markers (skip, skipif, xfail) in PyTest - Test Execution Trace

Choose your learning style10 modes available
Test Overview

This test demonstrates how pytest built-in markers skip, skipif, and xfail control test execution. It verifies that tests are skipped or expected to fail under certain conditions.

Test Code - pytest
PyTest
import pytest

@pytest.mark.skip(reason="Skipping this test always")
def test_always_skipped():
    assert False  # This should never run

@pytest.mark.skipif(True, reason="Condition is True, so skip")
def test_skipped_if_true():
    assert False  # This should be skipped

@pytest.mark.xfail(reason="Known bug, expected failure")
def test_expected_failure():
    assert 1 == 2  # This test is expected to fail

@pytest.mark.xfail(reason="Known bug, but fixed now", strict=True)
def test_strict_xfail():
    assert 1 == 1  # This test should pass, so strict xfail will fail the test
Execution Trace - 11 Steps
StepActionSystem StateAssertionResult
1pytest starts test runpytest test runner initialized—PASS
2pytest discovers test_always_skipped and applies @pytest.mark.skiptest_always_skipped marked to skip with reason—PASS
3pytest skips test_always_skipped without running ittest_always_skipped skippedtest_always_skipped is skippedPASS
4pytest discovers test_skipped_if_true and applies @pytest.mark.skipif with condition Truetest_skipped_if_true marked to skip if condition is True—PASS
5pytest skips test_skipped_if_true because condition is Truetest_skipped_if_true skippedtest_skipped_if_true is skippedPASS
6pytest discovers test_expected_failure and applies @pytest.mark.xfailtest_expected_failure marked as expected failure—PASS
7pytest runs test_expected_failure which asserts 1 == 2 (fails)test_expected_failure executed and failedtest_expected_failure failure matches xfail expectationPASS
8pytest marks test_expected_failure as xfail (expected failure)test_expected_failure result recorded as xfailtest_expected_failure is reported as expected failurePASS
9pytest discovers test_strict_xfail and applies @pytest.mark.xfail with strict=Truetest_strict_xfail marked as strict xfail—PASS
10pytest runs test_strict_xfail which asserts 1 == 1 (passes)test_strict_xfail executed and passedtest_strict_xfail passed but marked strict xfailFAIL
11pytest reports test_strict_xfail as failure because strict xfail expects failuretest_strict_xfail result recorded as failurestrict xfail test passed unexpectedly, causing failureFAIL
Failure Scenario
Failing Condition: test marked with strict xfail passes unexpectedly
Execution Trace Quiz - 3 Questions
Test your understanding
What happens to a test marked with @pytest.mark.skip?
AThe test is not run and marked as skipped
BThe test runs but is expected to fail
CThe test runs and must pass
DThe test runs and is ignored if it fails
Key Result
Use pytest markers skip, skipif, and xfail to control test execution flow and handle known issues clearly. Strict xfail helps detect when a bug is fixed but the marker was not updated.

Practice

(1/5)
1. What does the @pytest.mark.skip marker do in a test?
easy
A. It retries the test multiple times before failing.
B. It runs the test only if a condition is true.
C. It marks the test as expected to fail but still runs it.
D. It always skips the test, so it does not run.

Solution

  1. Step 1: Understand the purpose of @pytest.mark.skip

    This marker tells pytest to skip the test unconditionally, so the test is not executed at all.
  2. Step 2: Compare with other markers

    skipif skips conditionally, and xfail marks expected failures but runs the test. So only skip always skips.
  3. Final Answer:

    It always skips the test, so it does not run. -> Option D
  4. Quick Check:

    @pytest.mark.skip always skips = D [OK]
Hint: Skip always means test won't run at all [OK]
Common Mistakes:
  • Confusing skip with skipif (conditional skip)
  • Thinking xfail skips the test
  • Assuming skip reruns the test
2. Which of the following is the correct syntax to skip a test only if Python version is less than 3.8?
easy
A. @pytest.mark.skipif(sys.version_info < (3, 8)\ndef test_func(): pass
B. @pytest.mark.skipif(sys.version_info < (3, 8), reason='Python < 3.8')\ndef test_func(): pass
C. @pytest.mark.skipif(sys.version_info < 3.8)\ndef test_func(): pass
D. @pytest.mark.skipif(sys.version_info < '3.8')\ndef test_func(): pass

Solution

  1. Step 1: Check correct version tuple comparison syntax

    Python version info is a tuple like (3, 7, 5). So comparisons must use tuples, e.g., (3, 8).
  2. Step 2: Verify correct use of skipif with reason

    @pytest.mark.skipif(sys.version_info < (3, 8), reason='Python < 3.8')\ndef test_func(): pass uses tuple comparison and includes a reason string, which is best practice for clarity.
  3. Final Answer:

    @pytest.mark.skipif(sys.version_info < (3, 8), reason='Python < 3.8')\ndef test_func(): pass -> Option B
  4. Quick Check:

    Use tuple and reason in skipif = C [OK]
Hint: Use tuple for version and add reason in skipif [OK]
Common Mistakes:
  • Using float instead of tuple for version
  • Omitting reason argument
  • Comparing version to string
3. What will be the test result when running this code?
import pytest

@pytest.mark.xfail
def test_example():
    assert 1 == 2
medium
A. Test is marked as expected failure but does not fail the suite.
B. Test fails and is reported as failed.
C. Test passes because xfail ignores failures.
D. Test is skipped and not run.

Solution

  1. Step 1: Understand @pytest.mark.xfail behavior

    This marker means the test is expected to fail. If it fails, pytest reports it as an expected failure, not a hard failure.
  2. Step 2: Analyze the assertion

    The assertion 1 == 2 is false, so the test fails. Because of xfail, this failure is expected and reported accordingly.
  3. Final Answer:

    Test is marked as expected failure but does not fail the suite. -> Option A
  4. Quick Check:

    xfail means expected failure = A [OK]
Hint: xfail means failure is expected, not a hard fail [OK]
Common Mistakes:
  • Thinking xfail skips the test
  • Assuming test passes despite assertion
  • Confusing xfail with skipif
4. Identify the error in this pytest code snippet:
import pytest

@pytest.mark.skipif(sys.platform == 'win32')
def test_func():
    assert True
medium
A. Missing import of sys module causes NameError.
B. skipif should be skip to always skip the test.
C. The condition syntax is incorrect; should use double equals.
D. The test function must return a value.

Solution

  1. Step 1: Check imports used in condition

    The condition uses sys.platform, but sys is not imported, causing a NameError at runtime.
  2. Step 2: Verify other parts

    The condition syntax is correct with ==, skipif is valid, and test functions do not need to return values.
  3. Final Answer:

    Missing import of sys module causes NameError. -> Option A
  4. Quick Check:

    Missing import sys = A [OK]
Hint: Always import modules used in skipif conditions [OK]
Common Mistakes:
  • Forgetting to import sys
  • Confusing skipif with skip
  • Expecting test functions to return values
5. You want to mark a test that should be skipped on Windows and expected to fail on Python versions below 3.7. Which is the correct way to combine skipif and xfail markers?
hard
A. @pytest.mark.xfail(sys.version_info < (3,7, reason='Expected fail on old Python')\n@pytest.mark.skipif(sys.platform == 'win32', reason='Skip on Windows')\ndef test_func(): pass
B. @pytest.mark.skipif(sys.platform == 'win32' and sys.version_info < (3,7))\ndef test_func(): pass
C. @pytest.mark.skipif(sys.platform == 'win32', reason='Skip on Windows')\n@pytest.mark.xfail(sys.version_info < (3,7), reason='Expected fail on old Python')\ndef test_func(): pass
D. @pytest.mark.skipif(sys.platform == 'win32')\n@pytest.mark.skipif(sys.version_info < (3,7))\ndef test_func(): pass

Solution

  1. Step 1: Understand marker order and logic

    Tests should be skipped on Windows unconditionally, so skipif for Windows must be applied first.
  2. Step 2: Apply xfail conditionally for Python versions below 3.7

    The xfail marker is applied second to mark expected failures on old Python versions.
  3. Step 3: Verify option correctness

    @pytest.mark.skipif(sys.platform == 'win32', reason='Skip on Windows')\n@pytest.mark.xfail(sys.version_info < (3,7), reason='Expected fail on old Python')\ndef test_func(): pass applies skipif first, then xfail, both with reasons. This is the correct and clear approach.
  4. Final Answer:

    Use skipif for Windows, then xfail for Python version condition with reasons. -> Option C
  5. Quick Check:

    Skip first, then xfail with reasons = B [OK]
Hint: Apply skipif first, then xfail with clear reasons [OK]
Common Mistakes:
  • Reversing marker order causing unexpected runs
  • Combining conditions incorrectly in one skipif
  • Omitting reason strings for markers
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