Skip to main content

pytest-testpulse

A pytest plugin that reports test results into TestPulse via its JUnit-XML import API, matching each test to an existing case by key.

Install

pip install pytest-testpulse

Usage

Mark a test with the case key it corresponds to in TestPulse:

import pytest

@pytest.mark.testpulse("LOGIN-42", platform="linux", tags=["smoke"])
def test_login_succeeds():
    ...

Run with --junitxml — the plugin reads pytest's own JUnit XML output rather than generating it itself, so this flag is required whenever the marker (or --testpulse-dry-run) is in use:

pytest --junitxml=report.xml

You'll see a PytestWarning: record_property is incompatible with junit_family 'xunit2' on every marked test — this is pytest's own built-in warning about the mechanism the plugin relies on (record_property), and is harmless: the property is still written and read correctly against junit_family's default. Silence it with a filterwarnings entry in your pytest config if it's too noisy for your CI logs.

At the end of the session, the plugin submits report.xml to POST /api/v1/projects/{project}/imports and prints a summary. A suite with no marked tests and no --testpulse-dry-run needs no configuration at all — the plugin does nothing.

Configuration

Each setting resolves in this order: CLI flag › environment variable › pytest.ini/pyproject.toml option — the first one present wins.

Setting CLI flag Env var ini-option
API base URL --testpulse-url TESTPULSE_URL testpulse_url
API token --testpulse-token TESTPULSE_TOKEN testpulse_token
Project key --testpulse-project TESTPULSE_PROJECT testpulse_project
Fail on unmatched --testpulse-fail-on-unmatched / --testpulse-no-fail-on-unmatched TESTPULSE_FAIL_ON_UNMATCHED testpulse_fail_on_unmatched

TESTPULSE_URL/TESTPULSE_TOKEN match the env var names TestPulse's own docs already use for the raw conftest.py snippet, so migrating from that snippet to this plugin doesn't require renaming CI secrets. Put your token in an env var or CI secret — not in a committed ini-option.

testpulse_fail_on_unmatched (env var and ini-option) accepts 1/true/yes (case-insensitive) as true; anything else, including unset, is false. --testpulse-no-fail-on-unmatched overrides an ini-option or env var set to true, for a single local run.

Exit-code behavior

Import response Effect on pytest's exit code
201 — every test matched Untouched; a summary is printed to stderr.
207 — some tests unmatched Untouched by default (a warning is printed, naming the unmatched case keys and --testpulse-fail-on-unmatched as the escalation path). Set --testpulse-fail-on-unmatched to make this a hard failure instead.
Network error, auth failure, non-2xx Always fails the session — this isn't suppressible, since a broken submission is a different problem than an incomplete case-annotation rollout.

Dry run

--testpulse-dry-run previews which annotated case keys would match, via a read-only fetch of the project's cases — it never calls the import endpoint, never creates a run, and never affects the exit code:

pytest --junitxml=report.xml --testpulse-dry-run

Attachments

Call the testpulse_attach fixture from inside a marked test to attach a screenshot to its case — images only (PNG, JPEG, or WebP; TestPulse's import API doesn't accept other file types):

@pytest.mark.testpulse("LOGIN-42")
def test_login_succeeds(testpulse_attach):
    ...
    testpulse_attach("failure.png")

Calling it on a test with no @pytest.mark.testpulse marker, or with a file whose content type isn't one of those three image types, drops the attachment with a warning rather than risking the whole submission — there's no case key to attach it to in the first case, and an unsupported file would otherwise get the entire import rejected in the second. If a marked test's case comes back unmatched in a 207 response, its attachment is named separately in the warning output, distinct from the plain unmatched-case listing.

License

MIT

Metadata

Release files for pytest-testpulse 1.0.1

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-testpulse 1.0.1
File Size Uploaded Provenance
pytest_testpulse-1.0.1.tar.gz 12.5 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pytest-testpulse 1.0.1
File Interpreter ABI Platform
pytest_testpulse-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 20.6 kB

Release files / pytest_testpulse-1.0.1.tar.gz

Download URL pytest_testpulse-1.0.1.tar.gz
Size 12.5 kB
Tags Source
SHA-256 checksum
How to use checksums
60d0f122be2325f968ae3847ae356d3e8a56bb53957a0509d3a1903ab72414c9
BLAKE2b-256 checksum
How to use checksums
45b469ebc2b80ebad45266000dad5f9264416262a3e609e7f4e04b230aba3a4c
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 Sep 2, 2026.

Transparency log

Release files / pytest_testpulse-1.0.1-py3-none-any.whl

Download URL pytest_testpulse-1.0.1-py3-none-any.whl
Size 8.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c3470d6f0898d38116775beb17d9cfccac6c5213b614cf17092e9172e155343f
BLAKE2b-256 checksum
How to use checksums
a1ac38469e2e682c0d19ce12eb12b41f9036f3e0eb5a272b922132cd2c12eed7
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 Sep 2, 2026.

Transparency log

Security for pytest-testpulse 1.0.1

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pytest_testpulse-1.0.1.tar.gz

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 Sep 2, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files Full provenance

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