flutter-tdd
SKILL.md
When to Use
- Starting implementation of any new feature (write test FIRST)
- Testing domain entities and value objects
- Testing use cases / application services
- Testing Riverpod notifiers and providers
- Creating mock implementations for repository interfaces
- Testing infrastructure adapters (API clients, local storage)
Critical Patterns
| Pattern | Rule |
|---|---|
| Test FIRST | Write the failing test before production code. Always. |
| Red -> Green -> Refactor | Fail -> pass -> clean up. Never skip a step. |
| Mirror structure | test/ mirrors lib/ exactly |
| File naming | foo.dart -> foo_test.dart |
| Mocks via interfaces | Domain repository interfaces ARE the mock boundary — no mockito needed for simple cases |
| No test pollution | Each test is independent, no shared mutable state |
| group() for context | Use group() to organize related tests |
| Riverpod: use ProviderContainer | Create isolated containers per test |
The TDD Cycle
1. RED — Write a test that describes the desired behavior. Run it. It MUST fail.
2. GREEN — Write the MINIMUM code to make the test pass. Nothing more.
3. REFACTOR — Clean up while keeping tests green.
4. REPEAT
When Writing Code with AI
1. DESCRIBE the behavior you want as a test
2. AI writes the failing test
3. Run it — confirm RED
4. AI writes the implementation
5. Run it — confirm GREEN
6. AI refactors if needed
7. Run it — confirm still GREEN
Test Directory Structure
mobile/
test/
features/
auth/
domain/
entities/
user_test.dart
value_objects/
email_test.dart
password_test.dart
application/
use_cases/
login_use_case_test.dart
presentation/
providers/
auth_state_provider_test.dart
infrastructure/
repositories/
auth_repository_impl_test.dart
booking/
domain/
application/
presentation/
infrastructure/
shared/
domain/
value_objects/
money_test.dart
helpers/
mocks.dart # Shared mock implementations
test_providers.dart # Riverpod test overrides
Domain Entity Tests
Value Object Tests
Mock Pattern (Manual — No Framework)
For more complex mocking needs, use mocktail:
Use Case Tests
Riverpod Provider/Notifier Tests
AsyncNotifier Tests
Either Pattern Tests
When using fpdart or dartz for Either<Failure, T>:
Commands
# Run all unit tests
flutter test
# Run specific test file
flutter test test/features/auth/domain/entities/user_test.dart
# Run tests matching a name pattern
flutter test --name "login"
# Run with coverage
flutter test --coverage
# View coverage report (install lcov first: brew install lcov)
genhtml coverage/lcov.info -o coverage/html
open coverage/html/index.html
# Run tests in a specific directory
flutter test test/features/auth/
# Watch mode (re-run on changes) — requires flutter_test_watch or similar
# Not built-in; use: find test -name '*_test.dart' | entr flutter test
Dev Dependencies
Anti-Patterns
| Don't | Do |
|---|---|
| Write code first, tests later | Write test FIRST (red), then code (green) |
| Test implementation details | Test behavior — inputs and outputs |
| Shared mutable state between tests | Fresh setUp() per test |
| Import infrastructure in domain tests | Mock via interfaces |
Skip tearDown for ProviderContainer |
Always container.dispose() |
| One giant test function | group() + focused test() with descriptive names |
Use print() for debugging tests |
Use expect() with clear matchers |
| Mock everything | Only mock external boundaries (repos, APIs) |
Weekly Installs
1
Repository
333-333-333/agentsFirst Seen
5 days ago
Security Audits
Installed on
amp1
cline1
opencode1
cursor1
kimi-cli1
kiro-cli1