Modern Android Mastery: From Zero to Play Store
Lecture 6

The Final Mile: Testing and Publishing

Modern Android Mastery: From Zero to Play Store

Transcript

SPEAKER_1: So last time we got the data layer working together. Now the question is: how does someone know the app actually works before shipping it? SPEAKER_2: The answer is a layered strategy. The Android Testing Pyramid recommends many fast unit tests, fewer integration tests, and even fewer end-to-end UI tests — balancing reliability against build speed. SPEAKER_1: For Compose specifically — UI testing can't be looking for view IDs. So how does it find anything on screen? SPEAKER_2: That's the key idea. Compose testing relies on semantics properties instead of view IDs. Think of the semantics tree as a parallel description of the UI — content descriptions, test tags, roles — that testing tools query without touching rendered pixels. SPEAKER_1: So a developer adds Modifier.testTag to a composable, and the test finds it by that tag? SPEAKER_2: Exactly. Then functions like onNodeWithTag, onNodeWithText, performClick, and assertIsDisplayed let you interact with and verify composables. The whole API lives in the androidx.compose.ui.test package — quite different from Espresso, which targets traditional Views. SPEAKER_1: For everyone listening — suppose Adrià has a login screen with a button. What does a concrete test look like? SPEAKER_2: You set up the environment using createAndroidComposeRule or createComposeRule, built on the AndroidX Test library. Then call onNodeWithTag pointing at the button, performClick, and assert the next screen's node is displayed. Three lines. No emulator required for simpler cases. SPEAKER_1: That's cleaner than expected. Unit tests run on the JVM with no device — but what about tests needing Android APIs without the slowness of a real device? SPEAKER_2: Robolectric handles that. It runs tests using many Android framework APIs on the JVM without a device, giving faster feedback than full instrumented tests. Unit tests live under the test source set; instrumented tests under androidTest. Gradle tasks like testDebugUnitTest and connectedDebugAndroidTest run each set. SPEAKER_1: Now, the key idea for teams is running all of this automatically on every commit. SPEAKER_2: Right — CI systems like GitHub Actions, GitLab CI, and Bitrise execute both unit and instrumentation tests on every commit. That catches regressions before release. A bug found in CI costs far less than one found by users after launch. SPEAKER_1: Alright, app is tested. What does Google Play actually require before an app can go up? SPEAKER_2: a unique applicationId, a signing key, and a versionCode. Those identify the app and every update. Change the signing key and existing users can't receive updates — that's permanent damage. SPEAKER_1: Signing sounds risky to manage alone. Is there a safer approach? SPEAKER_2: Google Play App Signing handles it well. Developers upload with an upload key; Google securely manages the actual signing key used for distributed builds. If the upload key is lost, the app isn't permanently broken. It's the recommended approach for new apps. SPEAKER_1: APK versus App Bundle — what's the practical difference for someone publishing a new app? SPEAKER_2: The Android App Bundle, the AAB format, lets Google Play generate optimized APKs per device configuration. A user gets an APK optimized for their device configuration. That meaningfully reduces download size compared to a single universal APK. AAB is the recommended format now. SPEAKER_1: Before uploading, there's also R8. Why does that step matter beyond just shrinking size? SPEAKER_2: R8 shrinks, optimizes, and obfuscates bytecode — smaller APK, harder to reverse-engineer. The catch: reflection-based code needs keep rules so R8 doesn't strip entry points it can't statically trace. Miss that and the release build can crash in ways the debug build did not reveal. Running lint beforehand also catches missing translations and permission issues. SPEAKER_1: So lint, R8 rules verified, AAB signed — then straight to production? SPEAKER_2: Not necessarily straight to production. Google Play Console’s testing tracks — internal, closed, and open — let developers release pre-production versions to limited users or testers before a full production rollout. Then staged rollouts release to a percentage of users while monitoring crash rates and ANRs in Android Vitals. Exceeding bad behavior thresholds can hurt store visibility. For Adrià or anyone shipping an app, that staged path is the safety net between testing and full release.