Core library for all Qase Python reporters. Contains the complete configuration reference.
This module is an SDK for developing test reporters for Qase TMS. It uses qase-api-client as an API client, and all Qase Python reporters depend on this package.
Use this library if:
- You're developing a custom reporter for a specialized framework
- You need a complete configuration reference
For testing, use the ready-made reporters — see Reporters section.
pip install qase-python-commonsFor popular frameworks, use the ready-made reporters:
| Framework | Package | Documentation |
|---|---|---|
| Pytest | qase-pytest |
README |
| Behave | qase-behave |
README |
| Robot Framework | qase-robotframework |
README |
| Tavern | qase-tavern |
README |
Qase Python reporters support three configuration methods (in order of priority):
- CLI options (pytest and tavern only) — highest priority
- Environment variables (
QASE_*) - Config file (
qase.config.json) — lowest priority
The reporter mode is set via the mode option:
| Mode | Description |
|---|---|
testops |
Send results to a single Qase project |
testops_multi |
Send results to multiple projects |
report |
Generate a local JSON report |
off |
Reporter disabled (default) |
| Description | Config file | Environment variable | Default | Required |
|---|---|---|---|---|
| Reporter mode | mode |
QASE_MODE |
off |
No |
| Fallback mode | fallback |
QASE_FALLBACK |
off |
No |
| Environment | environment |
QASE_ENVIRONMENT |
— | No |
| Root suite | rootSuite |
QASE_ROOT_SUITE |
— | No |
| Debug mode | debug |
QASE_DEBUG |
False |
No |
| Execution plan path | executionPlan.path |
QASE_EXECUTION_PLAN_PATH |
./build/qase-execution-plan.json |
No |
| Exclude parameters | excludeParams |
QASE_EXCLUDE_PARAMS |
— | No |
| Status mapping | statusMapping |
QASE_STATUS_MAPPING |
— | No |
| Description | Config file | Environment variable | Default | Required |
|---|---|---|---|---|
| API token | testops.api.token |
QASE_TESTOPS_API_TOKEN |
— | Yes* |
| API host | testops.api.host |
QASE_TESTOPS_API_HOST |
qase.io |
No |
| Request timeout, seconds | testops.api.timeout |
QASE_TESTOPS_API_TIMEOUT |
30 |
No |
| Upload attempts | testops.api.retries |
QASE_TESTOPS_API_RETRIES |
3 |
No |
| Retry backoff base, seconds | testops.api.retryBackoff |
QASE_TESTOPS_API_RETRY_BACKOFF |
2 |
No |
| Project code | testops.project |
QASE_TESTOPS_PROJECT |
— | Yes* |
| Test run ID | testops.run.id |
QASE_TESTOPS_RUN_ID |
— | No |
| Test run title | testops.run.title |
QASE_TESTOPS_RUN_TITLE |
Automated run <date> |
No |
| Test run description | testops.run.description |
QASE_TESTOPS_RUN_DESCRIPTION |
<Framework> automated run |
No |
| Complete test run | testops.run.complete |
QASE_TESTOPS_RUN_COMPLETE |
True |
No |
| Test run tags | testops.run.tags |
QASE_TESTOPS_RUN_TAGS |
[] |
No |
| External link | testops.run.externalLink |
QASE_TESTOPS_RUN_EXTERNAL_LINK |
— | No |
| Test plan ID | testops.plan.id |
QASE_TESTOPS_PLAN_ID |
— | No |
| Batch size | testops.batch.size |
QASE_TESTOPS_BATCH_SIZE |
200 |
No |
| Create defects | testops.defect |
QASE_TESTOPS_DEFECT |
False |
No |
| Status filter | testops.statusFilter |
QASE_TESTOPS_STATUS_FILTER |
— | No |
| Configuration values | testops.configurations.values |
QASE_TESTOPS_CONFIGURATIONS_VALUES |
— | No |
| Create configurations | testops.configurations.createIfNotExists |
QASE_TESTOPS_CONFIGURATIONS_CREATE_IF_NOT_EXISTS |
false |
No |
| Show public report link | testops.showPublicReportLink |
QASE_TESTOPS_SHOW_PUBLIC_REPORT_LINK |
False |
No |
* Required when using testops mode
| Description | Config file | Environment variable | Default | Required |
|---|---|---|---|---|
| Default project | testops_multi.default_project |
QASE_TESTOPS_MULTI_DEFAULT_PROJECT |
— | No |
| Projects array | testops_multi.projects |
— | [] |
Yes** |
| Project code | testops_multi.projects[].code |
— | — | Yes** |
| Test run title | testops_multi.projects[].run.title |
— | Automated Run <code> <date> |
No |
| Test run description | testops_multi.projects[].run.description |
— | Automated Run <code> <date> |
No |
| Complete test run | testops_multi.projects[].run.complete |
— | True |
No |
| Test run ID | testops_multi.projects[].run.id |
— | — | No |
| Test run tags | testops_multi.projects[].run.tags |
— | [] |
No |
| External link | testops_multi.projects[].run.externalLink |
— | — | No |
| Test plan ID | testops_multi.projects[].plan.id |
— | — | No |
| Environment | testops_multi.projects[].environment |
— | Global | No |
** Required when using testops_multi mode
Multi-project annotations:
| Framework | Syntax |
|---|---|
| Pytest | @qase.project_id("CODE", 1, 2, 3) |
| Behave | @qase.project_id.CODE:1,2,3 |
| Robot Framework | Q-PROJECT.CODE-1,2,3 |
| Tavern | QaseProjectID.CODE=1,2,3 in test name |
See details: Pytest | Behave | Robot Framework | Tavern
| Description | Config file | Environment variable | Default |
|---|---|---|---|
| Driver | report.driver |
QASE_REPORT_DRIVER |
local |
| Report path | report.connection.path |
QASE_REPORT_CONNECTION_PATH |
./build/qase-report |
| Report format | report.connection.format |
QASE_REPORT_CONNECTION_FORMAT |
json |
| Description | Config file | Environment variable | Default |
|---|---|---|---|
| Console output | logging.console |
QASE_LOGGING_CONSOLE |
True |
| File output | logging.file |
QASE_LOGGING_FILE |
Same as debug |
| Description | Config file | Environment variable | CLI | Default |
|---|---|---|---|---|
| Capture logs | framework.pytest.captureLogs |
QASE_PYTEST_CAPTURE_LOGS |
--qase-pytest-capture-logs |
False |
| XFail status (failed) | framework.pytest.xfailStatus.xfail |
QASE_PYTEST_XFAIL_STATUS_XFAIL |
--qase-pytest-xfail-status-xfail |
Skipped |
| XFail status (passed) | framework.pytest.xfailStatus.xpass |
QASE_PYTEST_XFAIL_STATUS_XPASS |
--qase-pytest-xfail-status-xpass |
Passed |
These frameworks use only the common configuration options.
{
"mode": "testops",
"fallback": "report",
"debug": false,
"environment": "local",
"testops": {
"api": {
"token": "<token>",
"host": "qase.io"
},
"project": "DEMO",
"run": {
"title": "Regress run",
"description": "Automated regression tests",
"complete": true,
"tags": ["regression", "automated"]
},
"batch": {
"size": 100
}
}
}{
"mode": "testops_multi",
"fallback": "report",
"testops": {
"api": {
"token": "<token>",
"host": "qase.io"
},
"batch": {
"size": 100
}
},
"testops_multi": {
"default_project": "DEMO1",
"projects": [
{
"code": "DEMO1",
"run": {
"title": "DEMO1 Test Run",
"tags": ["staging"]
},
"environment": "staging"
},
{
"code": "DEMO2",
"run": {
"title": "DEMO2 Test Run",
"tags": ["production"]
},
"environment": "production"
}
]
}
}# Common settings
export QASE_MODE="testops"
export QASE_FALLBACK="report"
export QASE_ENVIRONMENT="local"
export QASE_DEBUG="false"
# TestOps
export QASE_TESTOPS_API_TOKEN="<token>"
export QASE_TESTOPS_PROJECT="DEMO"
export QASE_TESTOPS_RUN_TITLE="Automated Run"
export QASE_TESTOPS_RUN_COMPLETE="true"
export QASE_TESTOPS_API_TIMEOUT="30"
export QASE_TESTOPS_API_RETRIES="3"
export QASE_TESTOPS_API_RETRY_BACKOFF="2"
# Pytest
export QASE_PYTEST_CAPTURE_LOGS="true"Profilers automatically track operations during test execution and send them as steps to Qase TestOps.
| Profiler | Description | Documentation |
|---|---|---|
network |
Tracks HTTP requests (requests, urllib3) | Network Profiler |
db |
Tracks database operations | Database Profiler |
sleep |
Tracks sleep calls | — |
Enable profilers in qase.config.json:
{
"profilers": ["network", "db"]
}Or via environment variable:
export QASE_PROFILERS="network,db"The profilers array supports both string and object formats. Use the object format to configure profiler-specific options:
{
"profilers": [
{
"name": "network",
"excludeHosts": ["telemetry.local", "monitoring.internal"]
},
"db"
]
}Allows changing test result status before sending to Qase:
{
"statusMapping": {
"invalid": "failed",
"skipped": "passed"
}
}Available statuses: passed, failed, skipped, invalid
Excludes results with specified statuses from being sent:
{
"testops": {
"statusFilter": ["passed", "skipped"]
}
}Associates the test run with external resources (e.g., Jira):
{
"testops": {
"run": {
"externalLink": {
"type": "jiraCloud",
"link": "PROJ-123"
}
}
}
}Types: jiraCloud, jiraServer
Creates or finds configurations in Qase TestOps:
{
"testops": {
"configurations": {
"values": [
{ "name": "browser", "value": "chrome" },
{ "name": "os", "value": "linux" }
],
"createIfNotExists": true
}
}
}Results are uploaded in batches from background threads. A batch that fails on a transient error is retried rather than dropped.
| Setting | Meaning |
|---|---|
testops.api.timeout |
Per-request timeout in seconds. Without it a stalled connection blocks the session at teardown. |
testops.api.retries |
Total attempts per batch, not retries on top of the first. 3 means three tries; 0 sends once and never retries. |
testops.api.retryBackoff |
Base of the exponential delay: attempt n waits retryBackoff ** n seconds. |
Retried: connection resets, timeouts and other transport failures, plus HTTP 408, 429 and 5xx. Not retried: 400, 401, 403, 404, 413, 422 and 507 — a second attempt fails identically and only adds load.
When a 429 carries a Retry-After header, that value replaces the computed
backoff. Qase sends roughly 60 seconds, so a run that hits the rate limit takes
longer to finish rather than losing the batch.
The same timeout and retry settings apply to attachment uploads, which go through the API v1 client in batches of up to 20 files. If an attachment batch cannot be uploaded after all attempts, the reporter logs an error, drops those attachments and still submits the results they belong to — a failed attachment never costs you the test results.
If a batch cannot be delivered after all attempts, the reporter logs an
error naming how many results were lost and does not mark the run complete.
An open run is the signal that its data is incomplete; a completed run over
partial results would look trustworthy and not be. In testops_multi mode this
is per project — one project's failure does not stop the others completing.
{
"testops": {
"api": {
"token": "<token>",
"timeout": 30,
"retries": 3,
"retryBackoff": 2
}
}
}- Python 3.9+
- qase-api-client
Apache 2.0 — see LICENSE