Qase TestOps Pytest Reporter
Qase Pytest Reporter enables seamless integration between your Pytest tests and Qase TestOps, providing automatic test result reporting, test case management, and comprehensive test analytics.
Features
- Link automated tests to Qase test cases by ID
- Auto-create test cases from your test code
- Report test results with rich metadata (fields, attachments, steps)
- Support for parameterized tests
- Multi-project reporting support
- Flexible configuration (file, environment variables, CLI)
- Built-in support for Playwright-based tests
Installation
pip install qase-pytest
Quick Start
1. Create qase.config.json in your project root:
{
"mode": "testops",
"testops": {
"project": "YOUR_PROJECT_CODE",
"api": {
"token": "YOUR_API_TOKEN",
"host": "qase.io"
}
}
}
If your workspace is on the EU cluster (you open Qase at app-eu.qase.io), set host to eu.qase.io. The default, qase.io, is the US cluster.
2. Add Qase ID to your test:
from qase.pytest import qase
@qase.id(1)
def test_example():
assert True
3. Run your tests:
pytest
Upgrading
For migration guides between major versions, see Upgrade Guide.
Configuration
The reporter is configured via (in order of priority):
- CLI options (
--qase-*, highest priority) - Environment variables (
QASE_*) - Config file (
qase.config.json)
Minimal Configuration
| Option | Environment Variable | CLI Option | Description |
|---|---|---|---|
mode |
QASE_MODE |
--qase-mode |
Set to testops to enable reporting |
testops.project |
QASE_TESTOPS_PROJECT |
--qase-testops-project |
Your Qase project code |
testops.api.token |
QASE_TESTOPS_API_TOKEN |
--qase-testops-api-token |
Your Qase API token |
testops.api.host |
QASE_TESTOPS_API_HOST |
— | qase.io (US cluster, the default) or eu.qase.io (EU cluster). Required if your workspace is on the EU cluster |
Example qase.config.json
{
"mode": "testops",
"fallback": "report",
"testops": {
"project": "YOUR_PROJECT_CODE",
"api": {
"token": "YOUR_API_TOKEN",
"host": "qase.io"
},
"run": {
"title": "Pytest Automated Run"
},
"batch": {
"size": 100
}
},
"report": {
"driver": "local",
"connection": {
"local": {
"path": "./build/qase-report",
"format": "json"
}
}
},
"framework": {
"pytest": {
"captureLogs": true
}
}
}
Full configuration reference: See qase-python-commons for all available options including logging, status mapping, execution plans, and more.
Usage
Link Tests with Test Cases
Associate your tests with Qase test cases using test case IDs:
from qase.pytest import qase
# Single ID
@qase.id(1)
def test_single_id():
assert True
# Multiple IDs
@qase.id([2, 3])
def test_multiple_ids():
assert True
Add Metadata
Enhance your tests with additional information:
from qase.pytest import qase
@qase.id(1)
@qase.title("User Login Test")
@qase.suite("Authentication")
@qase.fields(
("severity", "critical"),
("priority", "high"),
("layer", "e2e"),
("description", "Verify user can log in with valid credentials"),
("preconditions", "User account exists in the system"),
)
def test_user_login():
assert True
Ignore Tests
Exclude specific tests from Qase reporting (test still runs, but results are not sent):
from qase.pytest import qase
@qase.ignore()
def test_not_reported():
assert True
Test Result Statuses
| Pytest Result | Qase Status |
|---|---|
| Passed | passed |
| Failed (AssertionError) | failed |
| Failed (other exception) | invalid |
| Skipped | skipped |
Attachments
Attach files, screenshots, and logs to test results:
from qase.pytest import qase
def test_with_attachments():
# Attach file from path
qase.attach("/path/to/file.txt")
# Attach with custom MIME type
qase.attach(("/path/to/file.json", "application/json"))
# Attach content from memory
qase.attach((b"screenshot data", "image/png", "screenshot.png"))
assert True
Test Steps
Define test steps for detailed reporting:
from qase.pytest import qase
@qase.step("Open login page")
def open_login():
pass
@qase.step("Enter credentials")
def enter_credentials(username, password):
pass
def test_login():
open_login()
enter_credentials("user", "pass")
# Inline step with context manager
with qase.step("Click login button"):
pass
For detailed usage examples, see the Usage Guide.
Running Tests
Basic Execution
pytest
With CLI Options
pytest \
--qase-mode=testops \
--qase-testops-project=PROJ \
--qase-testops-api-token=your_token
With Environment Variables
export QASE_MODE=testops
export QASE_TESTOPS_PROJECT=PROJ
export QASE_TESTOPS_API_TOKEN=your_token
export QASE_TESTOPS_API_HOST=qase.io # eu.qase.io for the EU cluster
pytest
With Existing Test Run
pytest --qase-testops-run-id=123
With Test Plan
pytest --qase-testops-plan-id=456
Requirements
- Python >= 3.9
- pytest >= 7.0.0
Documentation
| Guide | Description |
|---|---|
| Usage Guide | Complete usage reference with all decorators and options |
| Attachments | Adding screenshots, logs, and files to test results |
| Steps | Defining test steps for detailed reporting |
| Parameters | Working with parameterized tests |
| Multi-Project Support | Reporting to multiple Qase projects |
| Upgrade Guide | Migration guide for breaking changes |
Examples
See the examples directory for complete working examples.
License
Apache License 2.0. See LICENSE for details.
Using with pytest-bdd
If pytest-bdd is installed alongside qase-pytest, Gherkin scenarios
are reported with full step hierarchy automatically — no manual
qase.step() instrumentation required.
Feature file
Feature: Login
@qase.id=42 @qase.suite=Login.Smoke
Scenario: Successful login
Given the user is on the login page
When the user enters valid credentials
Then the user should see the dashboard
Test module
from pytest_bdd import scenarios
scenarios("features/login.feature")
Scenario name becomes the test title, the Feature becomes the parent suite,
each step is captured with its Given/When/Then keyword. You can still
use with qase.step("..."): inside a step function to add nested
sub-steps — they will appear as children of the Gherkin step.
Recognized scenario tags
Place tags on the Scenario line so they reach the plugin via
scenario.tags:
| Tag | Effect |
|---|---|
@qase.id=123 |
Link to test case 123 |
@qase.id=123,124 |
Link to multiple test cases |
@qase.project_id.CODE=1,2 |
Multi-project link |
@qase.ignore |
Skip the scenario from reporting |
@qase.muted |
Do not let this scenario fail the run |
@qase.suite=A.B.C |
Override suite (dot for nesting) |
@qase.severity=critical |
Set severity field |
@qase.priority=high |
Set priority field |
@qase.layer=e2e |
Set layer field |
| Any other tag | Stored as a free tag on the result |
Versions
Tested with pytest-bdd >= 7.0, < 9.0. pytest-bdd-ng is expected to
work but is not officially tested.
Metadata
Release files for qase-pytest 9.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| qase_pytest-9.0.1.tar.gz | 28.4 kB | Without provenance | Details for qase_pytest-9.0.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| qase_pytest-9.0.1-py3-none-any.whl | Python 3 | none | any | Details for qase_pytest-9.0.1-py3-none-any.whl |
Total release size: 55.0 kB
Release files / qase_pytest-9.0.1.tar.gz
| Download URL | qase_pytest-9.0.1.tar.gz |
|---|---|
| Size | 28.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2aa71dfed823a9675bf0ae3e9620d9f3d33cfe677d8ef3b5dd08ffe924b4f19d
|
|
BLAKE2b-256 checksum How to use checksums |
53b69ec0ea6310eb18ee2bd0202362f970d2ab9863913f0128a8bc8e4826b5a1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / qase_pytest-9.0.1-py3-none-any.whl
| Download URL | qase_pytest-9.0.1-py3-none-any.whl |
|---|---|
| Size | 26.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dc9abe29e3b06889b2db5a9bbfd470220937975251bb569e63f313ade52abd05
|
|
BLAKE2b-256 checksum How to use checksums |
aa576156a5413f06e255ecbf5b6840dbfb0c0a28e4ae80fd4ec1ec901cbb0003
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Security for qase-pytest 9.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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.