Skip to main content

Downloads

Introduction

Pytest plugin to measure fixture and test durations.

In order to get the pure test setup/teardown durations, the plugin subtracts time taken by fixtures whose scope is larger than "function".

In comparison to the built-in pytest "--durations", this plugin shows fixture durations separately from test function durations and supports xdist and time-traveling packages.

Installation

$ pip install pytest-durations

Plugin options

$ pytest --help

pytest-durations:
  --pytest-durations=N  Show N slowest setup/test durations (N=0 to disable
                        plugin). Default 30
  --pytest-durations-min=N
                        Minimal duration in seconds for inclusion in slowest
                        list. Default 0.005
  --pytest-durations-log=FILE
                        Result log filename or dash for terminal output. Default
                        "-"
  --pytest-durations-group-by={legacy,module,class,function}
                        Group test durations by module, class, or function. Use
                        legacy grouping for backward compatibility. Default:
                        "function"
  --pytest-durations-time-format={clock,auto,short}
                        How to format durations in the report. "clock" shows the
                        full datetime-style value, "short" a compact H:MM:SS, and
                        "auto" picks one readable form based on the report
                        magnitude. Default: "clock"
  --pytest-durations-show=SECTIONS
                        Comma-separated list of report sections to show:
                        "fixture", "call", "setup", "teardown". Default: show
                        all sections.
  --pytest-durations-columns=COLUMNS
                        Comma-separated list of stat columns to show: "total",
                        "num", "min", "med", "max". The test/fixture name is
                        always shown second, and the first listed column is used
                        to sort the report. Default: total,num,med,max.
  --pytest-durations-json=FILE
                        Export timing data as JSON to FILE (use "-" for
                        stdout). Written in addition to the terminal report
                        unless --pytest-durations=0.

Note: Please don't confuse these options with the --durations options that come from pytest itself.

Example of report

$ pytest --pytest-durations

...

========================================= fixture duration top ==========================================
total          name                                                     num med            max
0:00:00.031589 tests/test_options.py::fake_pluginmanager                  3 0:00:00.008776 0:00:00.008867
0:00:00.015807 tests/test_xdist.py::fake_session                          2 0:00:00.007904 0:00:00.007904
0:00:00.014311 tests/test_options.py::fake_config                         2 0:00:00.007155 0:00:00.007155
0:00:00.009118 tests/test_plugin.py::test_plugin_with_options::pytester   3 0:00:00.002232 0:00:00.002415
0:00:00.005009 tests/test_options.py::reload_module                       1 0:00:00.005009 0:00:00.005009
0:00:00.096780 grand total                                              164 0:00:00.000016 0:00:00.000073
======================================== test call duration top =========================================
total          name                                                     num med            max
0:00:00.483961 tests/test_plugin.py::test_plugin_xdist_enabled            1 0:00:00.483961 0:00:00.483961
0:00:00.177326 tests/test_plugin.py::test_plugin_with_options             3 0:00:00.057389 0:00:00.109171
0:00:00.067949 tests/test_plugin.py::test_plugin_with_resultlog           1 0:00:00.067949 0:00:00.067949
0:00:00.066597 tests/test_plugin.py::test_plugin_disable                  1 0:00:00.066597 0:00:00.066597
0:00:00.059509 tests/test_plugin.py::test_plugin_xdist_disabled           1 0:00:00.059509 0:00:00.059509
0:00:00.025053 tests/test_ticker.py::test_freezegun_import_none           1 0:00:00.025053 0:00:00.025053
0:00:00.023706 tests/test_ticker.py::test_get_current_ticks_frozen        2 0:00:00.011853 0:00:00.065801
0:00:00.912538 grand total                                               78 0:00:00.000083 0:00:00.000483
======================================== test setup duration top ========================================
total          name                                                     num med            max
0:00:00.019535 tests/test_options.py::test_pytest_addoption               1 0:00:00.019535 0:00:00.019535
0:00:00.016147 tests/test_options.py::test_pytest_configure_disabled      1 0:00:00.016147 0:00:00.016147
0:00:00.015358 tests/test_options.py::test_pytest_configure               1 0:00:00.015358 0:00:00.015358
0:00:00.010575 tests/test_plugin.py::test_plugin_with_options             3 0:00:00.002773 0:00:00.008465
0:00:00.008763 tests/test_xdist.py::test_pytest_sessionfinish_noxdist     1 0:00:00.008763 0:00:00.008763
0:00:00.007749 tests/test_xdist.py::test_pytest_sessionfinish             1 0:00:00.007749 0:00:00.007749
0:00:00.100089 grand total                                               78 0:00:00.000113 0:00:00.000192
====================================== test teardown duration top =======================================
total          name                                                     num med            max
0:00:00.006716 grand total                                               78 0:00:00.000062 0:00:00.000062
$ pytest --pytest-durations-columns=total,num,min,med,p90,p95,p99,max --pytest-durations-time-format=auto

...

============================================= fixture duration top =============================================
total  name                                                        num min    med    p90    p95    p99    max
0.135s tests/test_options.py::fake_pluginmanager                     3 0.031s 0.031s 0.065s 0.069s 0.072s 0.073s
0.058s tests/test_options.py::fake_config                            2 0.027s 0.029s 0.031s 0.031s 0.031s 0.031s
0.041s tests/test_xdist.py::fake_session                             2 0.020s 0.020s 0.021s 0.021s 0.021s 0.021s
0.013s tests/test_plugin.py::sample_testfile                        17 0.000s 0.001s 0.001s 0.001s 0.001s 0.001s
0.013s tests/test_xdist.py::fake_node                                2 0.006s 0.006s 0.007s 0.007s 0.007s 0.007s
0.305s grand total                                                 289 0.000s 0.000s 0.002s 0.007s 0.046s 0.073s

JSON Export Example

{
  "test call": [
    {"name": "tests/test_foo.py::test_bar", "calls": 3, "total": 0.0045, "min": 0.001, "med": 0.0015, "p90": 0.0018, "p95": 0.0019, "p99": 0.002, "max": 0.002}
  ],
  "fixture": [
    {"name": "tests/test_foo.py::my_fixture", "calls": 3, "total": 0.003, "min": 0.0009, "med": 0.001, "p90": 0.0011, "p95": 0.0011, "p99": 0.0011, "max": 0.0011}
  ]
}

Development

The project uses poetry for dependency management, pytest for testing, and pre-commit for coding standard checks.

$ pip install poetry
$ poetry install
$ pre-commit install
$ pytest

Unreleased

Nothing unreleased yet.

Change Log

1.9.0 (Aug 14, 2026)

  • Improved CI/CD: split lint/test jobs, added Poetry caching, wheel smoke-test, and ARCHITECTURE.md (#61).
  • Improved test coverage by adding missing assertions (#56).
  • Added --pytest-durations-json option to export timing data as JSON for CI integration and programmatic consumption (#60).
  • Added p90, p95, p99 percentile columns to duration reports via --pytest-durations-columns (#57).

1.8.0 (Aug 07, 2026)

  • Added a --pytest-durations-columns option to select which stat columns are printed (total, num, min, med, max) and which one sorts the report (#47). The test/fixture name is always shown second. The default matches the existing output, so nothing changes unless the flag is used.
  • Added a --pytest-durations-time-format option with clock, auto, and short presets for formatting durations in the report (#49). The default (clock) keeps the existing output unchanged.
  • Added a --pytest-durations-show option to select which report sections are printed (fixture, call, setup, teardown) (#48). By default all four tables are shown, so existing output is unchanged.

1.7.1 (Aug 06, 2026)

  • Show max duration instead of min in reports (#47) — fixes a regression from v1.3.1 where the last column was accidentally truncated.

1.7.0 (Jul 08, 2026)

  • Up support pytest version to 7.0.0+
  • Upgrade development dependencies
  • Add typos in pre-commits
  • Fix fixture key handling (pytest 10 compatibility)

1.6.3 (Jun 28, 2026) [YANKED]

Note: Yanked due to SemVer mistake.

1.6.2 (Mar 13, 2026)

  • Drop support python3.9 and add support python3.14

1.6.1 (Aug 29, 2025)

  • Introduced a new --pytest-durations-group-by=none option that preserves the full test node ID, including parameters
  • Removed the need for explicit serialization of Category values when sending CategoryMeasurementsT dictionaries

1.6.0 (Aug 27, 2025)

  • Added support for grouping test durations by module, class, or function (#26)
  • Improved column alignment in duration reports, ensuring test names are left-aligned
  • Renamed the avg column to med in reports, as it correctly represents median durations, not average durations (#24)
  • Refactoring
    • Added a Python script (check_versions.py) to automate checking that the package version is synchronized
    • Renamed the pytest-resultlog option to pytest-durations-log for consistency. The pytest-resultlog option will be deprecated in a future release
    • Converted the internal Category class to inherit from StrEnum for improved type safety and better serialization

To revert to the old behavior for test and fixture names in reports, set the --pytest-durations-group-by option to "legacy".

1.5.2 (Apr 29, 2025)

  • Fix a time-machine time.monotonic() unpatching glitch by using time.time() instead (#19)

1.5.1 (Apr 27, 2025)

  • Add Python 3.13 to supported versions
  • Drop Python 3.8 from supported versions, because of poetry and time_machine dependencies
  • Add time_machine package compatibility (#19)
  • Add README commentary on the difference from pytest builtin "--duration" function (#18)
  • Replace separated code style packages with ruff
  • Upgrade poetry and package dependencies versions

1.4.0 (Mar 18, 2025)

  • Add command line option to write the measure report to a file instead of terminal (#16)

1.3.1 (Sep 11, 2024)

  • Upgrade development dependencies

1.3.0 (Sep 11, 2024)

  • Update supported Python versions

1.2.0 (Apr 22, 2022)

  • Use same width for all reports (#6)
  • Improve test coverage (#7)
  • Continuous delivery GitHub workflow

1.1.0 (Mar 7, 2022)

  • Do not interoperate with xdist if it is disabled or absent

1.0.1 (Feb 14, 2022)

  • Grand total row shows real min/max values instead of averages

1.0.0 (Feb 14, 2022)

  • First Release

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytest_durations-1.9.0.tar.gz (18.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytest_durations-1.9.0-py3-none-any.whl (19.4 kB view details)

Uploaded Python 3

File details

Details for the file pytest_durations-1.9.0.tar.gz.

File metadata

  • Download URL: pytest_durations-1.9.0.tar.gz
  • Upload date:
  • Size: 18.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for pytest_durations-1.9.0.tar.gz
Algorithm Hash digest
SHA256 248ac89d9f926fc119508f20ce54c14a0622dbe496d128e18548db948edcdf93
MD5 dba843fdb2370df79ccdfc5da311f2bd
BLAKE2b-256 857ce8c05c44a0322f1580a2fca4de67fa521b6eae02746331fd33bd4f95ed41

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_durations-1.9.0.tar.gz:

Publisher: cicd.yml on blake-r/pytest-durations

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pytest_durations-1.9.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_durations-1.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9ec7c373635abf9747ab84872dd11795e05e7aa0e050e68c01166fc5b9afa0d1
MD5 0469276e4e6ec08ad33897e44026e17c
BLAKE2b-256 74de393d09e6038aaf96a17e14a01aca469e0395367a79b6608734c34be4ffc2

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_durations-1.9.0-py3-none-any.whl:

Publisher: cicd.yml on blake-r/pytest-durations

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.9.0 This release

2 files

1.8.0

2 files

1.7.1

2 files

1.7.0

2 files

1.6.4

2 files

1.6.3

2 files

1.6.2

2 files

1.6.1

2 files

1.6.0

2 files

1.5.2

2 files

1.5.1

2 files

1.5.0

2 files

1.4.0

2 files

1.3.1

2 files

1.3.0

2 files

1.2.0

2 files

1.1.0

2 files

1.0.1

2 files

1.0.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page