-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Integrate pytest-subtests #13738
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
nicoddemus
wants to merge
10
commits into
pytest-dev:main
Choose a base branch
from
nicoddemus:integrate-pytest-subtests
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,631
−14
Open
Integrate pytest-subtests #13738
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
2172c09
Add pytest-subtests files changes
nicoddemus f2f066d
subtests: remove direct pytest import
nicoddemus 2f5cf34
Force using xdist plugin and fix linting
nicoddemus 159217d
Replace attr by dataclass
nicoddemus 016c7c3
Add docs
nicoddemus 7b09c6c
Cleanup internal hacks
nicoddemus cf908c1
Code review
nicoddemus 66313f2
Code review
nicoddemus a63b021
Docs
nicoddemus ee3d5db
Make top-level tests fail when there are failing subtests
nicoddemus File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
**Support for subtests** has been added. | ||
|
||
:ref:`subtests <subtests>` are an alternative to parametrization, useful in situations where the parametrization values are not all known at collection time. | ||
|
||
**Example** | ||
|
||
.. code-block:: python | ||
|
||
def contains_docstring(p: Path) -> bool: | ||
"""Return True if the given Python file contains a top-level docstring.""" | ||
... | ||
|
||
|
||
def test_py_files_contain_docstring(subtests: pytest.Subtests) -> None: | ||
for path in Path.cwd().glob("*.py"): | ||
with subtests.test(path=str(path)): | ||
assert contains_docstring(path) | ||
|
||
|
||
Each assert failure or error is caught by the context manager and reported individually, giving a clear picture of all files that are missing a docstring. | ||
|
||
In addition, :meth:`unittest.TestCase.subTest` is now also supported. | ||
|
||
.. note:: | ||
|
||
This feature is experimental and will likely evolve in future releases. By that we mean that we might change how subtests are reported on failure, but the functionality and how to use it are stable. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ Core pytest functionality | |
fixtures | ||
mark | ||
parametrize | ||
subtests | ||
tmp_path | ||
monkeypatch | ||
doctest | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,95 @@ | ||||||
.. _subtests: | ||||||
|
||||||
How to use subtests | ||||||
=================== | ||||||
|
||||||
.. versionadded:: 9.0 | ||||||
|
||||||
.. note:: | ||||||
|
||||||
This feature is experimental. Its behavior, particularly how failures are reported, may evolve in future releases. However, the core functionality and usage are considered stable. | ||||||
|
||||||
pytest allows for grouping assertions within a normal test, known as *subtests*. | ||||||
|
||||||
Subtests are an alternative to parametrization, particularly useful when the exact parametrization values are not known at collection time. | ||||||
|
||||||
|
||||||
.. code-block:: python | ||||||
|
||||||
# content of test_subtest.py | ||||||
|
||||||
|
||||||
def test(subtests): | ||||||
for i in range(5): | ||||||
with subtests.test(msg="custom message", i=i): | ||||||
assert i % 2 == 0 | ||||||
|
||||||
Each assertion failure or error is caught by the context manager and reported individually: | ||||||
nicoddemus marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
.. code-block:: pytest | ||||||
|
||||||
$ pytest -q test_subtest.py | ||||||
|
||||||
|
||||||
In the output above: | ||||||
|
||||||
* Each subtest is reported with the ``,`` character. | ||||||
* Subtests are reported first and the "top-level" test is reported at the end on its own. | ||||||
* Subtest failures are reported as ``SUBFAIL``. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
Note that it is possible to use ``subtests`` multiple times in the same test, or even mix and match with normal assertions | ||||||
outside the ``subtests.test`` block: | ||||||
|
||||||
.. code-block:: python | ||||||
|
||||||
def test(subtests): | ||||||
for i in range(5): | ||||||
with subtests.test("stage 1", i=i): | ||||||
assert i % 2 == 0 | ||||||
|
||||||
assert func() == 10 | ||||||
|
||||||
for i in range(10, 20): | ||||||
with subtests.test("stage 2", i=i): | ||||||
assert i % 2 == 0 | ||||||
|
||||||
.. note:: | ||||||
|
||||||
See :ref:`parametrize` for an alternative to subtests. | ||||||
|
||||||
|
||||||
Typing | ||||||
------ | ||||||
|
||||||
:class:`pytest.Subtests` is exported so it can be used in type annotations: | ||||||
|
||||||
.. code-block:: python | ||||||
|
||||||
def test(subtests: pytest.Subtests) -> None: ... | ||||||
|
||||||
.. _parametrize_vs_subtests: | ||||||
|
||||||
Parametrization vs Subtests | ||||||
--------------------------- | ||||||
|
||||||
While :ref:`traditional pytest parametrization <parametrize>` and ``subtests`` are similar, they have important differences and use cases. | ||||||
|
||||||
nicoddemus marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
Parametrization | ||||||
~~~~~~~~~~~~~~~ | ||||||
|
||||||
* Happens at collection time. | ||||||
* Generates individual tests. | ||||||
* Parametrized tests can be referenced from the command line. | ||||||
* Plays well with plugins that handle test execution, such as ``--last-failed``. | ||||||
* Ideal for decision table testing. | ||||||
|
||||||
Subtests | ||||||
~~~~~~~~ | ||||||
|
||||||
* Happen during test execution. | ||||||
* Are not known at collection time. | ||||||
* Can be generated dynamically. | ||||||
* Cannot be referenced individually from the command line. | ||||||
* Plugins that handle test execution cannot target individual subtests. | ||||||
* An assertion failure inside a subtest does not interrupt the test, letting users see all failures in the same report. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,7 @@ | |
"pytest_catchlog", | ||
"pytest_capturelog", | ||
"pytest_faulthandler", | ||
"pytest_subtests", | ||
} | ||
|
||
|
||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps should mention that it integrates/replaces
pytest-subtests
with some differences?