Chapter 16: Testing
Testing billing from scratch means setting up license tester accounts, navigating Play Console test tracks, and dealing with shortened subscription intervals that still require real Google Play sandbox flows. RevenueCat gives you a faster alternative: the Test Store.
What Is the Test Store
The Test Store is a RevenueCat-managed testing environment that runs entirely without Google Play. When your app is configured with a test_ API key, calling awaitPurchase() shows a local dialog instead of launching the Google Play purchase sheet:
- Successful Purchase, SDK returns a successful
PurchaseResultwith active entitlements - Failed Purchase, SDK throws a
PurchasesTransactionExceptionwith a payment failure error - Cancel, SDK throws with
userCancelled = true
No sandbox accounts. No test tracks. No network dependency on Google's servers. Every outcome is deterministic.
Setup
1. Enable the Test Store
In the RevenueCat dashboard → your app → Apps & providers → Create Test Store. This generates a separate API key prefixed with test_.
2. Use the Test Key in Debug Builds
3. Initialize with the Build Config Key
That is all the setup required. The same awaitPurchase() call you write for production will show the Test Store dialog in debug builds.
Testing Each Purchase Outcome
The Test Store dialog lets you select any outcome before your code runs: successful purchase, cancellation, or specific error codes like BILLING_UNAVAILABLE and ITEM_ALREADY_OWNED. This means you can exercise every branch of your error handling code without needing to trigger real billing failures.
Unit Testing
For unit tests, wrap Purchases behind an interface so you can mock it without the SDK. The Purchases singleton is not directly mockable, and unit tests should not depend on a real SDK instance or network. Introducing a thin BillingService interface between your ViewModels and the SDK lets you inject a fake in tests and verify your business logic independently of RevenueCat's internals.
Your ViewModel takes a BillingService. In tests, inject a mock:
CI/CD
The Test Store works without a device or Google Play account, which makes it suitable for automated test runs in CI. Because the Test Store API key is distinct from your production key, you can safely expose it to your CI environment without risking live purchases. Store it as a repository secret and inject it at build time via a BuildConfigField. Your unit tests then run against the mock billing layer, while instrumented tests can drive the Test Store dialog programmatically.
When to Use Google Play Sandbox Instead
The Test Store covers most development and CI testing. Use the Google Play Sandbox when you specifically need to test:
Debug Dashboard
After any purchase (Test Store or Sandbox), inspect the result in the RevenueCat dashboard under Customers → [user ID]: full purchase history, active entitlements, and raw CustomerInfo JSON. The Events tab shows every webhook sent. This is the fastest way to confirm a test purchase was recorded correctly.
Pre-Ship Checklist
Purchases.logLevel = LogLevel.DEBUGremoved or gated onBuildConfig.DEBUG- Release build type uses production
goog_API key, nottest_key test_key is not committed to version control (use env variable or local properties)- Happy path, error path, and cancellation tested via Test Store dialog
- At least one end-to-end flow verified via Google Play Sandbox
- Webhook endpoint receives events for sandbox purchases