write-unit-tests

star 1.6k

Use when writing or modifying unit tests in the Alkaa project — triggers on tasks like "add a test", "write tests for X", "test this ViewModel", "cover this use case with tests", or "add unit test coverage".

igorescodro By igorescodro schedule Updated 3/28/2026

name: write-unit-tests description: Use when writing or modifying unit tests in the Alkaa project — triggers on tasks like "add a test", "write tests for X", "test this ViewModel", "cover this use case with tests", or "add unit test coverage".

Write Unit Tests

Overview

Unit tests in Alkaa are multiplatform-first, fake-based, and structured around a single scenario per test. Tests live in commonTest and run fastest via ./gradlew desktopTest.

Structure

  • Given / When / Then — Use comments to separate the three blocks in every test → see references/TEST_EXAMPLES.md
  • Backtick names — Start with test if or check if, describe the specific condition and expected outcome
  • One scenario per test — Split side effects, error paths, and edge cases into separate tests
  • Fakes only — Never mocks for domain interfaces → see references/FAKE_PATTERNS.md for all three fake patterns
  • CoroutinesTestDispatcher — Delegate by CoroutinesTestDispatcherImpl() for any coroutine-using test class → see references/TEST_EXAMPLES.md
  • ViewModel test setup → see references/TEST_EXAMPLES.md
  • Use case / repository test setup → see references/TEST_EXAMPLES.md

Naming

✅ `test if when load tasks fails the error state is returned`
✅ `test if task is updated as completed`
✅ `test if category without name is not added`
❌ testUpdateTask()
❌ test1()

Rules

Rule Details
Fakes over mocks Only use mocks for Android/Framework types you cannot interface (e.g., Context)
CoroutinesTestDispatcher Delegate by CoroutinesTestDispatcherImpl() for any coroutine-using test class
ViewModel at field level Construct ViewModel at field level, not inside @BeforeTest
runTest for suspend Use = runTest { } for all suspend test bodies
flow.first() Collect current state with flow.first()
require() for narrowing Use require(state is X) before accessing state-specific properties
@BeforeTest cleanup Call clean() on every fake to reset state between tests

Common Mistakes

Mistake Fix
Using mocks for domain interfaces Create a fake implementing the interface
Forgetting CoroutinesTestDispatcher delegation Add by CoroutinesTestDispatcherImpl()
Testing multiple scenarios in one test Split into separate @Test functions
Skipping @BeforeTest cleanup Add setup() calling clean() on every fake
Constructing ViewModel in @BeforeTest Construct at field level so it shares dispatcher context
Omitting Given/When/Then comments Always add the three comment blocks
Vague test names like testUpdate() Rename to describe the scenario and expected outcome

Related Skills

  • ViewModel tests → use write-viewmodel skill for ViewModel construction patterns
  • UI behavior tests → use write-ui-tests skill
  • Full user flow tests → use write-e2e-tests skill
Install via CLI
npx skills add https://github.com/igorescodro/alkaa --skill write-unit-tests
Repository Details
star Stars 1,633
call_split Forks 162
navigation Branch main
article Path SKILL.md
More from Creator