pytest-devant-cloud
pytest plugin that streams runs, results, and per-test step trees into Devant.net while your suite runs.
Requirements
Python 3.10 or newer, and pytest 7 or newer.
Quick start
Install the plugin:
pip install pytest-devant-cloud
Point it at your project. Copy the token and project id from your Devant CI/CD settings:
export DEVANT_API_URL=https://acme.devant.net
export DEVANT_TOKEN=your-ci-token
export DEVANT_PROJECT_ID=42
Run pytest as you normally would:
pytest
Results show up in Devant while the suite is still running. There is nothing
to add to conftest.py; the plugin registers itself through pytest's
pytest11 entry-point group.
Upgrading from 0.1.x
Every environment variable was renamed, and all config defaults were removed. Upgrade without changing your CI and the plugin disables itself — your suite still passes, so reporting stops without anything failing.
| 0.1.x | 0.4.0+ |
|---|---|
DEVANT_CLOUD_API_URL (or DEVQ_API_URL) |
DEVANT_API_URL — required |
DEVANT_CLOUD_TOKEN (or DEVQ_TOKEN) |
DEVANT_TOKEN — required |
DEVANT_CLOUD_PROJECT_ID (or DEVQ_PROJECT_ID) |
DEVANT_PROJECT_ID — required |
DEVANT_CLOUD_RUN_NAME / DEVANT_CLOUD_RUN_ID |
DEVANT_RUN_NAME / DEVANT_RUN_ID |
0.1.x silently fell back to http://localhost:32124, the token
dev-admin-token, and project 1. A misconfigured CI job therefore either
401'd against a real tenant or filed its results under whatever project
happened to be id 1. There are no fallbacks now.
When configuration is missing or unusable, the plugin writes one JSON line to stderr and does nothing further:
{"level":"error","source":"pytest-devant-cloud","msg":"not configured","missing":["DEVANT_TOKEN"]}
After upgrading, grep your CI logs for "msg":"not configured".
Configuration
Configure with environment variables:
| Variable | Default | Notes |
|---|---|---|
DEVANT_API_URL |
required | Your tenant's URL |
DEVANT_TOKEN |
required | CI token from Settings → CI/CD |
DEVANT_PROJECT_ID |
required | Devant project id |
DEVANT_RUN_NAME |
pytest — <ISO date> |
Display name on the run |
DEVANT_RUN_ID |
(unset) | Attach to an externally-created run instead of creating one |
DEVANT_COVERAGE |
./coverage.xml, then <rootdir>/coverage.xml |
Cobertura report to submit as the run's coverage |
The same settings work as CLI flags, which win over the environment:
pytest \
--devant-api-url=https://acme.devant.net \
--devant-token=$DEVANT_TOKEN \
--devant-project-id=42
Turn the plugin off for a single run without uninstalling it:
pytest -p no:devant_cloud
Binding tests to cases
Each test maps to one case in Devant. The plugin chooses the case in this order:
- The
@pytest.mark.devant("DEF-AB12")marker on the test, if present. - An existing case whose name matches the test.
- A new case, created on the spot, with a key like
DEF-XYZ9.
An auto-created case is tied to the test's name and its place in the suite tree, so renaming or moving the test starts a fresh case. To keep a test's history across renames, copy its key from your Devant dashboard and pin it in source:
@pytest.mark.devant("DEF-XYZ9")
def test_login(): ...
Coverage
Coverage is read from the Cobertura XML pytest-cov writes, so you need
--cov-report=xml — an HTML-only report produces no XML and the upload
silently no-ops:
pytest --cov=myapp --cov-report=xml --cov-report=html
The plugin picks up coverage.xml from the working directory (then rootdir)
by default; point it elsewhere
with --devant-coverage path/to/coverage.xml or DEVANT_COVERAGE. Line and
branch percentages are sent; Cobertura carries no function metric, and
coverage.py's lines are its statements, so those two fields stay null.
A missing or unparseable report is warned-and-skipped, never fatal.
Suites
The plugin turns each test's location into a nested suite tree, built from the directories, module, and class around it. The leaf is the test function plus any parametrize id.
| Test | Suite path | Case name |
|---|---|---|
tests/test_x.py::test_foo |
tests / test_x | test_foo |
tests/api/test_x.py::TestThing::test_y[a-1] |
tests / api / test_x / TestThing | test_y[a-1] |
If you re-parent a suite by hand in the dashboard, the plugin leaves your change alone on later runs.
CI metadata
On GitHub Actions, GitLab CI, CircleCI, Jenkins, and Azure DevOps (or any
runner that sets CI=true), the plugin attaches the commit, branch, and
pull request to each run, so Devant can link a run back to the code that
triggered it.
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_devant_cloud-0.7.0.tar.gz.
File metadata
- Download URL: pytest_devant_cloud-0.7.0.tar.gz
- Upload date:
- Size: 29.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
45da25c4016d2f364f6bb4300f46db5694e14f8277fc4148885013e5635529f2
|
|
| MD5 |
3d7e22ba8f69f91bb1b2a83a8b1effa6
|
|
| BLAKE2b-256 |
0c55534380c72f96026b00b27c76753b57b866a0b36447923280b36b8cc53b0c
|
File details
Details for the file pytest_devant_cloud-0.7.0-py3-none-any.whl.
File metadata
- Download URL: pytest_devant_cloud-0.7.0-py3-none-any.whl
- Upload date:
- Size: 26.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c2779786ab214ed1cc70bc9e4636958c553fddd6733b4b8673c0e58397a27f0c
|
|
| MD5 |
c3e1d76ef33ebb5dbbd4a15d2ecb0e56
|
|
| BLAKE2b-256 |
3279d4c11ff6412962e6861e8b4c5119279957990d1ac72fb6736bce30f26066
|