testing
SKILL.md
Testing
When to use
- Adding a repository, datasource, or parsing logic.
- Implementing or refactoring a BLoC/Cubit.
- Adding regression coverage for a bug.
Steps
1) Organize tests to mirror source folders
- Keep
test/structure aligned with the source layout so ownership and coverage are obvious. - Do not add dedicated tests for pure barrel export files.
- Group tests by behavior domain (render/navigation, BLoC event name, repository method name).
2) Unit test pure logic first
Prefer tests around:
- parsing/serialization
- mapping and validation logic
- small helpers/services
Example (DTO parsing):
import 'package:flutter_test/flutter_test.dart';
void main() {
test('OrderDto parses expected payload', () {
final dto = OrderDto.fromMap({
'id': '1',
'createdAt': '2026-01-01T00:00:00.000Z',
'timeout_ms': 0,
'status': 'unknown',
});
expect(dto.id, '1');
});
}
3) Test repositories with mocked datasources/clients
Use mocktail (or your project’s standard) to isolate I/O:
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
class _RemoteMock extends Mock implements IOrdersRemoteDataSource {}
void main() {
test('repository maps failures to typed exceptions', () async {
final remote = _RemoteMock();
when(() => remote.fetchOrders()).thenThrow(Exception('boom'));
final repo = OrdersRepository(remote: remote);
expect(repo.getOrders(), throwsA(isA<NetworkException>()));
});
}
4) Test BLoCs for success + failure paths
Prefer bloc_test and keep expectations explicit:
import 'package:bloc_test/bloc_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
class _RepoMock extends Mock implements IOrdersRepository {}
void main() {
blocTest<OrdersBloc, OrdersState>(
'emits Loading then Loaded',
build: () {
final repo = _RepoMock();
when(() => repo.getOrders()).thenAnswer((_) async => const []);
return OrdersBloc(repository: repo);
},
act: (bloc) => bloc.add(const OrdersStartedEvent()),
expect: () => [const OrdersLoadingState(), const OrdersLoadedState(orders: [])],
);
}
If event ordering is part of the expected behavior, separate event dispatches in act:
act: (bloc) async {
bloc.add(const FirstEvent());
await Future<void>.delayed(Duration.zero);
bloc.add(const SecondEvent());
},
5) Keep widget tests focused
Widget tests should verify:
- key UI states (loading/error/loaded)
- critical interactions
- behavior that can regress, not static constants
Prefer one scenario per test for easier failure diagnosis.
6) Use package:checks for Assertions
For clearer failure messages and a fluent API, prefer package:checks over matcher:
import 'package:checks/checks.dart';
import 'package:flutter_test/flutter_test.dart';
test('validates value', () {
final value = 42;
check(value).equals(42);
check(value).isGreaterThan(0);
});
7) Keep tests isolated and order-independent
- Keep
setUp/tearDowninsidegroup(...)blocks. - Recreate mutable collaborators per test; avoid shared static mutable state.
- Run randomized ordering periodically in CI to expose hidden coupling:
flutter test --test-randomize-ordering-seed random
8) Golden tests
- Tag golden tests consistently (for example
golden) so they can run separately. - Use
--update-goldensonly in explicit golden update workflows.
flutter test --tags golden
flutter test --tags golden --update-goldens
9) Integration Tests
Use integration_test for critical user flows (e.g., login, checkout).
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:my_app/main.dart' as app;
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('full login flow', (tester) async {
app.main();
await tester.pumpAndSettle();
await tester.enterText(find.byKey(const Key('email_field')), 'test@example.com');
await tester.tap(find.byKey(const Key('login_btn')));
await tester.pumpAndSettle();
expect(find.text('Welcome back!'), findsOneWidget);
});
}
Weekly Installs
2
Repository
yelmuratoff/agent_syncGitHub Stars
3
First Seen
Feb 27, 2026
Security Audits
Installed on
opencode2
gemini-cli2
antigravity2
claude-code2
github-copilot2
codex2