Flutter Testing Standards
SkillAI & modelsWrite unit, widget, and integration tests with robot patterns, widget keys, and Patrol in Flutter. Use when implementing test behavior; defer CI-only configuration without test changes.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Flutter Testing Standards skill
What this skill tells your AI
The instructions your AI receives, as published by hoangnguyen0403/agent-skills-standard in skills/flutter/flutter-testing/SKILL.md and read by ahel’s review.
Priority: P0 (CRITICAL)
Core Rules
- Test Pyramid: Unit > Widget > Integration.
- Naming:
should <behavior> when <condition>. - AAA: Arrange, Act, Assert in all tests.
- Shared Mocks:
test/shared/only — no local mocks. - File Placement:
_integration_test.dartONLY inintegration_test/. - Robot-First: ALL UI assertions/interactions via Robot pattern (e.g.,
CheckoutRobot) — never rawfind.*/expect()in test body.
Widget Testing & Mocking
- Setup: Use
TestWrapper.init()insetUpAllandtester.pumpLocalizedWidget(...). - Mocking: Use GetIt registration of Mock BLoCs in
setUpAllif created internally. Use blocTest for BLoC logic and whenListen for state transitions. - Stubbing: Always stub bloc.state and bloc.stream in
setUp. Prohibitany()/anyNamed(). - Async: Use settle: false for loading or stream states to verify mid-process transitions.
Robot Pattern
- All interactions and assertions belong in
*Robot(e.g.,expectFirstOrderVisible()). - Symmetric: every
expectXxxVisible()needs expectXxxNotVisible() pairs. - BaseRobot Centralization: Extract standard scrolling (
scrollDown,scrollToEnd) and screen visibility assertions (expectScreenVisible,expectScreenNotVisible) into commonBaseRobotor parent class to avoid duplication. - Widget tests: include
pumpScreen(bloc:, settle:)helper. - Widget Keys: Use WidgetKeys constants from
lib/core/keys/— never inlineKey('string').
Integration Testing
- Use patrolTest with IntegrationAuthHelper.loginOrSkip($) for authenticated flows.
- Use $.native.tap() or
$.native.*for native interactions (e.g., system dialogs). - Create robot:
final robot = OrdersRobot($.tester)— share same class as widget tests. - Only
$.native.*and navigation helpers may remain inline in test body.
Anti-Patterns
- No inline Key: Use
WidgetKeysconstant. Noany(): Use typed matchers. - No local mocks: Use
test/shared/. No missing bloc stub: Stubstate+stream. - No test-body logic: Move
find.*/expect()to robot. No raw find in integration tests. - No
_integration_test.dartintest/: Rename or merge. - No unused imports: Remove
v_dlswhen robots handle assertions. Check Material import needs. - No happy-path-only: Add
Edge casesgroup. No one-sided assertions: AddexpectNotVisiblepairs. - No unchecked text casing: Verify
.toUpperCase(),.tr()in source.
Verification
- Fakes used over Mocks for Repositories (well-defined inputs/outputs).
- Every ViewModel has unit tests covering loading, success, and error states.
- Every View has widget tests with faked ViewModel.
- Critical user flows have at least one integration test.
-
flutter testpasses.
Canonical response anchors
When this skill applies, preserve the following domain terminology or equivalent concrete examples in the answer when relevant:
- GetIt registration
- Register the mock with
GetItinsetUpAllbefore building the widget under test. - native interactions
Signals
- GitHub stars
- 565
- Forks
- 163
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
flutter-testing- Source
- github.com/hoangnguyen0403/agent-skills-standard