android-testing
Skill40 starsChanged 27 days agoMITView on GitHub
Defines testing standards for Android projects, including JUnit 5, Turbine, Mockito or MockK, descriptive backtick test names, parameterized tests, and flow testing patterns. Use this skill when creating, reviewing, or refactoring unit tests for ViewModels, use cases, mappers, calculators, repositories, or other pure Kotlin Android components.
5 other projects use a version of this.
Adopted by
Most recently taken up by
- wrinfotel/verified-android-skillstheir own version, first seen Oct 20, 2026
- geertberkers/claude-skillstheir own version, first seen Oct 11, 2026
- maxrave-dev/SimpMusictheir own version, first seen Oct 8, 2026
- earlzdev/android-drivertheir own version, first seen Sep 7, 2026
- Shekhar23/claude-zero-to-hero-android-KMPtheir own version, first seen Mar 29, 2026
Other versions5 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 5
- maxrave-dev/SimpMusic★ 13ksame name
- Shekhar23/claude-zero-to-hero-android-KMP★ 9same name
- earlzdev/android-driver★ 0same name
- geertberkers/claude-skills★ 0same name
- wrinfotel/verified-android-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository2 other files it gives its agents.
- android-architectureSkill
- android-patternsSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
55 rules. 0 are common, 47 are distinctive, and 8 are very specific to this project.
0
Common
Most of the 5 edited versions we read keep these.
47
Distinctive
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 9
Use this skill to create clear, behavior-focused tests for Android code.
- Distinctive: line 13
Test behavior, not implementation.
- Distinctive: line 26
Prefer unit tests for business logic, flow orchestration, mappers, and calculators.
- Distinctive: line 28
Avoid tests that depend on Android framework behavior unless they are true instrumentation tests.
- Distinctive: line 29
Verify the full expected result when the behavior has meaningful structure.
- Distinctive: line 30
Use the same naming style across the project.
- Distinctive: line 34
Use descriptive backtick names:
- Distinctive: line 45
Keep names readable without extra commentary.
- Distinctive: line 46
Use one test per scenario.
- Distinctive: line 47
Prefer names that read like a sentence.
- Very specific: line 51
Always name the subject being tested sut.
- Very specific: line 61
Use sut consistently in every test file.
- Distinctive: line 62
Keep all other mocks and test fixtures named by their actual role.
- Distinctive: line 63
Avoid vague names for dependencies.
- Distinctive: line 69
create objects and mocks
- Distinctive: line 104
Keep arrange, act, and assert separated.
- Very specific: line 105
Use expected name for the object expected to be the result.
- Very specific: line 106
Use actual name for the resultof the tested function.
- Distinctive: line 108
Keep mock setup close to the scenario it supports.
- Distinctive: line 109
Test one behavior per test unless a group of values is intentionally parameterized.
- Distinctive: line 113
Prefer complete assertions over partial checks.
- Distinctive: line 127
Use partial assertions only when the test is explicitly about a small part of the output and the rest is irrelevant.
- Distinctive: line 132
verify ordering when ordering matters
- Distinctive: line 133
verify contents when contents matter
- Distinctive: line 134
verify exact events when events matter
- Distinctive: line 139
Use the following stack:
- Very specific: line 148
Use @Test from JUnit 5.
- Very specific: line 149
Use runTest for suspending code and Flow collection.
- Distinctive: line 150
Use Turbine for emissions, completion, cancellation, and errors.
- Distinctive: line 151
Use MockK or Mockito-Kotlin consistently within the same project.
- Distinctive: line 155
Use Turbine whenever testing Flow or StateFlow behavior.
- Distinctive: line 184
Test cancellation when relevant.
- Distinctive: line 185
Test replay and state updates when using StateFlow or SharedFlow.
- Distinctive: line 186
Do not ignore intermediate emissions if they are part of the contract.
- Distinctive: line 190
Use parameterized approaches whenever multiple input and output combinations exist.
- Very specific: line 200
Use @TestFactory or dynamic tests when scenarios are naturally data driven and the body should stay compact.
- Distinctive: line 219
Use parameterized tests for repeated logic with different values.
- Distinctive: line 220
Use dynamic tests when the cases are easy to list as data.
- Distinctive: line 221
Keep scenario names meaningful.
- Distinctive: line 222
Prefer small, readable data sets.
- Very specific: line 226
Use runTest for all coroutine based tests.
- Distinctive: line 230
avoid real delays when possible
- Distinctive: line 234
keep test setup isolated from production threading behavior
- Distinctive: line 247
Test ViewModels through their public API.
- Distinctive: line 257
do not assert private implementation details
- Distinctive: line 260
use Turbine for state and event flows
- Distinctive: line 261
keep user scenarios readable through test names
- Distinctive: line 267
Test the input to output contract.
- Distinctive: line 271
Test exact mapped values.
- Distinctive: line 275
Test interaction with dependencies and returned domain results.
- Distinctive: line 280
verify repository output shape
- Distinctive: line 281
test both success and failure paths
- Distinctive: line 282
test fallback behavior when relevant
- Distinctive: line 286
Before merging a test, confirm:
- Distinctive: line 297
If a test is hard to read, hard to extend, or tied too closely to implementation details, rewrite it.
“Common” is measured: kept by at least 6 in 10 of the 5 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Android Testing
Use this skill to create clear, behavior-focused tests for Android code.
1. Testing principles
Test behavior, not implementation.
Priorities:
- correctness
- readability
- explicit expectations
- stable test names
- complete assertions
- easy diagnosis when failures happen
Rules:
- Prefer unit tests for business logic, flow orchestration, mappers, and calculators.
- Keep tests deterministic.
- Avoid tests that depend on Android framework behavior unless they are true instrumentation tests.
- Verify the full expected result when the behavior has meaningful structure.
- Use the same naming style across the project.
2. Test naming
Use descriptive backtick names:
@Test
fun `When amount is valid then it returns parsed value`() { }Rules:
- Describe the condition first.
- Describe the expected result second.
- Keep names readable without extra commentary.
- Use one test per scenario.
- Prefer names that read like a sentence.
3. System under test naming
Always name the subject being tested sut.
Example:
private lateinit var sut: ExchangeViewModelRules:
- Use
sutconsistently in every test file. - Keep all other mocks and test fixtures named by their actual role.
- Avoid vague names for dependencies.
4. Test structure
Organize tests into four blocks:
- create objects and mocks
- stub functions
- execute tested function
- assert result
Example:
private val repository = mockk<ExampleRepository>()
private val sut = ExampleUseCase(repository)
@Test
fun `when repository returns data then ui state is loaded`() = runTest {
// create objects and mocks
val text = "mocked text"
val textA = "A"
val textB = "B"
val param = mockk<Param>() {
every { this.text } returns text
}
val expected = listOf(textA, textB)
// stub functions
every { repository.getData(param) } returns flowOf(Result.success(listOf(textA, textB)))
// execute tested function
val actual = sut(text)
// assert result
assertEquals(expected = expected, actual = actual.first().getOrThrow())
}Rules:
- Keep arrange, act, and assert separated.
- Use
expectedname for the object expected to be the result. - Use
actualname for the resultof the tested function. - Assert expected against actual.
- Keep mock setup close to the scenario it supports.
- Test one behavior per test unless a group of values is intentionally parameterized.
5. Assertion style
Prefer complete assertions over partial checks.
Good:
assertEquals(expected = expectedUiState, actual = actualUiState)Better when collections matter:
assertEquals(expected = expectedItems, actual = actualItems)Use partial assertions only when the test is explicitly about a small part of the output and the rest is irrelevant.
Rules:
- assert full object values when practical
- verify ordering when ordering matters
- verify contents when contents matter
- verify exact events when events matter
- compare expected and actual explicitly
6. Preferred tools
Use the following stack:
- JUnit 5
- Turbine for Flow testing
- MockK or Mockito-Kotlin for mocking
runTestfor coroutine tests
Rules:
- Use
@Testfrom JUnit 5. - Use
runTestfor suspending code and Flow collection. - Use Turbine for emissions, completion, cancellation, and errors.
- Use MockK or Mockito-Kotlin consistently within the same project.
7. Flow testing with Turbine
Use Turbine whenever testing Flow or StateFlow behavior.
Common assertions:
awaitItem()awaitComplete()awaitError()expectNoEvents()
Example:
@Test
fun `When flow emits values, then it receives them in order`() = runTest {
val flow = flowOf(1, 2, 3)
flow.test {
assertEquals(expected = 1, actual = awaitItem())
assertEquals(expected = 2, actual = awaitItem())
assertEquals(expected = 3, actual = awaitItem())
awaitComplete()
}
}Rules:
- Test emission order.
- Test failure behavior.
- Test cancellation when relevant.
- Test replay and state updates when using StateFlow or SharedFlow.
- Do not ignore intermediate emissions if they are part of the contract.
8. Parameterized and generated tests
Use parameterized approaches whenever multiple input and output combinations exist.
Prefer:
@ParameterizedTest@MethodSource@CsvSource@EnumSource@TestFactoryfor dynamic tests
Use @TestFactory or dynamic tests when scenarios are naturally data driven and the body should stay compact.
Example:
@TestFactory
fun `When amounts are invalid, then parser returns zero`() = listOf(
"a" to BigDecimal.ZERO,
"" to BigDecimal.ZERO,
).map { (input, expected) ->
dynamicTest("input = $input") {
val actual = sut.parse(input)
assertEquals(expected = expected, actual = actual)
}
}Rules:
- Use parameterized tests for repeated logic with different values.
- Use dynamic tests when the cases are easy to list as data.
- Keep scenario names meaningful.
- Prefer small, readable data sets.
9. Coroutine and Flow test patterns
Use runTest for all coroutine based tests.
Rules:
- avoid real delays when possible
- inject dispatchers or use test dispatchers
- advance virtual time when needed
- cancel collectors when a test scenario requires it
- keep test setup isolated from production threading behavior
Useful checks:
- state updates
- retry behavior
- cancellation behavior
- error recovery
- replay behavior
- ordering of emissions
10. ViewModel testing
Test ViewModels through their public API.
Prefer testing:
onActionuiStateuiEvents
Rules:
- do not assert private implementation details
- assert the emitted state sequence
- assert side effects as events
- use Turbine for state and event flows
- keep user scenarios readable through test names
11. Repository, use case, and mapper tests
Use cases
Test the input to output contract.
Mappers
Test exact mapped values.
Repositories
Test interaction with dependencies and returned domain results.
Rules:
- mock external dependencies
- verify repository output shape
- test both success and failure paths
- test fallback behavior when relevant
12. Review checklist
Before merging a test, confirm:
- the test name explains the behavior
sutis used consistently- arrange, act, and assert are separated
- assertions compare expected and actual clearly
- data driven cases use parameterized or dynamic tests when appropriate
- Flow tests use Turbine
- coroutine tests use
runTest - the test verifies behavior instead of internal implementation
If a test is hard to read, hard to extend, or tied too closely to implementation details, rewrite it.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

