<< All versions
Skill v1.0.2
currentAutomated scan100/100hoangnguyen0403/agent-skills-standard/flutter-testing
13 files
──Details
PublishedOctober 2, 2026 at 01:38 PM
Content Hashsha256:6271465ee7e957a8...
Git SHA1fb0537c339c
Bump Typepatch
──Files
Files (1 file, 5.3 KB)
SKILL.md5.3 KBactive
SKILL.md · 82 lines · 5.3 KB
version: "1.0.2" name: flutter-testing description: Write 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. metadata: triggers: files:
- '/test/.dart'
- '/integration_test/.dart'
- '/robots/.dart'
- 'lib/core/keys/**.dart'
keywords:
- test
- patrol
- robot
- WidgetKeys
- patrolTest
- blocTest
- mocktail
Flutter Testing Standards
Priority: P0 (CRITICAL)
The Four-Pillar Test Value Framework
The Four Pillars provide a qualitative reasoning framework to assess test value:
- Protection against Regressions ($P$): Catches real defects; evaluated qualitatively or via mutation kill score. A test that passes when defects exist has zero protection.
- Resistance to Refactoring ($R$): Decoupled from implementation details; zero false alarms on internal refactorings or domain additions. Tests coupled to private state or mock sequences score low on resistance.
- Fast Feedback ($F$): Executes in milliseconds; rapid local TDD feedback loop.
- Maintainability ($M$): Clean AAA structure, fluent test data builders when setup repetition obscures intent, high readability, zero boilerplate duplication.
Avoid calculating or inventing arbitrary numeric scores (e.g. $P \times R \times F \times M$) statically without measured mutation or runtime evidence.
Core Rule Anchors
- `[MOB-TEST-01]` Tripartite Naming: Name tests
Method_Scenario_ExpectedBehavior. - `[MOB-TEST-02]` BLoC State Invariant Rule: Assert state transitions using
isA<State>().having(...)predicates; BAN full copyWith mirrors. - `[MOB-TEST-03]` Entity Invariant & Serialization Rule: Test calculations, validations, domain invariants, and non-trivial serialization/parsing or error mapping. BAN testing generated code, trivial getters/setters,
props, or echo tests (expect(item.discount, equals(5))) where the test merely repeats literal assignments. - `[MOB-TEST-04]` Contract Testing Rule: Repositories and data sources must be tested for contract compliance, golden JSON parsing, and error mapping. BAN 1:1 pass-through mock echoing (
when(() => dataSource.get()).thenAnswer((_) async => x); expect(await repo.get(), x)). - `[MOB-TEST-05]` Bug-First Regression Lock: Every PR fixing a bug ticket or with title
fix(...)must introduce a failing test reproducing the defect before fixing it.
Core Rules
- Test Pyramid: Unit > Widget > Integration.
- Naming: Follow
[MOB-TEST-01](Method_Scenario_ExpectedBehavior). - AAA: Arrange, Act, Assert in all tests.
- Isolated Builders: Fluent builders when setup complexity warrants (
OrderBuilder); avoid brittle shared global mocks. - File Placement:
_integration_test.dartONLY inintegration_test/. - Robot-First: All UI assertions/interactions via Robot pattern (extending
BaseRobot) — never rawfind.*/expect()in test body. UseWidgetKeysconstants fromlib/core/keys/. - Negative Assertions: Add
expectXxxNotVisible()in robot only when absence is part of the business contract (e.g. restricted action hidden), not blanket pairs for unrelated content. - Widget Testing & Mocking: Setup with
TestWrapper.init()andtester.pumpLocalizedWidget(...). Register mock BLoCs withGetItinsetUpAll; stubstateandstreaminsetUp(usewhenListenandsettle: falsefor loading/transition states). Prohibitany(). - Integration Testing: Use
patrolTestwithIntegrationAuthHelper.loginOrSkip($)for auth flows andnative interactions($.native.*).
Anti-Patterns & Banned Smells
- `[MOB-TEST-01]` Vague names: Banish non-descriptive names (
testCart). - `[MOB-TEST-02]` Brittle state mirrors: Ban 30-property
copyWithtrees inblocTest; useisA<State>().having(...). - `[MOB-TEST-03]` Entity echo tests: Ban asserting trivial field assignments or auto-generated boilerplate (
discount: 5). Meaningful serialization/parsing error handling remains valid. - `[MOB-TEST-04]` Pass-through mock echoing: Ban 1:1 repository-to-datasource pass-through mocks without contract assertions.
- `[MOB-TEST-05]` Missing bug reproduction: Ban bug fix PRs without reproduction tests.
- No blanket negative assertions: Avoid asserting absence of unrelated content.
- No inline Key: Use
WidgetKeysconstant. No `any()`: 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 unchecked text casing: Verify
.toUpperCase(),.tr()in source.
Verification
- [ ] Repositories use fakes over mocks where appropriate.
- [ ] Distinct BLoC/ViewModel behaviors covered (loading, success, error) with
isA<State>().having(...). - [ ] Views with distinct UI logic tested via Robot pattern at proper layer.
- [ ] Critical user flows have at least one integration test using
patrolTest. - [ ]
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