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
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytest_testpulse-1.0.1.tar.gz.
File metadata
- Download URL: pytest_testpulse-1.0.1.tar.gz
- Upload date:
- Size: 12.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60d0f122be2325f968ae3847ae356d3e8a56bb53957a0509d3a1903ab72414c9
|
|
| MD5 |
ecd5d617580eb6a2cfbc54b9494e0fa1
|
|
| BLAKE2b-256 |
45b469ebc2b80ebad45266000dad5f9264416262a3e609e7f4e04b230aba3a4c
|
Provenance
The following attestation bundles were made for pytest_testpulse-1.0.1.tar.gz:
Publisher:
release.yml on Barayo/pytest-testpulse
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_testpulse-1.0.1.tar.gz -
Subject digest:
60d0f122be2325f968ae3847ae356d3e8a56bb53957a0509d3a1903ab72414c9 - Sigstore transparency entry: 2684814146
- Sigstore integration time:
-
Permalink:
Barayo/pytest-testpulse@ffee827f8620ab689a21994cb825e5fbce2198a2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Barayo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ffee827f8620ab689a21994cb825e5fbce2198a2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pytest_testpulse-1.0.1-py3-none-any.whl.
File metadata
- Download URL: pytest_testpulse-1.0.1-py3-none-any.whl
- Upload date:
- Size: 8.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c3470d6f0898d38116775beb17d9cfccac6c5213b614cf17092e9172e155343f
|
|
| MD5 |
b828f17b71d89f63c3895c191ea173a9
|
|
| BLAKE2b-256 |
a1ac38469e2e682c0d19ce12eb12b41f9036f3e0eb5a272b922132cd2c12eed7
|
Provenance
The following attestation bundles were made for pytest_testpulse-1.0.1-py3-none-any.whl:
Publisher:
release.yml on Barayo/pytest-testpulse
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_testpulse-1.0.1-py3-none-any.whl -
Subject digest:
c3470d6f0898d38116775beb17d9cfccac6c5213b614cf17092e9172e155343f - Sigstore transparency entry: 2684814196
- Sigstore integration time:
-
Permalink:
Barayo/pytest-testpulse@ffee827f8620ab689a21994cb825e5fbce2198a2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Barayo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ffee827f8620ab689a21994cb825e5fbce2198a2 -
Trigger Event:
push
-
Statement type: