testing-animations-deterministically

Pause Jetpack Compose MainTestClock and step frames for deterministic animation UI tests.

303|10|Updated May 15, 2026
One-click install
npx skills add https://github.com/skydoves/android-testing-skills --skill testing-animations-deterministically
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: testing-animations-deterministically
Source: https://github.com/skydoves/android-testing-skills/tree/main/compose/synchronization/testing-animations-deterministically
Command: npx skills add https://github.com/skydoves/android-testing-skills --skill testing-animations-deterministically

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve?

This Skill solves flaky Jetpack Compose UI tests caused by indeterminate or time-based animations running differently on CI versus locally.

Core Features & Use Cases

  • Make animation timing deterministic by disabling mainClock.autoAdvance and driving frames manually.
  • Handle infinite/indeterminate animations safely so InfiniteAnimationPolicy does not fail your test with CancellationException.
  • Avoid mid-animation test hangs and race conditions by mutating Compose state with runOnUiThread (not runOnIdle) while the clock is paused.
  • Use test-clock waiting correctly with mainClock.advanceTimeUntil { ... } for state-observable conditions inside the paused-clock window.

Quick Start

Set up your Compose UI test by setting mainClock.autoAdvance = false before setContent, then call advanceTimeByFrame() once to kick off the animation and step it with advanceTimeBy(durationMillis) before asserting the intermediate UI state.

Frequently Asked Questions about testing-animations-deterministically

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I fix flaky Jetpack Compose animation UI tests in CI?

Fix flaky Jetpack Compose animation UI tests by pausing the MainTestClock with mainClock.autoAdvance = false before setContent, then manually stepping frames with advanceTimeByFrame(). This makes animation timing deterministic across CI and local environments.

Why does my Compose test throw a CancellationException for indeterminate progress indicators?

Compose tests throw CancellationException when infinite animations trigger the InfiniteAnimationPolicy. Prevent this by disabling mainClock.autoAdvance and manually stepping the animation frames to keep indeterminate progress indicators safely controlled.

How to test intermediate animation frames in Jetpack Compose?

Test intermediate animation frames by setting mainClock.autoAdvance = false before setContent, calling advanceTimeByFrame() to start, and using advanceTimeBy(durationMillis) to step the animation before asserting the intermediate UI state.

Should I use runOnIdle or runOnUiThread to mutate Compose state while the test clock is paused?

Use runOnUiThread to mutate Compose state while the test clock is paused. runOnUiThread avoids mid-animation race conditions and test hangs that occur when attempting state mutations on idle during paused-clock Compose animation testing.

What's the best way to wait for Compose-observable conditions during a paused animation test?

Use mainClock.advanceTimeUntil { ... } to wait for Compose-observable conditions during paused animation tests. Prefer advanceTimeUntil over wall-clock waitUntil to properly evaluate state conditions inside the paused-clock window.