$npx -y skills add mmiani/kotlin-kmp-claude-agent-skills --skill kotlin-testing-kmpUse when designing, implementing, or reviewing tests in KMP projects — unit tests, instrumented tests, Compose Multiplatform UI tests, test doubles, test strategy, stability, performance, and screenshot testing.
| 1 | # Kotlin Multiplatform Testing |
| 2 | |
| 3 | Use this skill when designing, implementing, or reviewing tests in a Kotlin Multiplatform project. |
| 4 | |
| 5 | This skill is intentionally strict. Its purpose is to keep the test suite fast, trustworthy, behavior-focused, and aligned with Android’s testing guidance while still respecting shared KMP boundaries and Compose Multiplatform testing patterns. |
| 6 | |
| 7 | ## Primary goals |
| 8 | |
| 9 | The testing strategy should optimize for: |
| 10 | |
| 11 | - strong confidence in business logic |
| 12 | - fast feedback from local/unit tests |
| 13 | - clear separation between local, Robolectric, instrumented, and UI tests |
| 14 | - behavior-focused tests instead of implementation-detail tests |
| 15 | - appropriate use of test doubles |
| 16 | - stable and performant larger tests |
| 17 | - isolated testing of shared KMP logic |
| 18 | - practical Compose Multiplatform UI test coverage |
| 19 | - targeted screenshot testing where visual regressions matter |
| 20 | |
| 21 | Do not optimize for raw coverage percentages alone. |
| 22 | Optimize for confidence, speed, signal quality, and maintainability. |
| 23 | |
| 24 | --- |
| 25 | |
| 26 | ## Official defaults to prefer |
| 27 | |
| 28 | Unless the project has a strong reason not to, prefer these defaults: |
| 29 | |
| 30 | - many small local/unit tests |
| 31 | - fewer integration tests |
| 32 | - fewer end-to-end/UI tests than lower-level tests |
| 33 | - tests focused on user-visible behavior and business outcomes |
| 34 | - use of test doubles to isolate dependencies |
| 35 | - `kotlin.test` for assertions and test declarations in shared KMP test source sets — this is the cross-platform test API recommended by JetBrains and works across JVM, native, and JS/Wasm targets |
| 36 | - local tests in `src/test` (JVM-side tests in Android modules) |
| 37 | - Android instrumented tests in `src/androidTest` |
| 38 | - Robolectric only when Android framework behavior is needed but device execution is not necessary |
| 39 | - common Compose Multiplatform UI tests where the behavior is truly shared |
| 40 | - stable UI tests with clear synchronization and controlled environment setup |
| 41 | - screenshot tests for important visual surfaces when appearance regressions matter |
| 42 | |
| 43 | --- |
| 44 | |
| 45 | ## Test strategy defaults |
| 46 | |
| 47 | ### 1. Testing pyramid |
| 48 | |
| 49 | Prefer a pyramid-shaped suite: |
| 50 | |
| 51 | - many unit tests |
| 52 | - fewer integration tests |
| 53 | - fewer UI/end-to-end tests |
| 54 | |
| 55 | Review expectation: |
| 56 | - lower-level tests should catch most regressions |
| 57 | - larger tests should validate integration and user workflows, not replace unit coverage |
| 58 | |
| 59 | Flag as a concern when: |
| 60 | - most confidence depends on slow UI tests |
| 61 | - business logic is only exercised through end-to-end flows |
| 62 | - the suite is top-heavy and expensive to run |
| 63 | |
| 64 | ### 2. Behavior over implementation detail |
| 65 | |
| 66 | Prefer tests that validate: |
| 67 | - observable outputs |
| 68 | - state transitions |
| 69 | - user-visible effects |
| 70 | - business rules |
| 71 | |
| 72 | Be cautious with tests that lock down: |
| 73 | - internal private structure |
| 74 | - implementation-specific sequencing that users do not observe |
| 75 | - framework internals |
| 76 | |
| 77 | Flag as a concern when: |
| 78 | - tests fail after harmless refactors |
| 79 | - mocks assert incidental calls instead of real behavior |
| 80 | - UI tests are verifying widget internals rather than actual interaction outcomes |
| 81 | |
| 82 | --- |
| 83 | |
| 84 | ## Test-scope review dimensions |
| 85 | |
| 86 | ### 3. What should be tested first |
| 87 | |
| 88 | Prioritize tests for: |
| 89 | |
| 90 | - business rules |
| 91 | - domain/use-case behavior |
| 92 | - repository coordination logic |
| 93 | - DTO/domain/UI mapping |
| 94 | - state-holder transitions |
| 95 | - failure and retry handling |
| 96 | - navigation decision logic where important |
| 97 | - shared UI behavior that is meaningful across targets |
| 98 | |
| 99 | Flag as a concern when: |
| 100 | - trivial pass-through code is heavily tested while important rules are not |
| 101 | - mapping and error paths are untested |
| 102 | - state transitions are inferred rather than verified |
| 103 | |
| 104 | ### 4. Local unit tests |
| 105 | |
| 106 | Local tests should be the default choice for fast feedback. |
| 107 | |
| 108 | For **shared KMP modules**, tests in `commonTest` (using `kotlin.test`) run on all declared targets — JVM, native, JS/Wasm — making them the correct layer for shared business logic. Do not confuse `commonTest` (shared KMP tests) with `src/test` (Android/JVM-local tests). |
| 109 | |
| 110 | Check whether: |
| 111 | - pure Kotlin/shared logic is tested in `commonTest` using `kotlin.test`, not pushed into Android-specific test layers |
| 112 | - Android-specific behavior is tested in `src/test` (local JVM) or `src/androidTest` (instrumented), not in shared test source sets |
| 113 | - test setup avoids Android device/emulator dependency when unnecessary |
| 114 | - most business logic tests live in the lowest practical test layer |
| 115 | |
| 116 | Review expectations: |
| 117 | - shared logic in KMP should be exercised in `commonTest` first, before platform-specific layers |
| 118 | - `src/test` remains the main home for fast-running JVM-side tests on Android-only modules |
| 119 | - local tests are preferred unless the behavior truly needs Android runtime support |
| 120 | |
| 121 | Flag as a concern when: |
| 122 | - shared business logic is only tested in Android-specific lay |