Famacase test management plugin for pytest. Drop-in transport swap for qase-pytest pointed at the Famacase Reporter Ingestion API.
Project description
famacase-pytest
Drop-in transport swap for qase-pytest. You keep writing
tests with the upstream @qase.* decorators and the upstream pytest plugin
\u2014 we just redirect the HTTP calls to the Famacase Reporter Ingestion
API instead of qase.io.
- Zero source-level changes to existing Qase test suites.
- Same wire format, same decorators, same markers, same BDD plugin.
- Switching back and forth between Qase and Famacase is a single env-var flip.
60-second migration
Already using qase-pytest? Three steps:
# 1. Install us alongside qase-pytest (we depend on it).
pip install famacase-pytest
# 2. Point at the Famacase backend.
export FAMACASE_API_URL=https://famacase.example.com
export FAMACASE_TESTOPS_API_TOKEN=rep_xxxxxxxxxxxxxxxx # your reporter token
export FAMACASE_TESTOPS_PROJECT=SMOKE # your project code
export FAMACASE_MODE=testops
# 3. Run your existing tests \u2014 no code changes.
pytest
That's it. Your @qase.title(...), @qase.suite(...), @qase.id(...)
decorators still work; results land in Famacase.
Sample test (vanilla qase decorators)
# tests/test_login.py
from qase.pytest import qase
@qase.title("Login works")
@qase.suite("Smoke")
@qase.severity("critical")
def test_login_works():
assert 1 + 1 == 2
Run it:
FAMACASE_API_URL=https://famacase.example.com \
FAMACASE_TESTOPS_API_TOKEN=rep_xxxxxxxxxxxxxxxx \
FAMACASE_TESTOPS_PROJECT=SMOKE \
FAMACASE_MODE=testops \
FAMACASE_TESTOPS_RUN_TITLE="Local smoke" \
FAMACASE_TESTOPS_RUN_COMPLETE=true \
pytest
You'll see the run link printed on completion:
[Qase][info] Famacase run link: https://famacase.example.com/runs/123
Configuration
Anything that worked with qase-pytest works here \u2014 we accept
both QASE_* and FAMACASE_* env vars, and both qase.config.json
and famacase.config.json files. The FAMACASE_* form wins when both are
set on the same key.
Env vars
| FAMACASE_* | QASE_* equivalent | Purpose |
|---|---|---|
FAMACASE_MODE |
QASE_MODE |
off / report / testops |
FAMACASE_FALLBACK |
QASE_FALLBACK |
Fallback mode if testops fails |
FAMACASE_DEBUG |
QASE_DEBUG |
Verbose plugin logs |
FAMACASE_API_URL |
(no equivalent) | Famacase backend host. Overrides testops.api.host |
FAMACASE_REPORTER_TOKEN |
(no equivalent) | Project-scoped reporter token |
FAMACASE_TESTOPS_API_TOKEN |
QASE_TESTOPS_API_TOKEN |
Same token, upstream-style name |
FAMACASE_TESTOPS_API_HOST |
QASE_TESTOPS_API_HOST |
Same as FAMACASE_API_URL |
FAMACASE_TESTOPS_PROJECT |
QASE_TESTOPS_PROJECT |
Project code |
FAMACASE_TESTOPS_PLAN_ID |
QASE_TESTOPS_PLAN_ID |
Restrict run to a test plan |
FAMACASE_TESTOPS_RUN_ID |
QASE_TESTOPS_RUN_ID |
Append to an existing run |
FAMACASE_TESTOPS_RUN_TITLE |
QASE_TESTOPS_RUN_TITLE |
Run title |
FAMACASE_TESTOPS_RUN_DESCRIPTION |
QASE_TESTOPS_RUN_DESCRIPTION |
Run description |
FAMACASE_TESTOPS_RUN_COMPLETE |
QASE_TESTOPS_RUN_COMPLETE |
Auto-complete the run at session end |
FAMACASE_TESTOPS_RUN_TAGS |
QASE_TESTOPS_RUN_TAGS |
Comma-separated run tags |
FAMACASE_TESTOPS_BATCH_SIZE |
QASE_TESTOPS_BATCH_SIZE |
Result batch size |
FAMACASE_ENVIRONMENT |
QASE_ENVIRONMENT |
Environment slug |
FAMACASE_ROOT_SUITE |
QASE_ROOT_SUITE |
Root suite override |
FAMACASE_REPORT_DRIVER |
QASE_REPORT_DRIVER |
Local report driver (when mode=report) |
Tuning knobs (no upstream equivalent):
| Env var | Default | Purpose |
|---|---|---|
FAMACASE_TIMEOUT |
30 |
HTTP timeout (seconds) |
FAMACASE_RETRY_ATTEMPTS |
3 |
Retries on transient {502,503,504}/connection errors |
FAMACASE_ATTACHMENT_WORKERS |
4 |
Threads for parallel attachment uploads |
CLI flags
Every upstream --qase-* flag has a --famacase-* twin. Both are accepted;
the --qase-* version wins on conflict (so explicit per-invocation Qase
overrides keep working).
pytest --famacase-mode=testops --famacase-testops-project=SMOKE
# or equivalently
pytest --qase-mode=testops --qase-testops-project=SMOKE
famacase.config.json
Drop a famacase.config.json (or keep your existing qase.config.json \u2014
we read it as a fallback) next to where you invoke pytest:
{
"mode": "testops",
"testops": {
"api": {
"host": "https://famacase.example.com",
"token": "rep_xxxxxxxxxxxxxxxx"
},
"project": "SMOKE",
"run": {
"title": "Local smoke",
"complete": true
}
}
}
How it works
Internally we monkey-patch two upstream classes at plugin load time:
qase.commons.client.api_v2_client.ApiV2Client\u2192FamacaseClientqase.commons.TestOpsPlanLoader\u2192FamacasePlanLoader
The FamacaseClient is a BaseApiClient subclass that speaks the Famacase
Reporter Ingestion API at /api/v1/reporter/v1/* (auth via
Authorization: Token <raw>). The wire payload schema is identical to
upstream's Result model, so every other piece of qase-pytest and
qase-python-commons stays unchanged.
Result of this design: no fork, no maintenance drift. Every fix or
feature in upstream qase-pytest is yours for free on the next pip
upgrade.
Drop-in features inherited from qase-pytest
These all work unchanged because we only replace the HTTP transport:
@qase.id,@qase.title,@qase.suite,@qase.fields,@qase.author,@qase.description,@qase.preconditions,@qase.postconditions,@qase.severity,@qase.priority,@qase.layer,@qase.ignore,@qase.muted,@qase.attach,@qase.project_id, etc.qase.runtime.add_step(...)/ step trees- BDD via
pytest-bdd - Parametrize handling and xfail/xpass mapping
- Local file reporter (
mode=report) - Profilers (
--qase-profilers=network,db,sleep) - Multi-project mode (
@qase.project_id)
Status mapping
Upstream qase-pytest maps pytest outcomes to status strings. Our backend
accepts both canonical names and upstream synonyms, so nothing has to be
translated client-side:
| Pytest outcome | qase string | Famacase canonical |
|---|---|---|
| pass | passed |
passed |
| fail (assert) | failed |
failed |
fail (pytest.fail(...)) |
invalid (BROKEN) |
invalid |
| skip | skipped |
skipped |
qase.muted() block |
blocked |
blocked |
Tests
# Unit tests (offline, mocked HTTP). No backend required.
PYTHONPATH=src python3 -m pytest tests_unit -v
# Live API regression. Requires the Famacase stack running on localhost:8000
# and the SMOKE project seeded (see tests/conftest.py).
python3 -m pytest tests -v
# E2E drop-in proof: spawns a pytest subprocess against `tests_e2e/sample_project/`
# using only vanilla qase decorators, then asserts the run + results landed
# in the backend via the reporter API. Requires the live stack.
PYTHONPATH=src python3 -m pytest tests_e2e -v
Full combined regression (unit + live + E2E): 79 tests, ~8 seconds.
License
Apache-2.0. Same license as upstream qase-pytest for ease of merging
fixes.
Project details
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 famacasepytest-0.1.3.tar.gz.
File metadata
- Download URL: famacasepytest-0.1.3.tar.gz
- Upload date:
- Size: 34.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
79b26a277acf5afacc42eb647b7fa436cbe386ac39d93ccc036dce360c51dff5
|
|
| MD5 |
d25a93d1bc99e5a47d80f0d0858c04c8
|
|
| BLAKE2b-256 |
a8dd77f84b7f05ed255d6e2af4e21ee55e5ff4e2a3f67a3c35a0387cec3319b5
|
Provenance
The following attestation bundles were made for famacasepytest-0.1.3.tar.gz:
Publisher:
release.yml on dsetiawan230294/famacase-pytest
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
famacasepytest-0.1.3.tar.gz -
Subject digest:
79b26a277acf5afacc42eb647b7fa436cbe386ac39d93ccc036dce360c51dff5 - Sigstore transparency entry: 1716847391
- Sigstore integration time:
-
Permalink:
dsetiawan230294/famacase-pytest@1b2a6e250010ab58454865b97328a7b7e7850d50 -
Branch / Tag:
refs/tags/v.0.1.3 - Owner: https://github.com/dsetiawan230294
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1b2a6e250010ab58454865b97328a7b7e7850d50 -
Trigger Event:
release
-
Statement type:
File details
Details for the file famacasepytest-0.1.3-py3-none-any.whl.
File metadata
- Download URL: famacasepytest-0.1.3-py3-none-any.whl
- Upload date:
- Size: 39.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f8ba34d60d70637ee2407ffa04f4f8335aeeba53f52bc372a3ce746f7d4eec4
|
|
| MD5 |
e0c3ccc8ba9088a092cf63301b4aac6b
|
|
| BLAKE2b-256 |
538d505cc8799e1032ccccd1d93c6b3237ea0f3587dff7440b62781b1f5c629d
|
Provenance
The following attestation bundles were made for famacasepytest-0.1.3-py3-none-any.whl:
Publisher:
release.yml on dsetiawan230294/famacase-pytest
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
famacasepytest-0.1.3-py3-none-any.whl -
Subject digest:
6f8ba34d60d70637ee2407ffa04f4f8335aeeba53f52bc372a3ce746f7d4eec4 - Sigstore transparency entry: 1716847521
- Sigstore integration time:
-
Permalink:
dsetiawan230294/famacase-pytest@1b2a6e250010ab58454865b97328a7b7e7850d50 -
Branch / Tag:
refs/tags/v.0.1.3 - Owner: https://github.com/dsetiawan230294
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1b2a6e250010ab58454865b97328a7b7e7850d50 -
Trigger Event:
release
-
Statement type: