Conditional parametrize helps run tests with different inputs only when certain conditions are met. It saves time by skipping unnecessary test cases.
Conditional parametrize in PyTest
Introduction
Syntax
PyTest
import pytest @pytest.mark.parametrize('input,expected', [ (1, 2), pytest.param(3, 4, marks=pytest.mark.skipif(condition, reason='skip reason')) ]) def test_func(input, expected): assert input + 1 == expected
Use pytest.param to add marks like skipif conditionally.
The condition is a Python expression that returns True or False.
Examples
PyTest
import pytest @pytest.mark.parametrize('x,y', [ (1, 2), pytest.param(3, 4, marks=pytest.mark.skipif(True, reason='Always skip')) ]) def test_add(x, y): assert x + 1 == y
PyTest
import sys import pytest @pytest.mark.parametrize('x,y', [ (1, 2), pytest.param(3, 4, marks=pytest.mark.skipif(sys.platform != 'linux', reason='Only run on Linux')) ]) def test_add(x, y): assert x + 1 == y
Sample Program
This test runs two cases. The second case runs only if Python version is 3.8 or higher. Otherwise, it is skipped.
PyTest
import sys import pytest @pytest.mark.parametrize('num,expected', [ (1, 2), pytest.param(3, 4, marks=pytest.mark.skipif(sys.version_info < (3, 8), reason='Requires Python 3.8+')) ]) def test_increment(num, expected): assert num + 1 == expected if __name__ == '__main__': pytest.main(['-v', __file__])
Important Notes
Use pytest.param to add conditions to individual test cases inside parametrize.
Conditions can check environment, Python version, OS, or any runtime info.
Skipping tests helps keep test runs fast and relevant.
Summary
Conditional parametrize lets you run or skip test cases based on conditions.
Use pytest.param with skipif mark inside parametrize.
This helps test only what matters in your current environment.
Practice
1. What is the main purpose of using
pytest.param with skipif inside @pytest.mark.parametrize?easy
Solution
Step 1: Understand
This syntax allows marking individual parameters to be skipped if a condition is true.pytest.paramwithskipifStep 2: Purpose of conditional skipping
This helps run only relevant tests in certain environments, skipping others automatically.Final Answer:
To conditionally skip specific test cases based on environment or conditions -> Option CQuick 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
Solution
Step 1: Identify correct usage of skipif mark
The skipif mark must be used inside pytest.mark.skipif with a reason string.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.Final Answer:
@pytest.mark.parametrize('x', [pytest.param(1, marks=pytest.mark.skipif(sys.version_info < (3,8), reason='Old Python'))]) -> Option AQuick 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
Solution
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.Step 2: Check other parameters
Parameters 2 and 3 have no skip marks, so their tests run and pass the assertion.Final Answer:
Test with num=1 is skipped; tests with num=2 and num=3 run and pass -> Option BQuick 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
Solution
Step 1: Check skipif condition type
The condition is passed as a string, but skipif expects a boolean expression, not a string.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.Final Answer:
The skipif condition is a string instead of a boolean expression -> Option AQuick 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
Solution
Step 1: Use os.getenv to check environment variable
os.getenv('SKIP_SLOW') returns the value of the environment variable as a string.Step 2: Apply skipif mark correctly
Use pytest.mark.skipif with a boolean condition and a reason inside marks parameter of pytest.param.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.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 DQuick 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
10 questions ~5 mineasy hard
