Bird
Raised Fist0
PyTesttesting~20 mins

Conditional parametrize in PyTest - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Conditional Parametrize Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of conditionally parametrized pytest test
Given the following pytest test code with conditional parametrization, what will be the output when running the test?

import pytest

@pytest.mark.parametrize("input,expected", [
    (1, 2),
    (2, 3),
    pytest.param(3, 4, marks=pytest.mark.skipif(True, reason="skip 3")),
])
def test_increment(input, expected):
    assert input + 1 == expected
PyTest
import pytest

@pytest.mark.parametrize("input,expected", [
    (1, 2),
    (2, 3),
    pytest.param(3, 4, marks=pytest.mark.skipif(True, reason="skip 3")),
])
def test_increment(input, expected):
    assert input + 1 == expected
AAll three tests pass
BTwo tests pass, one test fails
CTwo tests pass, one test is skipped
DAll three tests fail
Attempts:
2 left
💡 Hint
Look at the skipif mark condition and how it affects test execution.
❓ assertion
intermediate
2:00remaining
Assertion outcome with conditional parametrize
Consider this pytest test with conditional parametrization based on a variable:

import pytest

run_extra = False

params = [(1, 2), (2, 3)]
if run_extra:
    params.append((3, 5))

@pytest.mark.parametrize("input,expected", params)
def test_add_one(input, expected):
    assert input + 1 == expected

What will happen when running this test?
PyTest
import pytest

run_extra = False

params = [(1, 2), (2, 3)]
if run_extra:
    params.append((3, 5))

@pytest.mark.parametrize("input,expected", params)
def test_add_one(input, expected):
    assert input + 1 == expected
ATwo tests run and both pass
BThree tests run, one fails
CTwo tests run, one fails
DThree tests run and all pass
Attempts:
2 left
💡 Hint
Check the value of run_extra and how it affects params.
🔧 Debug
advanced
2:00remaining
Identify the error in conditional parametrize usage
What error will this pytest code raise?

import pytest

condition = False

@pytest.mark.parametrize("x", [1, 2] if condition else 3)
def test_example(x):
    assert x > 0
PyTest
import pytest

condition = False

@pytest.mark.parametrize("x", [1, 2] if condition else 3)
def test_example(x):
    assert x > 0
ATypeError: 'int' object is not iterable
BSyntaxError: invalid syntax
CNo error, tests run with x=1 and x=2
DValueError: parametrize values must be a list or tuple
Attempts:
2 left
💡 Hint
Check the else part of the conditional expression.
❓ framework
advanced
2:00remaining
Best way to conditionally parametrize tests in pytest
You want to run a test with extra parameters only if an environment variable TEST_EXTRA is set to 'yes'. Which pytest approach correctly implements this conditional parametrization?

Options:
PyTest
import os
import pytest

extra_params = [(3, 4)] if os.getenv('TEST_EXTRA') == 'yes' else []
params = [(1, 2), (2, 3)] + extra_params

@pytest.mark.parametrize("input,expected", params)
def test_func(input, expected):
    assert input + 1 == expected
AUse pytest hooks to add parameters dynamically at runtime
BUse pytest.mark.skipif inside parametrize for each extra param
CUse pytest parametrize with indirect=True and check env inside test
DUse a conditional list to build params before @pytest.mark.parametrize as shown
Attempts:
2 left
💡 Hint
Think about simple and clear ways to add parameters conditionally.
🧠 Conceptual
expert
2:00remaining
Understanding conditional parametrize impact on test count
If you have this pytest code:

import pytest

@pytest.mark.parametrize("a", [1, 2])
@pytest.mark.parametrize("b", [3, 4] if False else [5])
def test_combined(a, b):
    assert a < 10 and b < 10

How many tests will pytest run?
PyTest
import pytest

@pytest.mark.parametrize("a", [1, 2])
@pytest.mark.parametrize("b", [3, 4] if False else [5])
def test_combined(a, b):
    assert a < 10 and b < 10
A4 tests
B2 tests
C1 test
D3 tests
Attempts:
2 left
💡 Hint
Remember how multiple parametrize decorators combine parameters.

Practice

(1/5)
1. What is the main purpose of using pytest.param with skipif inside @pytest.mark.parametrize?
easy
A. To mark tests as expected failures
B. To run all test cases regardless of conditions
C. To conditionally skip specific test cases based on environment or conditions
D. To parametrize tests without any conditions

Solution

  1. Step 1: Understand pytest.param with skipif

    This syntax allows marking individual parameters to be skipped if a condition is true.
  2. Step 2: Purpose of conditional skipping

    This helps run only relevant tests in certain environments, skipping others automatically.
  3. Final Answer:

    To conditionally skip specific test cases based on environment or conditions -> Option C
  4. Quick Check:

    Conditional skipping = skipif with pytest.param [OK]
Hint: Use pytest.param with skipif to skip tests conditionally [OK]
Common Mistakes:
  • Thinking skipif skips all tests, not just specific params
  • Confusing skipif with xfail
  • Not using pytest.param inside parametrize
2. Which of the following is the correct syntax to skip a parameter when Python version is less than 3.8 using pytest.mark.parametrize?
easy
A. @pytest.mark.parametrize('x', [pytest.param(1, marks=pytest.mark.skipif(sys.version_info < (3,8), reason='Old Python'))])
B. @pytest.mark.parametrize('x', [pytest.param(1, skipif=sys.version_info < (3,8))])
C. @pytest.mark.parametrize('x', [pytest.param(1, marks=skipif(sys.version_info < (3,8)))])
D. @pytest.mark.parametrize('x', [pytest.param(1, marks=pytest.skipif(sys.version_info < (3,8)))])

Solution

  1. Step 1: Identify correct usage of skipif mark

    The skipif mark must be used inside pytest.mark.skipif with a reason string.
  2. Step 2: Check syntax correctness

    @pytest.mark.parametrize('x', [pytest.param(1, marks=pytest.mark.skipif(sys.version_info < (3,8), reason='Old Python'))]) correctly uses pytest.mark.skipif with condition and reason inside marks parameter.
  3. Final Answer:

    @pytest.mark.parametrize('x', [pytest.param(1, marks=pytest.mark.skipif(sys.version_info < (3,8), reason='Old Python'))]) -> Option A
  4. Quick Check:

    Use pytest.mark.skipif with marks and reason [OK]
Hint: Use marks=pytest.mark.skipif(condition, reason='') inside pytest.param [OK]
Common Mistakes:
  • Using skipif without pytest.mark
  • Omitting the reason argument
  • Passing skipif as a direct argument instead of marks
3. Given the code below, what will be the output when running pytest on Python 3.7?
import sys
import pytest

@pytest.mark.parametrize('num', [
    pytest.param(1, marks=pytest.mark.skipif(sys.version_info < (3,8), reason='Skip on old Python')),
    2,
    3
])
def test_numbers(num):
    assert num > 0
medium
A. All three tests run and pass
B. Test with num=1 is skipped; tests with num=2 and num=3 run and pass
C. All tests are skipped
D. Test with num=1 fails due to skipif syntax error

Solution

  1. Step 1: Analyze skipif condition with Python 3.7

    sys.version_info < (3,8) is True for Python 3.7, so param with num=1 is skipped.
  2. Step 2: Check other parameters

    Parameters 2 and 3 have no skip marks, so their tests run and pass the assertion.
  3. Final Answer:

    Test with num=1 is skipped; tests with num=2 and num=3 run and pass -> Option B
  4. Quick Check:

    skipif True skips param; others run [OK]
Hint: Check skipif condition against environment to predict skipped tests [OK]
Common Mistakes:
  • Assuming all tests run regardless of skipif
  • Confusing skipif with xfail
  • Thinking skipif causes syntax error
4. Identify the error in the following code snippet that uses conditional parametrize:
import pytest

@pytest.mark.parametrize('val', [
    pytest.param(10, marks=pytest.mark.skipif('sys.version_info < (3,8)', reason='Old Python')),
    20
])
def test_val(val):
    assert val > 0
medium
A. The skipif condition is a string instead of a boolean expression
B. Missing import of sys module
C. pytest.param cannot be used inside parametrize
D. The reason argument is missing in skipif

Solution

  1. Step 1: Check skipif condition type

    The condition is passed as a string, but skipif expects a boolean expression, not a string.
  2. Step 2: Confirm other parts

    sys module is not imported, but the main error is the string condition. pytest.param usage and reason argument are correct.
  3. Final Answer:

    The skipif condition is a string instead of a boolean expression -> Option A
  4. Quick Check:

    skipif condition must be boolean, not string [OK]
Hint: skipif condition must be a boolean expression, not a string [OK]
Common Mistakes:
  • Passing condition as string instead of boolean
  • Ignoring missing sys import (not main error here)
  • Misusing pytest.param outside parametrize
5. You want to run a test with parameters mode set to 'fast', 'slow', and 'medium'. However, you want to skip the 'slow' mode test only if an environment variable SKIP_SLOW is set to '1'. Which is the correct way to write this conditional parametrize in pytest?
hard
A. import os @pytest.mark.parametrize('mode', [ 'fast', pytest.param('slow', marks=pytest.mark.skipif('os.getenv("SKIP_SLOW") == "1"')), 'medium' ])
B. import os @pytest.mark.parametrize('mode', [ 'fast', pytest.param('slow', skipif=os.getenv('SKIP_SLOW') == '1'), 'medium' ])
C. import os @pytest.mark.parametrize('mode', [ 'fast', pytest.param('slow', marks=pytest.skipif(os.getenv('SKIP_SLOW') == '1')), 'medium' ])
D. import os @pytest.mark.parametrize('mode', [ 'fast', pytest.param('slow', marks=pytest.mark.skipif(os.getenv('SKIP_SLOW') == '1', reason='Skip slow mode')), 'medium' ])

Solution

  1. Step 1: Use os.getenv to check environment variable

    os.getenv('SKIP_SLOW') returns the value of the environment variable as a string.
  2. Step 2: Apply skipif mark correctly

    Use pytest.mark.skipif with a boolean condition and a reason inside marks parameter of pytest.param.
  3. Step 3: Verify syntax correctness

    import os @pytest.mark.parametrize('mode', [ 'fast', pytest.param('slow', marks=pytest.mark.skipif(os.getenv('SKIP_SLOW') == '1', reason='Skip slow mode')), 'medium' ]) correctly uses marks=pytest.mark.skipif(condition, reason='...') and imports os.
  4. Final Answer:

    import os @pytest.mark.parametrize('mode', [ 'fast', pytest.param('slow', marks=pytest.mark.skipif(os.getenv('SKIP_SLOW') == '1', reason='Skip slow mode')), 'medium' ]) -> Option D
  5. Quick Check:

    Use marks=pytest.mark.skipif with env check and reason [OK]
Hint: Use os.getenv and marks=pytest.mark.skipif with reason to skip params [OK]
Common Mistakes:
  • Passing skipif as direct argument instead of marks
  • Using string condition instead of boolean
  • Omitting reason in skipif mark
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