Skip to main content

pytest-smoke

PyPI Supported Python versions test Code style ruff

pytest-smoke is a pytest plugin designed to quickly perform smoke testing on large test suites. It allows you to scale down test execution by limiting the number of tests run from logical groupings (smoke scopes) to a smaller subset defined by N.

Installation

pip install pytest-smoke

Quick Start

For a quick smoke test with all default options, simply run:

pytest --smoke

This will run a small subset of tests from your test suite to quickly check basic functionality.

Usage

This plugin provides the following command options:

$ pytest -h

<snip>

Smoke testing:
  --smoke=[N]           Run only N tests from each smoke scope.
                        N can be a number (e.g. 5) or a percentage (e.g. 10%).
                        If not provided, the default value is 1.
  --smoke-scope=SCOPE   Specify the scope at which the value of N from the above options is applied.
                        The plugin provides the following predefined scopes, as well as custom user-defined scopes via a hook:
                        - function: Applies N to each test function
                        - class: Applies N to each test class
                        - file: Applies N to each test file
                        - directory: Applies N to each directory a test file is stored
                        - all: Applies N to the entire test suite
                        - auto (default): Dynamically determines an ideal scope per parent node (module or class) based on the presence
                        of parametrized tests. Uses function scope if any parameterized tests exist under the parent node. Otherwise,
                        falls back to file scope for test functions or class scope for test methods.
  --smoke-select-mode=MODE
                        Specify the mode for selecting tests from each scope.
                        The plugin provides the following predefined values, as well as custom user-defined values via a hook:
                        - first: The first N tests (default)
                        - last: The last N tests
                        - random: N randomly selected tests

Examples

Given you have the following test code:

import pytest


def test_something1():
    pass
    
@pytest.mark.parametrize("p", range(10))
def test_something2(p):
    pass
    
@pytest.mark.parametrize("p", range(20))
def test_something3(p):
    pass

You can run smoke tests on subsets of different sizes with the --smoke option.
Here are some basic examples:

  • Run only the first test from each test function
$ pytest -v --smoke
======================== test session starts ==========================
<snip>
collected 31 items / 28 deselected / 3 selected

tests/test_something.py::test_something1 PASSED                  [ 33%]
tests/test_something.py::test_something2[0] PASSED               [ 66%]
tests/test_something.py::test_something3[0] PASSED               [100%]

=================== 3 passed, 28 deselected in 0.02s ===================
  • Run up to 3 tests from each test function (N=3)
$ pytest -v --smoke 3
======================== test session starts ==========================
<snip>
collected 31 items / 24 deselected / 7 selected

tests/test_something.py::test_something1 PASSED                  [ 14%]
tests/test_something.py::test_something2[0] PASSED               [ 28%]
tests/test_something.py::test_something2[1] PASSED               [ 42%]
tests/test_something.py::test_something2[2] PASSED               [ 57%]
tests/test_something.py::test_something3[0] PASSED               [ 71%]
tests/test_something.py::test_something3[1] PASSED               [ 85%]
tests/test_something.py::test_something3[2] PASSED               [100%]

=================== 7 passed, 24 deselected in 0.02s ===================
  • Run 20% of tests from each test function (N=20%)
$ pytest -v --smoke 20%
======================== test session starts ==========================
<snip>
collected 31 items / 24 deselected / 7 selected

tests/test_something.py::test_something1 PASSED                  [ 14%]
tests/test_something.py::test_something2[0] PASSED               [ 28%]
tests/test_something.py::test_something2[1] PASSED               [ 42%]
tests/test_something.py::test_something3[0] PASSED               [ 57%]
tests/test_something.py::test_something3[1] PASSED               [ 71%]
tests/test_something.py::test_something3[2] PASSED               [ 85%]
tests/test_something.py::test_something3[3] PASSED               [100%]

=================== 7 passed, 24 deselected in 0.02s ===================

Markers

@pytest.mark.smoke(*, mustpass=False, runif=True)

When the feature is explicitly enabled via the smoke_marked_tests_as_critical INI option, collected tests marked with @pytest.mark.smoke are considered "critical" smoke tests while ones without this marker are considered "regular" smoke tests. Additionally, if the optional mustpass keyword argument is set to True in the marker, the test is considered a "must-pass" critical smoke test.

The plugin will apply the following behavior:

  • All collected critical tests with runif=True are automatically included, in addition to the regular tests selected as part of N (Ones with runif=False will be deselected)
  • Execute critical smoke tests first, before any regular smoke tests
  • If any "must-pass" test fails, all subsequent regular smoke tests will be skipped

Hooks

The plugin provides the following hooks to customize or extend the plugin's capabilities:

pytest_smoke_generate_group_id(item, scope)

This hook allows you to implement your own custom scopes for the --smoke-scope option, or override the logic of the predefined scopes. Items with the same group ID are grouped together and are considered to be in the same scope, at which N is applied.
Any custom values passed to the --smoke-scope option must be handled in this hook.

pytest_smoke_include(item, scope)

Return True for tests that should be included as "additional" tests. These tests will not be counted towards the calculation of N.

pytest_smoke_exclude(item, scope)

Return True for tests that should not be selected. These items will not be included in the total number of tests to which N% is applied. An example use case is to prevent tests that are marked with skip and/or xfail from being selected.
Note that this hook takes precedence over any other options provided by the plugin.

pytest_smoke_sort_by_select_mode(items, scope, select_mode)

This hook allows you to implement your own custom select modes for the --smoke-select-mode option. Return sorted items to implement a test selection logic for the custom select mode. The plugin will pick N tests from each scope group based on the sorted items, meaning that an item appearing earlier in the same scope group has a higher chance of being selected.
Any custom values passed to the --smoke-select-mode option must be handled in this hook.
Note that the hook does not affect the test execution order.

INI Options

You can override the plugin's default values by setting the following options in a configuration file (pytest.ini, pyproject.toml, etc.).

smoke_default_n

The default N value to be applied when not provided to the --smoke option.
Plugin default: 1

smoke_default_scope

The default smoke scope to be applied when not explicitly specified with the --smoke-scope option.
Plugin default: auto

smoke_default_select_mode

The default smoke select mode to be applied when not explicitly specified with the --smoke-select-mode option.
Plugin default: first

smoke_default_xdist_dist_by_scope

When using the pytest-xdist plugin (>=2.3.0) for parallel testing, this option replaces the default scheduler with a custom distribution algorithm that distributes tests based on the smoke scope. When enabled, the custom scheduler will be automatically used when the -n/--numprocesses option is used without a dist option (--dist or -d).
Plugin default: false

smoke_marked_tests_as_critical

Treat tests marked with @pytest.mark.smoke as "critical" smoke tests.
Plugin default: false

Development

This project uses uv for dependency management. Editing dependencies in pyproject.toml requires re-running uv lock and committing the updated uv.lock. CI rejects a stale lock.

uv sync                      # create .venv with all dev dependencies
uv run pre-commit install    # install git hooks (keeps uv.lock in sync)
uv run pytest tests -n auto  # run the test suite
uv run tox                   # run the full test/lint matrix

Metadata

Release files for pytest-smoke 0.11.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pytest-smoke 0.11.0
File Size Uploaded
pytest_smoke-0.11.0.tar.gz 77.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pytest-smoke 0.11.0
File Interpreter ABI Platform
pytest_smoke-0.11.0-py3-none-any.whl Python 3 none any Details

Total release size: 94.2 kB

Release files / pytest_smoke-0.11.0.tar.gz

Download URL pytest_smoke-0.11.0.tar.gz
Size 77.5 kB
Tags Source
SHA-256 checksum
How to use checksums
5db22c43dcb3086594259e7bbb650581f463454bdaba3a3f494bd5bb321c2f40
BLAKE2b-256 checksum
How to use checksums
b8599065279d6724aeb960ca60c5f6c7b1c94afa10aabb4049fb5be828da9cb1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / pytest_smoke-0.11.0-py3-none-any.whl

Download URL pytest_smoke-0.11.0-py3-none-any.whl
Size 16.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b78e3b825844cc95fe971f4aff33b683a04a56ed8330ce9e7e486983c9617982
BLAKE2b-256 checksum
How to use checksums
2f63c86a3101c311c415c3b4bfd94eb965cfc611e1b0f864b0f3043c61d3ee7e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.11.0 This release

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page