Appium/pytest test analytics reporter — command timeline, device log capture (logcat/syslog), network interception, screenshot/video artifacts, and interactive HTML reports for Android and iOS.
Project description
testrelic-appium
Appium test analytics reporter for pytest — captures command timelines,
device logs (Android logcat / iOS syslog), console logs, network requests,
screenshots, and video, then generates a self-contained interactive HTML
report. Python port of
@testrelic/appium-analytics.
What it does
When you run your Appium tests with pytest and the testrelic-appium plugin
installed, you get JSON + HTML reports that capture:
- Command timeline — every Appium / WebDriver command with timing,
category (
find,interaction,gesture,navigation,lifecycle,context,device,keyboard,alert,screenshot,other), selector, arguments (sensitive ones redacted), and result. - Device logs — Android
logcat, iOSsyslogandcrashlog, polled in the background and sliced per test. - Console logs — WebView / browser console output via WebDriver BiDi
(
log.entryAdded) when supported, with polling fallback (browser,safariConsole). - Network capture — Chrome DevTools Protocol performance logs (Android),
safariNetwork(iOS), with optionalmitmproxyfallback for emulators without CDP. - Screenshots & video — configurable: off, on every test, on failure, or
on every step. Video uses Appium recording commands first, falling back to
adb screenrecord. - Assertions —
assert_that(...)context manager records named assertion steps; bareassertstatements are picked up bypytest_assertion_pass. - CI metadata — auto-detect GitHub Actions, GitLab CI, Jenkins, CircleCI, Bitbucket Pipelines.
- Sensitive-data redaction — AWS access keys, Bearer tokens, PEM private
keys, embedded URL credentials, plus Appium-specific command-argument
redaction (
elementSendKeys,setValueImmediate,replaceValue). - HTML report — self-contained, opens in any browser.
System requirements
The package itself has no platform requirements beyond Python, but to test mobile apps you'll need the standard Appium tooling on your machine. None of these are pip dependencies — they are subprocess dependencies the SDK invokes when needed.
| Tool | Required for |
|---|---|
Appium server (npm install -g appium) |
All tests |
appium driver install uiautomator2 |
Android |
appium driver install xcuitest |
iOS (macOS only) |
adb on PATH |
Android device-log capture, video recording fallback, proxy network capture |
xcrun simctl |
iOS simulators |
iOS testing requires macOS 13+ with Xcode 15+. iOS tests cannot run on Windows or Linux.
Quick start
1. Install
pip install testrelic-appium
The plugin activates automatically because testrelic-appium registers a
pytest11 entry point. No conftest.py plumbing required.
For the optional HTTPS network-capture proxy:
pip install "testrelic-appium[network-proxy]"
2. Write a test
Use any Appium driver instantiation pattern. The plugin walks
item.funcargs after each fixture resolves and per-instance wraps any
appium.webdriver.webdriver.WebDriver it finds — Selenium-only tests are
never touched.
# tests/test_login.py
import pytest
from appium import webdriver
from appium.options.android import UiAutomator2Options
@pytest.fixture
def driver():
options = UiAutomator2Options()
options.platform_name = "Android"
options.device_name = "emulator-5554"
options.app = "/path/to/MyApp.apk"
d = webdriver.Remote("http://127.0.0.1:4723", options=options)
yield d
d.quit()
def test_login_succeeds(driver):
driver.find_element("accessibility id", "username").send_keys("alice")
driver.find_element("accessibility id", "password").send_keys("hunter2")
driver.find_element("accessibility id", "submit").click()
assert driver.find_element("accessibility id", "welcome").is_displayed()
3. Run
pytest
Outputs land in:
test-results/
├── testrelic-timeline.json
└── testrelic-timeline.html
Configuration
Reporter options can be supplied three ways (highest priority first):
- Environment variables (
TESTRELIC_API_KEY,TESTRELIC_CLOUD_ENDPOINT,TESTRELIC_UPLOAD_STRATEGY,TESTRELIC_CLOUD_TIMEOUT,TESTRELIC_RUN_TYPE). pytest.ini/pyproject.tomlundertestrelic_options..testrelic/testrelic-config.jsonin the project root.
pyproject.toml
[tool.pytest.ini_options]
testrelic_options = [
"outputPath=./test-results/testrelic-timeline.json",
"includeDeviceLogs=true",
"includeNetworkLogs=true",
"screenshotOnEvery=failure",
"includeVideoRecording=false",
]
CLI flags
pytest --testrelic-output ./test-results/custom.json
pytest --testrelic-disable # turn the reporter off for this run
pytest --testrelic-quiet # suppress banner output
pytest --testrelic-no-autowrap # disable WebDriver auto-detection
Full option list
| Option | Type | Default | Description |
|---|---|---|---|
outputPath |
str | ./test-results/testrelic-timeline.json |
JSON report path |
htmlReportPath |
str | derived from outputPath |
HTML report path |
openReport |
bool | false |
Open the HTML report in the default browser after the run |
includeDeviceLogs |
bool | true |
Capture Android logcat / iOS syslog and crashlog |
includeNetworkLogs |
bool | true |
Capture HTTP network requests and responses |
includeConsoleLogs |
bool | true |
Capture webview / browser console output |
includeScreenshots |
bool | true |
Capture device screenshots |
screenshotOnEvery |
off | on | on-failure | on-every-step |
on-failure |
When to take screenshots |
includeVideoRecording |
bool | false |
Record the device screen for each test |
includeCommands |
bool | true |
Record every Appium / WebDriver command |
includeAssertions |
bool | true |
Record assertion steps |
deviceLogPollInterval |
int (ms) | 1000 |
Interval between device log polls (min 100) |
maxDeviceLogMb |
int | 20 |
Truncate per-test device log buffer above this size |
preferBiDi |
bool | true |
Try BiDi log.entryAdded before polling |
redactPatterns |
list[str] | [] |
Extra regex patterns to redact (built-ins always apply) |
quiet |
bool | false |
Suppress the console summary table at session end |
metadata |
dict | null |
Arbitrary key-value pairs attached to the run report |
cloud |
object | — | Cloud upload configuration (see below) |
Cloud integration
Set TESTRELIC_API_KEY and the reporter uploads the run to
https://platform.testrelic.ai/api/v1/runs at session end.
export TESTRELIC_API_KEY=tk_live_...
export TESTRELIC_UPLOAD_STRATEGY=both # realtime | batch | both | none
Or use a project file:
// .testrelic/testrelic-config.json
{
"cloud": {
"apiKey": "$TESTRELIC_API_KEY",
"endpoint": "https://platform.testrelic.ai/api/v1",
"upload": "both",
"projectName": "my-mobile-app"
}
}
Network failures are queued to .testrelic/queue/ and retried with:
testrelic-appium drain
testrelic-appium cleanup-queue --max-age-days 7
Parallel runs (pytest-xdist)
pytest -n 2 runs workers as separate subprocesses. The master process
creates the cloud run during pytest_configure, writes a manifest, and
finalizes the run after all workers exit. Each worker uploads its per-test
realtime data under the master's run ID — exactly one run shows up on the
dashboard.
CLI
testrelic-appium version
testrelic-appium merge shard-1.json shard-2.json -o merged.json
testrelic-appium serve ./test-results --port 9323
testrelic-appium drain
testrelic-appium cleanup-queue --max-age-days 7
Manual driver wrap
If auto-detection misses your driver (custom subclass, fixture indirection, non-pytest harness), use the explicit fixture or wrap function:
import pytest
from testrelic_appium import testrelic_appium_driver # fixture
def test_with_explicit_fixture(testrelic_appium_driver):
driver = testrelic_appium_driver # already wrapped
driver.find_element("accessibility id", "btn").click()
from testrelic_appium import wrap_driver
def test_with_manual_wrap(driver):
unwrap = wrap_driver(driver)
try:
driver.find_element("accessibility id", "btn").click()
finally:
unwrap()
Compatibility
- Python 3.9 – 3.12
- pytest 7.0+
- Appium-Python-Client 4.x – 5.x
- Appium 2.x / 3.x
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
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 testrelic_appium-0.2.0.tar.gz.
File metadata
- Download URL: testrelic_appium-0.2.0.tar.gz
- Upload date:
- Size: 59.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
732278a86bae369cf1a383c14c408b5c598d9080424898baf86f8c53644a85ee
|
|
| MD5 |
5e82580022734f70d7019755d1d44cff
|
|
| BLAKE2b-256 |
86fdf5af1e6e83004bb67aebfcabaa48eadcd8967a1b590be5a41df050efcf9e
|
Provenance
The following attestation bundles were made for testrelic_appium-0.2.0.tar.gz:
Publisher:
publish-appium-prod.yml on testrelic-ai/testrelic-python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
testrelic_appium-0.2.0.tar.gz -
Subject digest:
732278a86bae369cf1a383c14c408b5c598d9080424898baf86f8c53644a85ee - Sigstore transparency entry: 1719162249
- Sigstore integration time:
-
Permalink:
testrelic-ai/testrelic-python-sdk@f0aff5efb889a31267c2be2d9bf34b921541dc1e -
Branch / Tag:
refs/heads/prod - Owner: https://github.com/testrelic-ai
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-appium-prod.yml@f0aff5efb889a31267c2be2d9bf34b921541dc1e -
Trigger Event:
push
-
Statement type:
File details
Details for the file testrelic_appium-0.2.0-py3-none-any.whl.
File metadata
- Download URL: testrelic_appium-0.2.0-py3-none-any.whl
- Upload date:
- Size: 80.5 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 |
fcfa5bfd9034e7fcae0f30a37e2c3d10d2b800ad3f392c7be5dc1e485404d332
|
|
| MD5 |
aa7e16189e769bee78bcbd4029fd1c93
|
|
| BLAKE2b-256 |
bd672548ae85702d5759e86a318722911f2f44dfe71007081231f4716a7fc0e6
|
Provenance
The following attestation bundles were made for testrelic_appium-0.2.0-py3-none-any.whl:
Publisher:
publish-appium-prod.yml on testrelic-ai/testrelic-python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
testrelic_appium-0.2.0-py3-none-any.whl -
Subject digest:
fcfa5bfd9034e7fcae0f30a37e2c3d10d2b800ad3f392c7be5dc1e485404d332 - Sigstore transparency entry: 1719162307
- Sigstore integration time:
-
Permalink:
testrelic-ai/testrelic-python-sdk@f0aff5efb889a31267c2be2d9bf34b921541dc1e -
Branch / Tag:
refs/heads/prod - Owner: https://github.com/testrelic-ai
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-appium-prod.yml@f0aff5efb889a31267c2be2d9bf34b921541dc1e -
Trigger Event:
push
-
Statement type: