Appium test reporting
@qualflare/appium reports Appium suites run through
WebdriverIO — iOS and Android results with the device, OS version and
driver on every case, every attempt of a retried test, and the screenshots Appium takes — and labels
the launch as Appium. Appium driven from Java or Python is covered by the reporter for that runner instead.
This guide covers the setup, how the platform is read from the session, and the
hosted, historical analysis — AI failure clustering,
flaky-test scoring and per-launch risk — that sits on top.
Which reporter an Appium suite needs
Appium is a server. It drives a device, but it does not run tests, and it does not know which ones passed — the framework that sends it commands does. So the question is never “how does Appium report” but “what is driving it”:
- JavaScript, through WebdriverIO —
@qualflare/appium, this page. - Java — the TestNG or JUnit reporter.
- Python — the pytest reporter.
Send Appium results to Qualflare
npm install --save-dev @qualflare/appium
Add the reporter to wdio.conf, next to the Appium
service that starts the server:
// wdio.conf.js
export const config = {
// ...
capabilities: [{
platformName: 'iOS',
'appium:automationName': 'XCUITest',
'appium:deviceName': 'iPhone 17 Pro',
'appium:app': './build/MyApp.app',
}],
// 'appium' starts the Appium server. No Qualflare service is
// needed: every worker derives one run id from the launcher.
services: ['appium'],
reporters: ['spec', ['@qualflare/appium', { environment: 'staging' }]],
afterTest: async function (test, context, { passed }) {
if (!passed) await driver.takeScreenshot();
},
}; npx wdio run wdio.conf.js qf myapp collect ./qualflare-results
Each spec file runs in its own WebdriverIO worker and writes its own report, and
qf collect merges the reports that share one run id.
Every worker derives that id from the wdio run launcher
process, or uses the CI provider's, so the whole run lands in one launch with nothing to configure. The
WebdriverIO guide explains the mechanism, and
when the optional @qualflare/appium/service is still
worth adding. Upload with @qualflare/cli v0.1.37 or
newer, the first release that labels these launches as Appium.
Reading the platform from a real session
The device a test ran on is the most useful fact about a mobile failure, and it is in the session's capabilities — but not quite where the documentation suggests. This is what a real XCUITest session driving mobile Safari returns:
// What a real XCUITest session hands back (mobile Safari, iOS simulator)
{
"platformName": "iOS", // ← read: the platform is ios
"browserName": "Safari", // ← also present; must NOT make it "web"
"deviceName": "iPhone 17 Pro", // ← unprefixed, though sent as appium:deviceName
"platformVersion": "26.5",
"automationName": "XCUITest",
"platform": "MAC" // ← legacy key; never read
}
Three things in that object would each produce a wrong answer if read naively, and the reporter is tested
against a real session for all three. The keys come back unprefixed,
though they were sent as appium:*. The session names a
browser as well as a mobile platform, so checking the browser first
would file a mobile-Safari run under web. And a legacy platform:
"MAC" describes the simulator's host, not the device. The platform comes from
platformName; the device, OS version and driver are
recorded on every case.
Each test's history is kept per platform — ios,
android, or
ios-safari for a browser session — so a suite run on both
keeps two histories instead of one overwriting the other. Device model and OS version are deliberately left
out of that identity, so moving to a newer simulator keeps the history intact.
What else gets captured
- Retries, attempt by attempt, each with its own error and timing; a test that passed on retry is marked flaky.
- Screenshots from
driver.takeScreenshot(), attached to the test and attempt they were taken for — including fromafterTest. - Your own metadata — labels, steps and masked parameters — from
@qualflare/appium/runtime.
The reporter is tested the way it is used: every week, a real Appium session drives mobile Safari on an iOS simulator, and its results are uploaded to Qualflare through the published CLI. Running Appium alongside native suites? See Espresso, XCTest and Maestro reporting, or browse all framework reporting guides.
Frequently asked questions
Is there a native Qualflare reporter for Appium?
Yes, for Appium’s JavaScript client: @qualflare/appium, Apache-2.0 on npm, for Appium suites run through WebdriverIO. It is @qualflare/webdriverio’s reporter with Appium’s label, so launches appear in Qualflare as Appium, with the platform, device, OS version and driver recorded on every case.
My Appium tests are in Java or Python. What do I use?
The reporter for your test runner. Appium itself is a server; the results belong to the framework driving it. A Java suite on TestNG or JUnit 5 uses qualflare-testng or qualflare-junit5, and a Python suite on pytest uses qualflare-pytest. Each also uploads the plain JUnit-XML those runners already write, with no reporter at all.
How does Qualflare know a run was iOS or Android?
From the session’s own capabilities, read the way a real session returns them. XCUITest hands back platformName, deviceName, platformVersion and automationName unprefixed, although the request sends them as appium:*, so the reporter reads both. The platform is decided by platformName first: mobile Safari reports a browser name as well, and checking the browser first would label every mobile-Safari run as web. The same session also carries a legacy platform: MAC for an iOS simulator, which the reporter never reads.
Will moving to a newer simulator break my test history?
No. Each test’s identity includes the platform (ios, android, or ios-safari for a browser session) so a suite run on iOS and Android keeps two histories instead of overwriting one with the other, but it deliberately leaves out the device model and OS version. Those are recorded on every case instead, so you can still see which device a failure came from.
Does Qualflare run my Appium tests or provide devices?
No. Qualflare is a results-management and observability layer, not a device cloud. It never boots a simulator or connects to a device; your Appium server and devices are wherever they already are — a CI macOS runner, an emulator, a device farm — and Qualflare reads the reports the run writes.
Setup reflects @qualflare/appium 0.1.0, the Qualflare CLI
(docs.qualflare.com)
and Appium 3 with WebdriverIO 8 and 9 as of October 2026; the capability behaviour was measured on a real
XCUITest session. Published 3 October 2026. Written by
İbrahim Süren, founder of Qualflare.