You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
title: Introduction to advanced testing with pytest
6
-
description: This module walks you through advanced features of pytest, a powerful testing tool for Python. You'll find out about parametrize, fixtures, and patching.
7
-
ms.date: 4/12/2024
6
+
description: Introduce pytest parametrization, fixtures, and the built-in monkeypatch fixture for more maintainable Python tests.
description: Use pytest fixtures to create reusable test helpers. Learn how these fixtures can use other fixtures and automatically clean up after they run.
7
-
ms.date: 4/12/2024
6
+
description: Use pytest fixtures for reusable setup and cleanup, control fixture scope, and explore built-in fixtures such as tmp_path and monkeypatch.
description: Check your knowledge about pytest parametrize and fixtures
7
-
ms.date: 4/12/2024
6
+
description: Check your knowledge about pytest parametrization, fixtures, fixture scope, yield-based cleanup, and monkeypatch.
7
+
ms.date: 04/20/2026
8
8
author: alfredodeza
9
9
ms.author: orthomas
10
10
ms.custom:
11
11
- team=nextgen
12
12
- devx-track-python
13
13
ms.topic: unit
14
14
module_assessment: true
15
-
durationInMinutes: 1
15
+
durationInMinutes: 3
16
16
content: |
17
17
quiz:
18
18
questions:
19
-
- content: "What is one useful feature of adding fixtures to the _conftest.py_ file?"
19
+
- content: "What is one useful feature of defining fixtures in a _conftest.py_ file?"
20
20
choices:
21
-
- content: "It allows importing those fixtures in a test suite."
22
-
isCorrect: false
23
-
explanation: "Incorrect. Adding fixtures in a _conftest.py_ file doesn't affect their importing in a suite."
24
-
- content: "It allows sharing the fixtures without importing them in a test suite."
21
+
- content: "Tests in the same directory and its subdirectories can request those fixtures by name without importing them."
25
22
isCorrect: true
26
-
explanation: "Correct. By adding fixtures in a _conftest.py_, they become available to any test in a test suite without importing them."
27
-
- content: "Because it allows fixtures to require pytest fixtures."
23
+
explanation: "Correct. Pytest discovers `conftest.py` files automatically and makes their fixtures available to tests in the same directory and its subdirectories without explicit imports."
24
+
- content: "Fixtures defined in _conftest.py_ run only when the test file imports them."
25
+
isCorrect: false
26
+
explanation: "Incorrect. Fixtures in _conftest.py_ are discovered automatically by pytest and don't need to be imported by tests."
27
+
- content: "Fixtures in _conftest.py_ can only be requested by tests in that exact same file."
28
28
isCorrect: false
29
-
explanation: "Incorrect. Fixtures can always require pytest fixtures regardless of their location."
30
-
- content: "What makes a test a good candidate for `parametrize()`?"
29
+
explanation: "Incorrect. Tests in the same directory and its subdirectories can request fixtures from _conftest.py_."
30
+
- content: "What makes a test a good candidate for `@pytest.mark.parametrize`?"
31
31
choices:
32
-
- content: "When a test needs to loop over inputs for the same assertion."
32
+
- content: "When the same test logic should run for several input values or input/expected-value pairs."
33
33
isCorrect: true
34
-
explanation: "Correct. Parametrize is a great choice to avoid looping, converting input items into individual tests."
35
-
- content: "When a test needs to catch multiple exceptions."
34
+
explanation: "Correct. Parametrization replaces a `for` loop or near-duplicate test functions with one test that pytest collects as a separate test case for each parameter set."
35
+
- content: "When unrelated behaviors need to be checked in one test function."
36
36
isCorrect: false
37
-
explanation: "Incorrect. Multiple exceptions in a test don't make it a good candidate for _parametrize_."
37
+
explanation: "Incorrect. Parametrize is best when each case exercises the same behavior. Unrelated behaviors should usually be separate tests."
38
38
- content: "When a test needs to run in parallel."
39
39
isCorrect: false
40
-
explanation: "Incorrect. There’s no need to use _parametrize_ to run tests in parallel."
41
-
- content: "Why might multiple arguments with _parametrize_ not be a good idea?"
40
+
explanation: "Incorrect. Parallel execution is provided by plugins such as `pytest-xdist`, not by `parametrize`."
41
+
- content: "How do you parametrize a test that needs both an input value and an expected value?"
42
+
choices:
43
+
- content: "Use a comma-separated argument-name string and a list of tuples, such as `@pytest.mark.parametrize(\"test_input, expected_value\", [(\"3+5\", 8), (\"3*4\", 12)])`."
44
+
isCorrect: true
45
+
explanation: "Correct. Each tuple supplies one value for each named test function argument, in order."
46
+
- content: "Use one list for all input values and a separate, unrelated list for all expected values."
47
+
isCorrect: false
48
+
explanation: "Incorrect. Pytest needs each parameter set to keep the input and expected value paired together."
49
+
- content: "Avoid multiple argument names because pytest doesn't support them."
50
+
isCorrect: false
51
+
explanation: "Incorrect. Pytest supports multiple argument names separated by commas in the first argument to `@pytest.mark.parametrize`."
52
+
- content: "What does `scope=\"module\"` do for a pytest fixture?"
53
+
choices:
54
+
- content: "Pytest creates and caches one fixture value for the module, then tears it down during module teardown after pytest finishes the last test in that module."
55
+
isCorrect: true
56
+
explanation: "Correct. Broader fixture scopes reuse the same fixture value for the duration of that scope."
57
+
- content: "Pytest creates a new fixture value before every assertion in the module."
58
+
isCorrect: false
59
+
explanation: "Incorrect. Even the default `function` scope creates one value per test function, not per assertion."
60
+
- content: "Pytest makes the fixture available without a `conftest.py` file."
61
+
isCorrect: false
62
+
explanation: "Incorrect. Scope controls fixture lifecycle, not where pytest discovers the fixture."
63
+
- content: "In a `yield`-based fixture, when does the code after `yield` run?"
42
64
choices:
43
-
- content: "Because pytest doesn't allow it. An exception gets raised instead."
65
+
- content: "During teardown, after the requesting test or fixture scope finishes."
66
+
isCorrect: true
67
+
explanation: "Correct. Code before `yield` performs setup and supplies a value. Code after `yield` runs during fixture teardown."
68
+
- content: "Before pytest passes the fixture value to the test."
44
69
isCorrect: false
45
-
explanation: "Incorrect. Pytest does allow multiple arguments with _parametrize_."
46
-
- content: "Because test functions don't allow multiple arguments."
70
+
explanation: "Incorrect. Code before `yield` runs before the test; code after `yield` runs during teardown."
71
+
- content: "Only when the test fails."
47
72
isCorrect: false
48
-
explanation: "Incorrect. Test functions do allow multiple arguments, including when testing with _parametrize_."
49
-
- content: "Because it can make tests harder to read."
73
+
explanation: "Incorrect. Fixture teardown runs after the fixture's scope finishes, whether the requesting test passes or fails."
74
+
- content: "Why use the `monkeypatch` fixture when replacing a function or environment value in a test?"
75
+
choices:
76
+
- content: "It automatically undoes the change after the requesting test or fixture finishes."
50
77
isCorrect: true
51
-
explanation: "Correct. Using multiple arguments with _parametrize_ can make tests harder to read."
78
+
explanation: "Correct. The `monkeypatch` fixture helps isolate tests by making temporary changes and then restoring the original state."
79
+
- content: "It permanently changes the application code so later tests see the same value."
80
+
isCorrect: false
81
+
explanation: "Incorrect. The `monkeypatch` fixture is designed for temporary changes scoped to a single test."
82
+
- content: "It runs parametrized tests in parallel."
83
+
isCorrect: false
84
+
explanation: "Incorrect. `monkeypatch` changes test state; it doesn't control parallel execution."
description: In this module, we went through two advanced features of pytest. Fixtures and _parametrize_ help you to write better tests and produce better output.
7
-
ms.date: 4/12/2024
6
+
description: Recap how parametrization, fixtures, and the monkeypatch fixture help you write clearer, more maintainable pytest tests.
Beyond the basic tasks of running tests and generating reports, pytest offers many advanced features. These features can improve and simplify your testing and help you to craft more robust tests, expand test coverage, and troubleshoot failures.
1
+
Pytest can do more than discover tests and report assertion results. As a Python test suite grows, repeated test logic and shared setup code make tests harder to read, debug, and extend. In this module, you'll learn three pytest features that help keep Python tests readable and maintainable: parametrization, fixtures, and the built-in `monkeypatch` fixture.
2
2
3
-
In this module, you'll learn about features of the pytest framework that will help you write effective tests that are also simple and readable.
3
+
This module assumes that you can write Python scripts, run commands in a terminal, and run simple pytest tests in a virtual environment with Python 3.10 or later. If you need setup help on Windows, see [Set up your Python development environment on Windows](/windows/dev-environment/python). For virtual environment details, see Python's [`venv` documentation](https://docs.python.org/3/tutorial/venv.html).
4
4
5
-
## What you will learn
5
+
Parametrization with `@pytest.mark.parametrize` runs the same test function with multiple sets of arguments, and pytest collects each generated invocation as its own test item. Fixtures are functions registered with pytest, usually with `@pytest.fixture`, that tests or other fixtures request by name. They can return reusable values and, when needed, run cleanup after the test or fixture scope finishes. The `monkeypatch` fixture temporarily changes attributes, dictionary items, environment variables, `sys.path`, or the current working directory, then automatically undoes those changes after the requesting test or fixture finishes.
6
6
7
-
After completing this module, you'll be able to use _parametrize_ in your tests to reduce code repetition and improve test coverage. You'll also learn about fixtures, which enable sharing common setups and cleanups in tests.
7
+
The examples in this module are unit-style tests, but the same pytest features apply to larger integration or functional test suites. The examples use Python's `assert` statement; pytest provides assertion introspection so failure reports include useful values from the expression.
8
8
9
-
Completing this module helps you to:
9
+
## When to use these features
10
10
11
-
-Increase code coverage by adding input values using parametrize
12
-
-Build common test code with custom _fixtures_ and avoid code repetition
13
-
- Use the _monkey patch_ fixture to safely invoke code by calling mock functions and setting mock values
11
+
-Use **parametrization** when you find yourself looping over inputs in a test or copying near-duplicate test functions for slightly different inputs. Parametrization expands one test definition into many test items, so each input gets its own pass/fail report.
12
+
-Use **fixtures** when several tests need the same setup (such as test data, a temporary file, or a database connection) or need predictable cleanup after they run.
13
+
- Use **`monkeypatch`** when a test needs to isolate code from external state—for example, environment variables, the current working directory, or a function that calls a remote service—without permanently changing that state.
14
14
15
-
## What is the main goal
15
+
You'll start by replacing loops and near-duplicate tests with parametrization. Then you'll use fixtures to share setup and cleanup, review built-in fixtures such as `tmp_path` and `monkeypatch`, and practice refactoring xUnit-style setup and teardown methods into a fixture.
16
16
17
-
You should feel confident in your ability to begin using these advanced features of pytest. These features can help you to write more robust and powerful tests with improved coverage.
17
+
By the end of this module, you'll be ready to apply these pytest features to reduce repetition, expand coverage, and improve failure diagnostics in your Python test suites.
18
+
19
+
For more information, see the pytest documentation for [assertions](https://docs.pytest.org/en/stable/how-to/assert.html), [parametrizing tests](https://docs.pytest.org/en/stable/how-to/parametrize.html), [fixtures](https://docs.pytest.org/en/stable/how-to/fixtures.html), and [monkeypatch](https://docs.pytest.org/en/stable/how-to/monkeypatch.html).
0 commit comments