Testing & Quality skills

Browse reusable Agent Skills, each with a clear purpose and practical guidance.

setting-up-host-vs-device-tests

Use this skill to choose between host (Robolectric/JVM) and device (instrumentation) tests for Jetpack Compose, and to configure each correctly. Covers the `androidHostTest` (a.k.a. `src/test/`) vs `androidDeviceTest` (a.k.a. `src/androidTest/`) source set split, what each flavor can and cannot drive (RenderThread, screenshots, accessibility), the `@RunWith(AndroidJUnit4::class) @Config(minSdk = 23)` setup for Robolectric, and why `Thread.sleep` is forbidden everywhere except screenshot tests waiting on the RenderThread. Use when the user reports "tests pass locally but fail on CI", asks "Robolectric vs instrumentation", mentions screenshot tests, ripple animations, accessibility checks throwing on Robolectric, or "should this test live in test/ or androidTest/".

296 repo starsObserved in 2 repos
Testing & Quality

structuring-a-compose-test

Use this skill to structure a Jetpack Compose UI test class the way androidx itself writes them — `@MediumTest` + `@RunWith(AndroidJUnit4::class)`, a single `createComposeRule(StandardTestDispatcher())` rule, hoisted `mutableStateOf` declared above `setContent { }`, and the Test → Find → Assert → Act → Re-assert flow. Covers when to use `createAndroidComposeRule<MyActivity>()` for custom Activities, how to drive state from outside the composition via `runOnIdle { }`, why state must NOT be hoisted inside `setContent`, and why `@get:Rule createComposeRule()` and `runComposeUiTest { }` MUST NOT both appear in the same test. Use when the developer asks "how do I write a Compose test", "where do I declare state", "how do I name the test class", "MediumTest vs LargeTest", "rule.setContent inside @Before", or shows a test class that won't compile or doesn't drive state from outside.

296 repo starsObserved in 2 repos
Testing & Quality

synchronizing-with-idle

Use this skill to choose the right idle-synchronization primitive in Compose UI tests — waitForIdle, awaitIdle, waitUntil(conditionDescription, timeoutMillis, condition), waitUntilNodeCount, waitUntilExactlyOneExists, waitUntilAtLeastOneExists, waitUntilDoesNotExist, runOnIdle, runOnUiThread, runWhenIdle, awaitAndRunWhenIdle, hasPendingWork, and IdlingResource. Explains what "idle" means (no pending recomposition or draw, every IdlingResource isIdleNow), the wall-clock vs test-clock timeout split, the Espresso/Robolectric strategy bridge, and why direct state reads from the test thread race the recomposer. If the user mentions "test is flaky", "test passes locally fails on CI", "Thread.sleep waiting for state", "Espresso IdlingResource", "ComposeTimeoutException waitUntil", "AndroidComposeUiTestTimeoutException", waitUntilExactlyOneExists, runOnIdle, runWhenIdle, or "register IdlingResource", use this skill.

296 repo starsObserved in 2 repos
Testing & Quality

testing-animations-deterministically

Use this skill to write non-flaky Compose animation tests by setting mainClock.autoAdvance = false and stepping frames by hand with advanceTimeByFrame and advanceTimeBy(durationMillis). Explains why InfiniteAnimationPolicy cancels indeterminate animations the moment the test starts unless autoAdvance is disabled, why the first frame after a state toggle does not initialize playTime, and why state mutations during the paused-clock window must go through runOnUiThread instead of runOnIdle. If the user mentions "animation never finishes", "InfiniteAnimationPolicy CancellationException", "Crossfade test flaky", "indeterminate progress indicator", "Thread.sleep(500) waiting for animation", advanceTimeByFrame, advanceTimeBy, or autoAdvance, use this skill.

296 repo starsObserved in 2 repos
Testing & Quality

testing-coroutines-with-runtest

Use this skill to test suspend functions and coroutine-using classes on the JVM with kotlinx-coroutines-test. Covers runTest, TestScope, StandardTestDispatcher vs UnconfinedTestDispatcher, virtual time via TestCoroutineScheduler (advanceTimeBy, advanceUntilIdle, runCurrent), the canonical MainDispatcherRule wrapper for Dispatchers.setMain/resetMain, the TestResult Promise contract on KMP, and the runBlockingTest -> runTest migration. If the user mentions runTest, runBlockingTest deprecated, advanceUntilIdle, advanceTimeBy, TestScope, StandardTestDispatcher, UnconfinedTestDispatcher, MainDispatcherRule, "Module with the Main dispatcher is missing", "test hangs forever", dispatchTimeoutMs, viewModelScope test, or a ViewModel that posts state from a coroutine, use this skill.

296 repo starsObserved in 2 repos
Testing & Quality

testing-flows-with-turbine

Use this skill to assert Flow emissions in tests with Cash App Turbine. Covers flow.test entry, ReceiveTurbine API (awaitItem, awaitComplete, awaitError, expectMostRecentItem, skipItems, expectNoEvents, cancel and friends, plus the non-suspending takeItem/takeComplete/takeError), turbineScope/testIn for multi-flow tests, the standalone Turbine<T> channel (add/close/asChannel/ensureAllEventsConsumed) for verifying non-Flow callbacks and listeners, the hot vs cold cancellation contract (StateFlow/SharedFlow never auto-complete), Turbine's wall-clock timeout decoupled from runTest virtual time, and the decision matrix between Turbine and raw flow.toList. If the user mentions Turbine, awaitItem, awaitComplete, expectMostRecentItem, takeItem, "test hangs on collect", "SharedFlow never completes", "StateFlow first emission", "TurbineAssertionError", "withTurbineTimeout", "Turbine() channel", "capture a callback in a test", or asserts a ViewModel's StateFlow/SharedFlow, use this skill.

296 repo starsObserved in 2 repos
Testing & Quality

testing-lazy-lists

Use this skill to test `LazyColumn`, `LazyRow`, and `LazyVerticalGrid` correctly — tag the container with `Modifier.testTag(...)`, tag each item by its key, scroll via the semantic action (`hasScrollAction()`, `performScrollToIndex`, `performScrollToKey`) or via `Modifier.testTag` plus `performTouchInput { swipeUp() }`, and verify visibility with `assertIsDisplayed` (NOT `assertExists`, since off-screen lazy items still exist as semantic nodes in some configurations). Covers `LazyListState.layoutInfo.visibleItemsInfo` as the highest-signal probe, `mainClock.autoAdvance = false` for animated item placement, and the parameterized vertical/horizontal base-class pattern. Use when the developer asks "how do I scroll a LazyColumn in a test", "assertExists vs assertIsDisplayed", "scroll to a key", "test item placement animation", or sees a test pass when an item is off-screen.

296 repo starsObserved in 2 repos
Testing & Quality

testing-with-espresso-interop

Use this skill to mix Compose finders and Espresso `onView` in the same test — for Android `Dialog` windows, IME (soft keyboard) state, `ComposeView` inside an Android View hierarchy, or focus interactions that cross the Compose/View boundary. Covers `createAndroidComposeRule<A>()` setup, the `EspressoLink` bridge that auto-registers Compose's `IdlingResource` with Espresso, the `onRootWithViewInteraction` API, and why `Espresso.onView(...)` MUST run from the test thread (not from `runOnIdle` / `runOnUiThread`). Use when the developer mentions "Espresso onView and Compose at the same time", "ComposeView inside a View", "soft keyboard test", "Dialog focus", "compose interop test", or shows a test that calls Espresso from inside `runOnIdle` and deadlocks.

296 repo starsObserved in 2 repos
Testing & Quality

traversing-the-semantics-tree

Use this skill to navigate from one Compose semantics node to its relatives via `onParent`, `onChildren`, `onChild`, `onChildAt`, `onSibling`, `onSiblings`, `onAncestors`, plus the collection helpers `onFirst`, `onLast`, `filter`, `filterToOne`, and the `[index]` operator. Covers when to traverse vs when to add a stable `testTag`, the LazyColumn/LazyRow caveat (only currently composed children appear), the absence of a singular `onAncestor`, and the sticky `useUnmergedTree` flag across navigation. Use when the developer mentions `onChildren`, `onChild`, `onParent`, `onSiblings`, `onAncestors`, `filterToOne`, `onFirst`, `onLast`, brittle child-index chains, or asks how to find the second child of a Row, the parent of a Text, or any sibling of a node. If the developer is dot-chaining navigation through a layout, use this skill.

296 repo starsObserved in 2 repos
Testing & Quality

understanding-the-testing-pyramid

Use this skill to size an Android test suite using Google's small / medium / big scope vocabulary and the qualitative pyramid. Explains why most apps should hold "many small tests and relatively few big tests", how scope (small/medium/big) is orthogonal to execution location (local vs instrumented), and where the older 70/20/10 numeric ratio actually comes from. Use when the user asks "how many unit vs UI tests should I write", "what's the testing pyramid", "all my tests are instrumented and CI is slow", "test pyramid 70 20 10", "Android small medium large tests", "Robolectric counts as which layer", or mentions Unit / Component / Feature / Application / Release Candidate framing from the strategies page.

296 repo starsObserved in 2 repos
Testing & Quality