android-testing
Android Testing
Android-specific testing on a test-first foundation. This reference focuses on the test-first discipline plus the Compose-test and KMP traps that are easy to get wrong, not the basics of the three tiers, fakes over mocks, runTest, or Given-When-Then naming — except where a name breaks one target's compile.
Test-first (the foundation)
- No production code without a failing test first. Write the test, watch it fail (RED), write the minimal code to pass (GREEN), then refactor. A behaviour you never watched fail isn't proven.
- A bug isn't fixed until a test that was red because of the bug is green.
This layers on top of any dedicated TDD discipline skill (superpowers:test-driven-development, ace:test-driven-development) but requires none. For bootstrapping the test stack from scratch (test DI, JUnit/Robolectric/Roborazzi/Paparazzi selection, the instrumented runner, Compose Preview Screenshot Testing, UI Automator, Jacoco), see Google's official testing-setup skill (android skills add testing-setup).
commonTest names must survive Kotlin/Native, not just the JVM
commonTest is compiled once per declared target, so a green jvmTest proves nothing about the iOS compile. Backticks themselves are fine on every target — they are escaping syntax, not part of the name — but Kotlin/Native's frontend rejects 24 characters inside them: . ; , ( ) [ ] { } / < > : \ $ & ~ * ? # | § % @ (FirNativeIdentifierChecker — an unconditional error since Kotlin 1.7; the set also reserves the IR mangler's own characters). Kotlin/JVM forbids only . ; [ ] / < > : \. The comma is the gap between the two lists; a space is in neither, so a Given-When-Then convention with commas fails every native target while CI stays green:
// commonTest — compiles for jvm; fails compileTestKotlinIosSimulatorArm64 with
// error: name contains illegal characters: ","
@Test fun `given an empty cart, when an item is added, then the total updates`() { … }