
Testing
- 43 installs
- 605 repo stars
- Updated August 4, 2026
- evanca/flutter-ai-rules
Helps with testing & qa tasks.
About
testing is a Claude Code skill for testing & qa. It helps solo builders move faster with AI-assisted coding.
- testing
- Testing & QA
- AI-coding skill
Testing by the numbers
- 43 all-time installs (skills.sh)
- Ranked #1,252 of 2,153 Testing & QA skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/evanca/flutter-ai-rules --skill testingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 43 |
|---|---|
| repo stars | ★ 605 |
| Last updated | August 4, 2026 |
| Repository | evanca/flutter-ai-rules ↗ |
What it does
Helps with testing & qa tasks.
Files
Testing Skill
Write effective, meaningful Flutter and Dart tests that catch real regressions.
When to Use
Use this skill when:
- Writing unit tests for business logic, repositories, or utility classes.
- Writing widget tests for UI components.
- Reviewing existing tests for correctness and coverage.
- Fixing flaky or false-positive tests.
- Deciding between unit tests, widget tests, and integration tests.
---
1. Test Validity
Before writing or accepting a test, ask:
"Can this test actually fail if the real code is broken?"
- Avoid tests that only confirm mocked/fake behavior without exercising real logic.
- Avoid tests that confirm behavior guaranteed by the language or standard library.
- Every test must be capable of catching a real regression.
// BAD — tests the mock, not real logic
test('should return user', () {
when(() => repo.getUser()).thenReturn(fakeUser);
expect(repo.getUser(), fakeUser); // Only proves the mock works
});
// GOOD — tests the cubit's state transitions driven by the mock
blocTest<UserCubit, UserState>(
'should emit loaded state when getUser succeeds',
build: () {
when(() => repo.getUser()).thenAnswer((_) async => fakeUser);
return UserCubit(repo);
},
act: (cubit) => cubit.fetchUser(),
expect: () => [
const UserState(status: UserStatus.loading),
UserState(status: UserStatus.loaded, user: fakeUser),
],
);---
2. Structure
Always use group() in test files. Name the group after the class under test:
group('Counter', () {
late Counter counter;
setUp(() {
counter = Counter();
});
test('value should start at 0', () {
expect(counter.value, 0);
});
test('should increment value by 1', () {
counter.increment();
expect(counter.value, 1);
});
});Rules:
- Use
setUpfor shared object creation; usetearDownfor cleanup (closing streams, controllers). - Keep each test focused on one behavior.
- Nest
group()blocks for sub-features when a class has many methods.
---
3. Naming
Name test cases using "should" to describe expected behavior:
test('should emit updated list when item is added', () { ... });
test('should throw ArgumentError when input is negative', () { ... });---
4. Unit Tests vs Widget Tests
| Type | Target | Tools |
|---|---|---|
| Unit test | Pure Dart logic, repositories, cubits/blocs | test, bloc_test, mocktail |
| Widget test | Individual widgets, UI behavior, navigation | flutter_test, WidgetTester |
Default to unit tests for business logic. Use widget tests when verifying UI rendering, gesture handling, or widget interaction.
---
5. Widget Test Patterns
testWidgets('should display error message on failure', (tester) async {
await tester.pumpWidget(
MaterialApp(
home: BlocProvider<LoginCubit>.value(
value: mockLoginCubit,
child: const LoginView(),
),
),
);
// Simulate failure state
whenListen(
mockLoginCubit,
Stream.fromIterable([const LoginState(status: LoginStatus.failure, errorMessage: 'Invalid')]),
initialState: const LoginState(),
);
await tester.pump();
expect(find.text('Invalid'), findsOneWidget);
});Rules:
- Wrap widgets in
MaterialApp(or the app's root widget) to provideMediaQuery,Directionality, etc. - Use
pump()for a single frame orpumpAndSettle()when animations must complete. - Prefer
find.byKeyoverfind.textfor widgets that may have localized or dynamic text.
---
6. Mocking Best Practices
- Use
mocktailfor mocks (no code generation required). - Call
registerFallbackValue()insetUpAllfor custom types passed toany(). - Mock at the repository boundary, not at the HTTP/database layer.
class MockAuthRepository extends Mock implements AuthRepository {}
void main() {
setUpAll(() {
registerFallbackValue(FakeLoginRequest());
});
// ... tests
}---
7. Test File Organization
test/
feature_a/
cubit/
feature_a_cubit_test.dart
view/
feature_a_view_test.dart
model/
feature_a_model_test.dart- Mirror the
lib/folder structure undertest/. - One test file per source file.
- Name test files
<source_file>_test.dart.