android-testing
Testing patterns for Android/KMP - ViewModel unit tests with JUnit5, Turbine, AssertK, UnconfinedTestDispatcher, fake repositories, SavedStateHandle, and…
Skill by kvithayathil
Chalk Labs
Need help deploying android-testing?
Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/kvithayathil-android-testing
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: design, testing, writing
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/android-testing
What's inside
- Skill name
android-testing- Description
- Testing patterns for Android/KMP - ViewModel unit tests with JUnit5, Turbine, AssertK, UnconfinedTestDispatcher, fake repositories, SavedStateHandle, and Compose UI tests. Use this skill whenever writing or reviewing tests for ViewModels, repositories, use cases, or Compose screens. Trigger on phrases like "write a test", "unit test the ViewModel", "test a repository", "Turbine", "fake repository", "UnconfinedTestDispatcher", "runTest", "ComposeTestRule", or "JUnit5".
- License
- AGPL-3.0
- Instructions
- 228 lines in SKILL.md · view on GitHub
Files (1)
- SKILL.md
SKILL.md (first lines)
# Android / KMP Testing
## Stack
| Concern | Library |
|---|---|
| Test framework | JUnit5 |
| Assertions | AssertK |
| Flow / StateFlow testing | Turbine |
| Coroutine testing | `kotlinx-coroutines-test` + `UnconfinedTestDispatcher` |
| UI testing | `ComposeTestRule` |
---
## ViewModel Unit Tests
### Setup
```kotlin
class NoteListViewModelTest {
private val testDispatcher = UnconfinedTestDispatcher()
@BeforeEach
fun setUp() {
Dispatchers.setMain(testDispatcher)
}
@AfterEach
fun tearDown() {
Dispatchers.resetMain()
}
}
```
### Testing State with Turbine
```kotlin
@Test
fun `loading notes emits notes in state`() = runTest {
val repo = FakeNoteRepository()
val viewModel = NoteListViewModel(repo)
viewModel.state.test {
viewModel.onAction(NoteListAction.OnRefreshClick)
assertThat(awaitItem().isLoading).isTrue()
assertThat(awaitItem().notes).isNotEmpty()
}
}
```
### Testing Events (one-time side effects)
```kotlin
@Test
fun `clicking note sends NavigateToDetail event`() = runTest {
val viewModel = NoteListViewModel(FakeNoteRepository())
viewModel.events.test {
viewModel.onAction(NoteListAction.OnNoteClick("123"))
assertThat(awaitItem()).isEqualTo(NoteListEvent.NavigateToDetail("123"))
}
}
```
---
## Fake Repositories
Prefer **fakes** (not mocks) for repository dependencies. A fake is a simple in-memory implementation:
```kotlin
class FakeNoteRepository : NoteRepository {
private val notes = mutableListOf<Note>()
var shouldReturnError = false
override suspend fun getNotes(): Result<List<Note>, DataError.Local> {
return if (shouldReturnError) Result.Error(DataError.Local.UNKNOWN)
else Result.Success(notes.toList())
}
override suspend fun insertNote(note: Note): EmptyResult<DataError.Local> {
notes.add(note)
return Result.Success(Unit)
}
}
```
---
## SavedStateHandle in Tests
Instantiate it directly — no mocking needed:
```kotlin
val savedStateHandle = SavedStateHandle(mapOf("noteId" to "123"))
val viewModel = NoteEditorViewModel(savedStateHandle, FakeNoteRepository())
```
---
## When to Inject Dispatchers
Only inject `CoroutineDispatcher` into a class when:
1. It dispatches to a non-main dispatcher (e.g., `IO`), AND
2. That class is directly unit-tested.
ViewModels that only use `viewModelScope` do not need injected dispatchers. Use `Dispatchers.setMain()` in tests instead.
If a non-ViewModel class uses `withContext(Dispatchers.IO)` and is unit-tested, inject the dispatcher:
```kotlin
class ImageCompressor(private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO) {
suspend fun compress(bytes: ByteArray): ByteArray = withContext(ioDispatcher) { ... }
}
// In test:
val compressor = ImageCompressor(ioDispatcher = UnconfinedTestDispatcher())
```From kvithayathil/agent-resources, AGPL-3.0.
More from kvithayathil/agent-resources
- 0.544score
design-an-interface
mattpocock
Generate multiple radically different interface designs for a module using parallel sub-agents.
SkillAFreshness: AClaude Code +9 - 0.539score
grill-me
mattpocock
Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree.
SkillAFreshness: AClaude Code +9 - 0.479score
modern-git-patterns
kvithayathil
Use when working with git commands, planning git workflows, advising on git best practices, or needing version-aware git guidance.
SkillCFreshness: CClaude Code +9 - 0.414score
android-layouts
kvithayathil
Android layout best practices for XML/Views and Jetpack Compose.
SkillDFreshness: DClaude Code +9 - 0.414score
design-md
kvithayathil
Create, consume, and validate DESIGN.md files — the open format for describing visual identity to coding agents.
SkillDFreshness: DClaude Code +9 - 0.410score
provenance-tracking
kvithayathil
Ensures every remote-installed skill has a references/ folder citing its upstream source and can be checked for updates against that source.
SkillDFreshness: DClaude Code +9 - 0.409score
android-error-handling
kvithayathil
Generic Result wrapper, error types, and extension helpers for Android/KMP - Result<T, E>, DataError, EmptyResult, map, onSuccess, onFailure.
SkillDFreshness: DClaude Code +9 - 0.409score
android-module-structure
kvithayathil
Module layout, dependency rules, and Gradle convention plugins for Android and Kotlin Multiplatform (KMP) projects.
SkillDFreshness: DClaude Code +9 - 0.409score
android-navigation
kvithayathil
Type-safe Compose Navigation for Android/KMP - route objects, feature nav graphs, cross-feature callbacks, and wiring in :app.
SkillDFreshness: DClaude Code +9 - 0.409score
android-presentation-mvi
kvithayathil
MVI presentation layer for Android/KMP - State, Action, Event, ViewModel, Root/Screen composable split, UI models, UiText error mapping, and process death…
SkillDFreshness: DClaude Code +9 - 0.409score
android-di-koin
kvithayathil
Koin dependency injection setup for Android/KMP - module definitions per layer, ViewModel injection, assembling modules in :app, and koinViewModel() in…
SkillDFreshness: DClaude Code +9 - 0.409score
android-data-layer
kvithayathil
Data layer patterns for Android/KMP - data sources, repositories, DTOs, mappers, Room entities, Ktor HttpClient, safe call helpers, token storage, and…
SkillDFreshness: DClaude Code +9
Signals
- Stars
- 0
- Forks
- 0
- Open issues
- 1
- Last commit (this folder)
- Apr 14, 2026 (6 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- AGPL-3.0
- Repository
- github.com/kvithayathil/agent-resources
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from kvithayathil
- 0.479score
modern-git-patterns
kvithayathil
Use when working with git commands, planning git workflows, advising on git best practices, or needing version-aware git guidance.
SkillCFreshness: CClaude Code +9 - 0.414score
design-md
kvithayathil
Create, consume, and validate DESIGN.md files — the open format for describing visual identity to coding agents.
SkillDFreshness: DClaude Code +9 - 0.414score
android-layouts
kvithayathil
Android layout best practices for XML/Views and Jetpack Compose.
SkillDFreshness: DClaude Code +9 - 0.410score
provenance-tracking
kvithayathil
Ensures every remote-installed skill has a references/ folder citing its upstream source and can be checked for updates against that source.
SkillDFreshness: DClaude Code +9 - 0.409score
android-di-koin
kvithayathil
Koin dependency injection setup for Android/KMP - module definitions per layer, ViewModel injection, assembling modules in :app, and koinViewModel() in…
SkillDFreshness: DClaude Code +9 - 0.409score
android-error-handling
kvithayathil
Generic Result wrapper, error types, and extension helpers for Android/KMP - Result<T, E>, DataError, EmptyResult, map, onSuccess, onFailure.
SkillDFreshness: DClaude Code +9
Done for you
Rather not set it up yourself?
Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.
See how we build AI agents →Read the case studies
Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.
- launches shipped
- 50+
- launches shipped
- media placements
- 500+
- media placements
- founders on every account
- 2
- founders on every account
Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block
Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.
Get android-testing running in your business
Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.
Cite this page
android-testing skill. Agent Mart. https://agentmart.dev/skills/kvithayathil-android-testing (last updated 2026-10-24)