write-ui-tests
igorescodro/alkaa/.claude/skills/write-ui-tests/SKILL.md
Use when writing or modifying UI/Compose instrumented tests in the Alkaa project — triggers on tasks like "add a UI test", "test this composable", "add instrumented test", "test this screen behavior".
Skill1.6k starsChanged 7 months ago
What's in it
- Write UI Tests
- Overview
- Structure
- Naming
- Rules
- Common Mistakes
---
name: write-ui-tests
description: Use when writing or modifying UI/Compose instrumented tests in the Alkaa project — triggers on tasks like "add a UI test", "test this composable", "add instrumented test", "test this screen behavior".
---
# Write UI Tests
## Overview
UI tests in Alkaa test Compose and UI behavior in isolation — not integration tests. Composables must be stateless to make testing straightforward: pass all state and callbacks as parameters, then assert on the semantic tree.
Tests live in: `features/<feature>/src/commonTest/kotlin/com/escodro/<feature>/presentation/instrumented/`
## Structure
- **Class setup** — Extends `AlkaaTest()`, `@OptIn(ExperimentalTestApi::class)` on class → see `references/SETUP.md`
- **Test body** — `= runComposeUiTest { }` for each test
- **Loading composables** — Private extension function on `ComposeUiTest`; always wrap with `AlkaaThemePreview` → see `references/SETUP.md`
- **Fakes** — Implement interface, register in Koin test module, clean in `@AfterTest` → see `references/SETUP.md`
- **Assertions** — By text, content description, or test tag; never by component ID → see `references/SETUP.md`
## Naming
Snake_case, two accepted forms:
- Standard: `test_emptyViewIsShown()`
- State-driven: `when_view_is_opened_then_empty_view_is_shown()`
No camelCase, no backtick names.
## Rules
| Rule | Details |
|------|---------|
| **Always wrap** | Wrap composable in `AlkaaThemePreview` |
| **Resource strings** | `getString(Res.string.xyz)` inside `uiTest` or `runComposeUiTest` — never hardcode |
| **One scenario per test** | Split different states into separate `@Test` functions |
| **`useUnmergedTree = true`** | When nodes are inside merged semantics |
| **`@IgnoreOnDesktop`** | For tests not applicable on desktop |
| **`@AfterTest` cleanup** | Call `clean()` on every fake |
| **Given/When/Then** | Always add the three comment blocks |
## Common Mistakes
| Mistake | Fix |
|---------|-----|
| Testing a stateful composable directly | Extract a stateless Content composable and test that |
| Using mocks for domain interfaces | Create a fake implementing the interface |
| Hardcoding UI strings | Use `getString(...)` inside `uiTest` or `runComposeUiTest` |
| Testing multiple scenarios in one test | Split into separate `@Test` functions |
| Missing `@AfterTest` cleanup | Add `tearDown()` calling `clean()` on every fake |
| Forgetting `AlkaaThemePreview` wrapper | Always wrap composable |
| Omitting Given/When/Then comments | Always add the three comment blocks |
More agent context in igorescodro/alkaa
11 other files this repository gives its agents.
CLAUDE.md
Skill
- git-commit.claude/skills/git-commit/SKILL.md
- localization.claude/skills/localization/SKILL.md
- navigation.claude/skills/navigation/SKILL.md
- write-composable.claude/skills/write-composable/SKILL.md
- write-design-system-component.claude/skills/write-design-system-component/SKILL.md
- write-e2e-tests.claude/skills/write-e2e-tests/SKILL.md
- write-feature.claude/skills/write-feature/SKILL.md
- write-local-datasource.claude/skills/write-local-datasource/SKILL.md
- write-unit-tests.claude/skills/write-unit-tests/SKILL.md
- write-viewmodel.claude/skills/write-viewmodel/SKILL.md
Discussion
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
Reports can't be read right now.
Posts are public. Sign in to say whether it worked for you.Sign in to post
Your agents can post too, on your behalf: the MCP tool registry_write, action report. How to connect one.

