Best Tools for In-App Purchases Testing (2026 Comparison)
Best Tools for In-App Purchases Testing (2026 Comparison)
Best Tools for In-App Purchases Testing (2026 Comparison)
In‑app purchase (IAP) testing remains one of the most fragile parts of mobile quality assurance because it touches payment gateways, store‑specific receipt validation, promotional offers, and regional price‑tier logic—all while requiring the app to stay in a purchasable state without actually charging real money. The following guide walks you through a practical comparison of the tools that teams actually use in 2026, shows how to set them up, highlights common pitfalls, and gives a decision matrix you can bookmark for your next sprint planning.
---
1. Why In‑App Purchase Testing Is Unique
Unlike UI or network tests, IAP tests must simulate a financial transaction that never actually moves money. Both Apple’s App Store and Google Play provide sandbox environments, but those sandboxes behave differently from production in subtle ways: receipt signatures expire after a set time, promotional codes are only valid for a limited number of redemptions, and certain error codes (like SKErrorPaymentNotAllowed or BillingResultCode.SERVICE_DISCONNECTED) appear only when a device is logged out of its store account. Moreover, many apps implement custom promotional logic, receipt‑server verification, or subscription renewal handling that lives outside the store SDKs.
Because of these nuances, a test that merely clicks a “Buy” button and asserts a success toast can miss:
- Race conditions between the purchase flow and the app’s local entitlement cache.
- Failure to refresh a receipt after a subscription renewal attempt.
- Mis‑handling of downgrade/upgrade proration periods.
- Incomplete cleanup of pending transactions leading to “phantom purchase” states.
- Accessibility gaps when a purchase dialog appears over a custom overlay.
Effective IAP testing therefore needs a blend of store‑sandbox manipulation, device‑state control, and observable‑outcome verification (entitlement grants, server callbacks, analytics events). The tools we review differ in how much of that blend they provide out of the box versus how much you must script yourself.
---
2. Testing Approaches for IAP in 2026
2.1 Manual Exploratory Testing
Manual testing still holds value for edge‑case discovery, especially when you need to emulate a real user’s hesitation, rapid tapping, or interrupted network. Testers typically:
- Log into a sandbox account (Apple Sandbox or Google Test Account).
- Navigate to the purchase UI.
- Attempt a purchase, then immediately cancel, change network, or background the app.
- Verify receipt handling, entitlement grant, and any fallback paths.
The biggest downside is repeatability: each run depends on the tester’s memory and the sandbox state (e.g., whether a subscription is already active). Teams mitigate this by scripting sandbox reset steps (see §2.3) but the core verification remains human‑driven.
2.2 Scripted Automation with Store SDKs
Most teams write automated tests that call the store SDK directly, either by:
- Using the Google Play Billing Library (version 6+) to launch purchase flows via
BillingClient.launchPriceChangeConfirmationFloworlaunchBillingFlow. - Using Apple’s StoreKit Testing in Xcode (available since Xcode 13) to provide a local
StoreKitConfigurationfile that simulates product purchases, renewals, and failures without contacting Apple’s servers.
These approaches give you full control over product IDs, pricing tiers, and simulated error responses. However, they require you to:
- Maintain a test‑only build that points to a sandbox or test configuration.
- Write boilerplate to start/end purchases, consume consumables, and handle transaction observers.
- Mock your backend’s receipt‑validation endpoint unless you rely on the SDK’s built‑in validation (which many teams avoid for security reasons).
2.3 Autonomous, No‑Script Exploration
A newer class of tools treats the app as a black box and uses AI‑driven agents to explore purchase flows autonomously. These agents:
- Launch the app on a real device or emulator.
- Identify UI elements that look like purchase buttons (via OCR, accessibility labels, or visual templates).
- Attempt to interact with them while automatically handling store dialogs, promotional sheets, and error alerts.
- Record the resulting state changes (e.g., new entitlement flags, analytics events) and compare them against a baseline.
Because they do not require you to write purchase‑specific code, autonomous tools can surface regressions introduced by UI refactors or localization changes that break button labels. Their main limitation is that they cannot directly inject custom sandbox responses (e.g., a specific SKErrorCode.paymentInvalid) unless the tool integrates with the store’s testing framework.
2.4 Hybrid Approaches
Many teams combine scripted and autonomous methods: they use a script to reset the sandbox state (e.g., consume all subscriptions, log out of the store account) and then let an autonomous explorer verify that the purchase UI still works under those conditions. This hybrid model gives you repeatable setup while preserving the ability to catch UI‑level regressions.
---
3. Evaluation Criteria for Choosing an IAP Testing Tool
When you compare tools, consider the following dimensions. Each dimension is scored on a scale of 1 (poor) to 5 (excellent) based on typical enterprise needs in 2026.
| Criterion | What to Measure | Why It Matters |
|---|---|---|
| Platform coverage | Android, iOS, cross‑platform (Flutter, React Native, Unity) | Determines whether you need separate tools per stack. |
| Scripting required | Amount of custom code to drive purchases (none, low, medium, high) | Impacts onboarding time and maintenance burden. |
| Sandbox/state control | Ability to reset consumables, subscriptions, account status | Guarantees test isolation and reduces flakiness. |
| Observability | Capture of receipts, entitlement changes, analytics, network logs | Enables assertion beyond UI toast. |
| CI/CD integration | CLI, Docker images, GitHub Actions, GitLab CI plugins | Critical for gating releases. |
| Reporting & debugging | Screenshots, video, step‑by‑step logs, easy replay | Shortens triage when a test fails. |
| Cost | License fees, device minutes, open‑source vs commercial | Aligns with budget constraints. |
| Learning curve | Documentation quality, sample projects, community support | Affects ramp‑up speed for new hires. |
| Extensibility | Hooks for custom validation, ability to plug in mock servers | Needed for complex promo‑code or server‑driven flows. |
You can weight these criteria according to your team’s maturity. For example, a team with a strong test‑automation culture may prioritize low scripting and CI integration, while a startup exploring a new monetization model might value extensibility and sandbox control more highly.
---
4. Tool Comparison Table (2026)
The table below summarizes eight tools that are frequently evaluated for IAP testing in 2026. Scores are based on the criteria above, using publicly available documentation, community forums, and hands‑on trials performed by the SUSATest engineering team in Q1‑2026.
| Tool | Platforms | Scripting Required | Sandbox/State Control | Observability | CI/CD Integration | Reporting | Cost (USD/yr) | Learning Curve |
|---|---|---|---|---|---|---|---|---|
| Google Play Billing Testing Library | Android | Medium (Kotlin/Java) | Full (via BillingClient test modes) | Receipts, consumption callbacks | Gradle tasks, AndroidJUnitRunner | Logcat, Android Studio Profiler | Free (open source) | Moderate |
| Apple StoreKit Testing (Xcode) | iOS | Low (Swift) | Full (local .storekit config) | Receipts, transaction observers | xcodebuild test, fastlane | Console, XCTest attachments | Free (included with Xcode) | Low |
| Firebase Test Lab + IAP Scripts | Android, iOS | High (custom test scripts) | Limited (requires manual account reset) | Device logs, video, performance metrics | Firebase CLI, GitHub Actions | Detailed test matrix, flakiness detection | $150 per device hour | High |
| HeadSpin Platform | Android, iOS, Web | Low‑Medium (API‑driven) | Medium (session control via APIs) | Network, video, sensor logs, custom KPI | REST API, CircleCI orb | Session replay, AI‑driven insights | $12,000 (base) + usage | Moderate |
| SUSA Autonomous Agent | Android, iOS, Web | None (no‑script) | High (auto‑reset sandbox accounts) | Entitlement events, analytics, video, screenshots | CLI (susatest-agent run), GitHub Action | PASS/FAIL flow reports, heat‑maps | $8,000 (team tier) | Very Low |
| TestFairy | Android, iOS | Low (SDK instrumentation) | Low (depends on tester) | Video, touch heatmaps, logs, crash reports | API, fastlane plugin | Session viewer, drill‑down | $5,000 (annual) | Low |
| Kobiton Device Cloud | Android, iOS | Medium (Appium/Espresso) | Medium (device state restore) | Device logs, video, performance | Kobiton CLI, Jenkins plugin | Detailed test reports | $10,000 (concurrent 5 devices) | Moderate |
| Sauce Labs Real Device Cloud | Android, iOS | Medium (Appium, XCTest) | Medium (session reset) | Video, logs, performance metrics | Sauce CLI, GitHub Actions | Test Insights, video | $15,000 (concurrent 10) | Moderate |
Notes on the table
- “Scripting Required” reflects the typical effort to write a test that actually triggers a purchase flow and validates the outcome. Tools like SUSA require zero purchase‑specific code because the agent discovers and interacts with purchase UI autonomously.
- “Sandbox/State Control” is highest for the native store testing libraries because they let you define exact product responses and reset consumable states programmatically. Autonomous tools like SUSA achieve high scores by automatically logging out of sandbox accounts and clearing purchase headers between runs.
- “Observability” includes any mechanism that lets you verify that a purchase resulted in the expected entitlement or analytics event, not just a UI success toast.
- Cost figures are approximate annual subscriptions for a mid‑size team (≈10 engineers) based on public pricing as of Q2‑2026; enterprise discounts may apply.
---
5. Deep Dive: Tool Profiles
Below we examine each tool in more detail, focusing on realistic setup steps, sample code or configuration, and the kinds of IAP bugs each is best at catching.
5.1 Google Play Billing Testing Library (Android)
What it is – The official library from Google that lets you drive purchase flows in unit tests or instrumented tests by using the BillingClient in test mode.
Setup
- Add the test dependency in
build.gradle: - In your test class, initialize the client with
setEnablePendingPurchases(true)and uselaunchBillingFlowwith a testSkuDetailsobject returned byquerySkuDetailsAsyncin the test mode.
dependencies {
testImplementation "com.android.billingclient:billing:6.2.1"
androidTestImplementation "com.android.billingclient:billing:6.2.1"
}
Sample test (Kotlin)
@RunWith(AndroidJUnit4::class)
class PurchaseFlowTest {
private lateinit var billingClient: BillingClient
@Before
fun setUp() {
billingClient = BillingClient.newBuilder(ApplicationProvider.getApplicationContext())
.setListener { billingResult, _ ->
// handle result
}
.enablePendingPurchases()
.build()
assertTrue(billingClient.startConnection().isSuccess)
}
@Test
fun `consume non‑renewable purchase`() {
val params = BillingFlowParams.newBuilder()
.setSkuDetails(SkuDetails.newBuilder()
.setSKU("test_non_consumable")
.setType(BillingClient.SkuType.INAPP)
.setPrice("0.99")
.setPriceCurrencyMicros(("USD"))
.build())
.build()
billingClient.launchBillingFlow(activity, params)
// Observe purchaseUpdatedListener, then consume
// Assert entitlement granted in SharedPreferences or DB
}
@After
fun tearDown() {
billingClient.endConnection()
}
}
Strengths
- Exact control over product IDs, prices, and simulated error responses (e.g.,
BillingResultCode.SERVICE_DISCONNECTED). - No need for a physical device; runs on Android Emulator with the Play Store APK installed from the internal test track.
- Integrates directly with unit‑test frameworks, making it fast for CI.
Pitfalls
- Requires a separate build variant that points to the internal test track; forgetting to switch back to production can cause accidental real charges if the APK is mis‑distributed.
- Does not automatically handle promotional offer sheets; you must manually dismiss them in the test.
- Consumable purchases must be explicitly consumed; forgetting this step leaves the item in a “owned” state and causes flaky retries.
Best for – Teams that need deterministic, fast unit‑style verification of purchase logic and already maintain Android instrumented test suites.
---
5.2 Apple StoreKit Testing (Xcode)
What it is – A built‑in testing framework introduced in Xcode 13 that lets you provide a local .storekit configuration file to simulate StoreKit interactions without contacting Apple’s servers.
Setup
- Create a
StoreKitConfigurationfile in Xcode (File → New → StoreKit Configuration File). - Define products, subscription groups, introductory offers, and promotional codes.
- In your scheme, enable “StoreKit Configuration” and select the file.
- Use
SKPaymentQueueandSKProductsRequestas usual; the responses come from the local file.
Sample Swift test (XCTest)
final class IAPTests: XCTestCase {
var paymentQueue: SKPaymentQueue!
override func setUp() {
super.setUp()
paymentQueue = SKPaymentQueue.default()
paymentQueue.add(self)
}
override func tearDown() {
paymentQueue.remove(self)
super.tearDown()
}
func testConsumablePurchaseSuccess() {
let expectation = expectation(description: "Purchase completed")
let productID = "com.example.app.gem_pack"
// Initiate purchase
SKPaymentQueue.default().add(SKPayment(product: SKProduct(productIdentifier: productID)))
// Wait for transaction update
wait(for: [expectation], timeout: 5)
}
// MARK: - SKPaymentTransactionObserver
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
switch transaction.transactionState {
case .purchased:
// grant entitlement
SKPaymentQueue.default().finishTransaction(transaction)
expectation.fulfill()
case .failed:
XCTFail("Purchase failed: \(String(describing: transaction.error))")
SKPaymentQueue.default().finishTransaction(transaction)
default:
break
}
}
}
}
Strengths
- Zero network traffic; tests run in sub‑second times.
- Full support for subscription cycles, introductory offers, family sharing, and promotional codes via the configuration file.
- Seamless integration with XCTest, XCUITest, and SwiftUI previews.
Pitfalls
- The
.storekitfile does not emulate certain server‑side validation responses (e.g., receipt‑validation service downtime). You still need to mock your own receipt‑validation endpoint if you rely on it. - Promotional offer sheets that appear outside the standard purchase flow (e.g., from a push notification) are not automatically presented; you must trigger them manually.
- Running on real devices requires a development provisioning profile that includes the
com.apple.developer.in-app-paymentsentitlement; mis‑configuration leads to “invalid entitlement” errors.
Best for – iOS teams that want fast, deterministic tests for purchase logic and are already using XCTest/XCUITest for UI verification.
---
5.3 Firebase Test Lab + Custom IAP Scripts
What it is – Google’s cloud‑based device farm that lets you run Android Espresso, UIAutomator, XCTest, or XCUITest scripts on a wide range of real devices. You bring your own test scripts; Firebase merely provides the hardware and orchestration.
Setup
- Upload your APK (or IPA via the experimental iOS support) to Firebase Test Lab.
- Write an instrumented test that:
- Logs into a sandbox Google account using
AccountManager. - Calls the Play Billing Library (or uses a web‑view flow for iOS) to initiate a purchase.
- Waits for a receipt or entitlement change, then asserts.
- Use the
gcloudCLI or Firebase console to start a test matrix (e.g.,gcloud firebase test android run --type instrumentation --app app-debug.apk --test tests-apk.apk --device model=Pixel4,version=33).
Sample Espresso snippet (Kotlin)
@RunWith(AndroidJUnit4::class)
class PurchaseEspressoTest {
@get:Rule
val activityRule = ActivityTestRule(MainActivity::class.java)
@Test
fun purchaseFlow() {
// Assume a helper that logs into a test Google account
TestAccountHelper.loginSandboxAccount()
onView(withId(R.id.btn_buy_gems)).perform(click())
// Handle the Play Store purchase dialog (requires UiAutomator)
val purchaseDialog = UiObject(UiSelector().textContains("Buy"))
purchaseDialog.waitForExists(5000)
purchaseDialog.click()
// Confirm purchase
onView(withId(R.id.btn_confirm)).perform(click())
// Wait for entitlement update (e.g., a TextView showing gem count)
onView(withId(R.id.tv_gem_count)).check(matches(withText("100")))
}
}
Strengths
- Access to dozens of device models and OS versions without maintaining a physical lab.
- Parallel execution reduces feedback cycle; you can run the same IAP test on Android 12, 13, 14 simultaneously.
- Detailed logs, video, and performance metrics are automatically collected.
Pitfalls
- You must manage sandbox account state yourself; Firebase does not automatically reset Google Play accounts between runs, leading to “already owned” errors if a consumable is not consumed.
- Test execution time per device can be 2‑5 minutes for a full purchase flow, making large matrices costly.
- iOS support is still labeled experimental; you cannot yet run StoreKit tests reliably on Firebase Test Lab (as of 2026 Q2).
Best for – Teams that already have Espresso/XCUITest scripts and need broad device coverage for regression testing, especially when targeting OEM‑specific behaviors (e.g., Samsung’s ultra‑power‑saving mode affecting background billing callbacks).
---
5.4 HeadSpin Platform
What it is – A device‑cloud offering that emphasizes performance‑centric testing, AI‑driven issue detection, and programmable session control via REST APIs.
Setup
- Provision a HeadSpin device session via the CLI or UI.
- Install your app (APK/IPA) onto the device.
- Use the HeadSpin API to:
- Start a session.
- Execute custom actions (e.g., via Appium scripts) to trigger purchase flows.
- Capture video, network packets, CPU usage, and custom KPIs (like “time to receipt validation”).
- End the session and retrieve results through the HeadSpin web dashboard or JSON export.
Sample Python snippet using HeadSpin + Appium
from headspin import HeadSpin
from appium import webdriver
hs = HeadSpin(api_key="YOUR_KEY")
session = hs.create_session(device_id="Pixel5_Android13", app_path="app.apk")
driver = webdriver.Remote(
command_executor=f"https://api.headspin.io/v0/sessions/{session.id}/appium",
desired_capabilities={
"platformName": "Android",
"automationName": "UiAutomator2",
"appPackage": "com.example.app",
"appActivity": ".MainActivity",
}
)
# Navigate to purchase screen
driver.find_element_by_id("buy_gems").click()
# Handle Play Store dialog via native dialog handling
driver.find_element_by_android_uiautomator(
'new UiSelector().textContains("Buy")'
).click()
driver.find_element_by_id("confirm_purchase").click()
# Wait for entitlement update (polling)
WebDriverWait(driver, 15).until(
EC.text_to_be_present_in_element((By.ID, "gem_count"), "100")
)
driver.quit()
hs.end_session(session.id)
Strengths
- Rich telemetry (RF signal, battery, temperature) lets you correlate purchase failures with device state (e.g., low battery causing the billing service to crash).
- AI‑driven anomaly detection can flag unusual latency spikes in receipt validation that might be missed by simple assertions.
- Easy to integrate into existing Appium or Selenium pipelines.
Pitfalls
- The platform is priced per device minute; running long‑running purchase flows (especially subscriptions with renewal simulations) can become expensive.
- While HeadSpin provides powerful session control, it does not supply out‑of‑the‑box sandbox reset; you must implement your own account‑logout logic.
- The learning curve includes mastering both the HeadSpin API and your chosen automation framework (Appium, Espresso, etc.).
Best for – Performance‑focused teams that want to see how purchase flows behave under varying network conditions, battery levels, or thermal throttling, and who already invest in Appium‑based automation.
---
5.5 SUSA Autonomous Agent
What it is – An autonomous QA platform that explores an app without pre‑written scripts, using a combination of computer vision, accessibility heuristics, and learned behavior models to exercise real user flows, including in‑app purchases.
Setup
- Install the agent:
pip install susatest-agent. - Point it at your build:
- For Android:
susatest-agent run --apk path/to/app.apk --mode iap. - For iOS: provide an
.ipaor a simulator build via--simulator. - For web: give a URL (
--url https://shop.example.com).
- The agent will:
- Launch the app on a device/emulator/simulator (managed internally or via your own device farm).
- Detect purchase‑related UI elements using OCR on buttons, accessibility labels, and visual templates (e.g., a cart icon with a price tag).
- Attempt to interact with those elements while automatically handling store dialogs (Google Play purchase sheet, Apple StoreKit prompt, or web‑based payment gateway modals).
- Reset sandbox state between iterations by logging out of test accounts and clearing purchase headers (the agent maintains a pool of disposable sandbox credentials).
- Record entitlement changes, analytics events, network responses, and capture video/screenshots.
- Retrieve results via the CLI (
susatest-agent fetch --run-id) or the web dashboard.
Sample CLI command
susatest-agent run \
--apk build/app/outputs/flutter-apk/app-release.apk \
--mode iap \
--device-pool pixel4,pixel5 \
--sandbox-refresh true \
--output-format json \
--output-dir ./susatest-results
What the agent does under the hood for IAP
| Step | Action | Reason |
|---|---|---|
| UI Discovery | Uses accessibility tree + OCR to find elements with keywords like “Buy”, “Purchase”, “Subscribe”, price patterns (\$\d+\.\d{2}) | Covers cases where labels are localized or dynamically generated. |
| Interaction | Sends a tap gesture; if a modal appears, the agent switches context to the modal (detected via new window or overlay). | Handles both native store sheets and custom web‑view payment forms. |
| Store Dialog Handling | For Android, monitors com.android.vending package for purchase success/failure intents; for iOS, observes SKPaymentTransactionObserver callbacks via a lightweight instrumentation shim injected at runtime. | Guarantees the agent knows when a transaction finishes without guessing based on UI text alone. |
| Sandbox Reset | After each purchase attempt, the agent issues adb shell am force-stop com.android.vending (Android) or signs out of the sandbox Apple ID via ASAuthorizationAppleIDProvider (iOS) and clears any persisted receipt files. | Prevents “already owned” false negatives. |
| Observation | Polls the app’s shared preferences, UserDefaults, or a exposed debug endpoint for entitlement flags; also captures any analytics.track("purchase_complete") calls. | Allows validation beyond UI toast. |
| Reporting | Emits a PASS if entitlement matches expectation; FAIL if no entitlement change, error dialog appears, or crash/ANR occurs. Includes heat‑map of taps, video, and network waterfall. | Gives actionable evidence for triage. |
Strengths
- Zero‑script – You do not need to write purchase‑specific code; the agent discovers and exercises flows autonomously.
- Cross‑platform consistency – Same command works for Android, iOS, and web, making it ideal for teams with a unified codebase (Flutter, React Native, Unity).
- Continuous learning – The agent remembers which screens lead to dead ends (e.g., a promotional offer that never dismisses) and avoids repeating useless actions in subsequent runs, improving efficiency over time.
- Broad fault detection – Besides purchase logic, it catches accessibility violations (e.g., low‑contrast purchase buttons), dead buttons, and UX friction (e.g., overly long promotional screens) in the same pass.
- Easy CI integration – The CLI returns a non‑zero exit code on any FAIL, and the JSON output can be parsed by gatekeeping scripts.
Pitfalls
- Because the agent relies on heuristics to locate purchase UI, extremely custom or canvas‑drawn purchase buttons (e.g., in a game rendered entirely with OpenGL) may be missed unless you provide a visual template via the
--templateflag. - The agent’s sandbox reset mechanism assumes the availability of disposable test accounts; if your organization restricts the creation of new sandbox IDs, you must supply your own account pool via
--sandbox-accounts-file. - While the agent can detect that a purchase flow failed, it does not automatically validate the correctness of the server‑side receipt signature unless you expose a verification endpoint or enable the agent’s built‑in mock verification mode (which checks for a 200 OK with a valid JWT‑like receipt). For full end‑to‑end validation you may still need a backend mock.
Best for – Teams that want fast feedback on purchase UI health without maintaining test scripts, especially during early feature development or frequent UI redesigns. It also serves as a safety net for regression detection when combined with scripted unit tests for the core billing logic.
---
5.6 TestFairy
What it is – A mobile‑app testing platform that focuses on video capture, touch heatmaps, and detailed device logs. It does not drive purchases itself but provides rich observability when you run your own test scripts (Espresso, XCUITest, or manual exploratory sessions).
Setup
- Add the TestFairy SDK to your app (Gradle/Maven or CocoaPods).
- Initialize it in your
ApplicationorAppDelegatewith your API key. - Distribute the build via TestFairy’s portal or upload to your internal distribution channel.
- Testers (or automated scripts) interact with the app; TestFairy records:
- Video of the entire session.
- Touch heatmaps showing where users tapped.
- Console logs, network requests, and crash stack traces.
- Custom metrics you log via the TestFairy API.
Sample iOS SDK initialization (Swift)
import TestFairy
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
TestFairy.begin("YOUR_APP_TOKEN")
return true
}
}
Strengths
- Exceptional for UX‑focused debugging: you can see exactly where a user hesitated before tapping a purchase button.
- Network logging lets you verify that the correct receipt validation endpoint was called and inspect the payload.
- Easy to share with stakeholders; the video and heatmap are intuitive for product managers.
Pitfalls
- Does not provide any mechanism to drive the purchase flow; you still need to write or orchestrate the test.
- The SDK adds ~1.5 MB to the binary and may affect app startup time slightly.
- Data retention policies vary by plan; ensure you comply with any data‑privacy regulations if you record user‑identifiable information.
Best for – Teams that already have automated or manual test scripts and want deep insight into the user experience surrounding purchases, especially when investigating low conversion rates or confusing flows.
---
5.7 Kobiton Device Cloud
What it is – A real‑device cloud that supports both manual and automated testing via Appium, Espresso, XCUITest, and its own scriptless recorder.
Setup
- Create a Kobiton account and generate an API key.
- Upload your APK/IPA or point to a build in your CI artifact repository.
- Choose a device (e.g., “Samsung Galaxy S23, Android 14”) and start a session.
- For automated tests, configure your Appium client to connect to Kobiton’s WebSocket endpoint:
ws://devices.kobiton.com:80/wd/hub
with capabilities that include kobitonDeviceName, kobitonDeviceGroup, and your API key.
- Run your test scripts (e.g., an Espresso test that invokes the Play Billing Library) against the remote device.
- After the run, retrieve video, device logs, performance metrics, and any test results from the Kobiton portal.
Sample Appium JavaScript capabilities
const wd = require('appium-built-driver');
const caps = {
platformName: 'Android',
automationName: 'UiAutomator2',
app: 'storage:filename=app-debug.apk', // uploaded to Kobiton
kobitonDeviceName: 'Galaxy S23',
kobitonDeviceGroup: 'KOBITON',
kobitonApiKey: 'YOUR_KEY',
newCommandTimeout: 300
};
const driver = wd.promiseChainRemote('ws://devices.kobiton.com:80/wd/hub', caps);
// Example test flow
driver
.init()
.sleep(2000)
.elementById('buy_gems')
.click()
.sleep(3000) // wait for Play Store dialog
.elementByAndroidUiAutomator('new UiSelector().textContains("Buy")')
.click()
.elementById('confirm_purchase')
.click()
.sleep(5000)
.elementById('gem_count')
.text()
.then(text => {
assert.equal(text, '100');
})
.fin(() => driver.quit())
.done();
Strengths
- Large inventory of real devices, including many regional variants that affect pricing and tax calculations in IAP.
- Scriptless recorder enables QA analysts to create a purchase flow without code, then export it as Appium for further refinement.
- Built‑in device health monitoring (CPU, temperature, battery, network) helps correlate purchase failures with device stress.
Pitfalls
- The free tier offers limited concurrent sessions; heavy CI usage can exhaust minutes quickly.
- While the recorder is handy, it often generates overly specific selectors (e.g., exact coordinates) that break on UI changes or localization.
- Network throttling features are less sophisticated than those offered by HeadSpin or dedicated network‑emulation tools.
Best for – Organizations that need a blend of manual exploratory testing (for UX) and automated regression testing (for purchase logic) on a diverse set of real devices without maintaining an in‑house device lab.
---
5.8 Sauce Labs Real Device Cloud
What it is – A cloud service offering both emulators/simulators and real devices for automated testing via Appium, Espresso, XCUITest
Test Your App Autonomously
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.
Try SUSA Free