UI Testing with Jetpack Compose + Coroutines
UI Testing with Jetpack Compose + Coroutines (Complete Guide)
Testing Jetpack Compose UI that uses coroutines, StateFlow, and ViewModel is a must for modern Android apps.
This guide covers setup → ViewModel → Compose → coroutine-aware UI tests in a clean and practical way.
1. What We Are Testing
In Compose UI tests, we usually test:
UI reacts to StateFlow updates
Buttons trigger ViewModel coroutine calls
Loading / success / error states
One-time events (Snackbars, navigation)
👉 We do NOT test coroutines directly here — we test UI behavior caused by coroutines.
2. Required Dependencies
3. Sample ViewModel (StateFlow + Coroutine)
4. Compose UI Using ViewModel
5. Basic Compose UI Test Setup
6. Testing UI State Change (Coroutine Driven)
✔ Button click triggers coroutine
✔ UI updates from StateFlow
✔ Test waits safely (no Thread.sleep)
7. Using TestDispatcher with Compose (IMPORTANT)
Replace Main Dispatcher
(Use the same MainDispatcherRule from ViewModel testing)
This ensures:
viewModelScoperuns on test dispatcherDelays are controllable
8. Testing Loading → Success Flow
9. Testing One-Time Events (Snackbar)
ViewModel
Compose
UI Test
10. Testing Navigation Triggered by Coroutines
✔ Use fake NavController
✔ Assert navigation route
✔ No real Activity required
(Advanced topic — can cover next if you want)
11. Common Mistakes (Avoid These)
❌ Using Thread.sleep()
❌ Testing real network calls
❌ Testing ViewModel logic again
❌ Not using test tags
❌ Not replacing Main dispatcher
12. Best Practices (Must Follow)
✔ UI tests test what user sees
✔ ViewModel tests test logic
✔ Use StateFlow / SharedFlow
✔ Add testTag for stable selectors
✔ Let Compose handle recomposition
Final Summary
Compose UI tests work perfectly with coroutines
Test state-driven UI, not coroutine internals
Use StateFlow + collectAsState
Avoid sleeps, use
waitUntilKeep UI tests fast & deterministic
