Proxy Mail QA

Testing sign-up emails in an Android app (Kotlin)

Signing a real Gmail account into every emulator is slow, and one shared inbox soon fills with codes from every run. Use a fresh address per test instead, read the code or link from it, and open the link in your app with one adb command.

Updated

Why sign-up emails are awkward to test on Android

Test it by hand on the emulator

  1. Create an address in Proxy Mail QA, with a persona and a generated password if your form needs them.
  2. Sign up in the emulator with it. The emulator shares your computer’s clipboard, so copy and paste works both ways.
  3. Get the code from the address’s row with Copy, and paste it into the app.
  4. Or open the link in the app: adb shell "am start -W -a android.intent.action.VIEW -d '<link>'". For a myapp:// link the inbox shows this command next to it, ready to copy.
  5. If Chrome opens instead, check verification with adb shell pm get-app-links com.example.app and retry it with adb shell pm verify-app-links --re-verify com.example.app.

Automate it with Espresso

Add the Kotlin helper from the Espresso guide to androidTest, pass the API key as an instrumentation argument, and the test reads the code itself:

Kotlin
val qa = ProxyMailQA()
val account = qa.createAddress()

onView(withHint("Email")).perform(typeText(account.address), closeSoftKeyboard())
val submitted = Instant.now()
onView(withText("Sign up")).perform(click())

val code = qa.waitForCode(account.address, submitted)
onView(withHint("Code")).perform(typeText(code))

In a Compose test, use composeTestRule.onNodeWithText("Email").performTextInput(account.address) and so on. To open a link, start an ACTION_VIEW intent with it (the guide has the two lines). If the email has both a web link and a myapp:// one, waitForLink(…, app = true) returns the app’s.

The same helper checks the email itself (checkEmail with your App Link domain, and countEmails for duplicates), signs in as a saved test account, and adds each test to the pull request’s report: see the Espresso guide.

What to check in your Kotlin code

Using Firebase email-link sign-in? Its App Links use your Firebase Hosting domain: see Firebase email-link sign-in on mobile.

Try it on your next sign-up test

Free plan, no credit card. Create an address and watch the code or link arrive.

Create a free accountOpen the app

Questions

Why does my verification link open in Chrome instead of my app?

From Android 12, an https link opens in your app only when its App Links are verified for that domain; otherwise it opens in the browser. Run adb shell pm get-app-links with your package name to see the state. The usual causes are a missing assetlinks.json, or one listing the wrong signing certificate: the debug key for a debug build, or Google's app signing key (not your upload key) for a build from Google Play.

Why can't the emulator open a link to localhost?

On the Android emulator, localhost is the emulator itself. It reaches your computer at 10.0.2.2. Proxy Mail QA flags links to localhost and to 10.0.2.2 so you can tell a local link from a broken one: see proxymail.qa/solve/localhost-links.

Does this work with Jetpack Compose?

Yes. The helper doesn't care how the screen is built: type the address with Espresso's typeText for views, or performTextInput in a Compose test.

Can I test codes sent by text message?

No. Proxy Mail QA receives email only. Codes sent by SMS need a different tool.

See every email testing problem we solve