npx skills add ...
npx skills add flutter/skills --skill dart-matcher-best-practices
npx skills add flutter/skills --skill dart-matcher-best-practices
Best practices for using `expect` and `package:matcher`. Focuses on readable assertions, proper matcher selection, and avoiding common pitfalls.
Use this skill when:
expect and package:matcher.To find candidates for improving matcher usage, search for suboptimal patterns:
Search for length checks that should use hasLength:
expect\([^,]+.length,\s*Search for checks on boolean properties that have specific matchers:
expect\([^,]+.isEmpty,\s*(true|equals\(true\))expect\([^,]+.isNotEmpty,\s*(true|equals\(true\))expect\([^,]+.contains\(.*\),\s*(true|equals\(true\))Search for manual map lookups instead of containsPair:
expect\([^,]+\[.*\],\s*hasLength, contains, isEmpty, unorderedEquals, containsPair)hasLength(n):
expect(list, hasLength(n)) over expect(list.length, n).isEmpty / isNotEmpty:
expect(list, isEmpty) over expect(list.isEmpty, true).expect(list, isNotEmpty) over expect(list.isNotEmpty, true).contains(item):
expect(list.contains(item), true).unorderedEquals(items):
expect(list, containsAll(items)).containsPair(key, value):
expect(map[key], value) or
expect(map.containsKey(key), true).isA<T> and TypeMatcher<T>)isA<T>():
expect(obj, isA<Type>()).TypeMatcher<Type>()..having().TypeMatcher<T>:
const: const isMyType = TypeMatcher<MyType>();.having() works here too, but the resulting matcher is not const.having)Use .having() on isA<T>() or other TypeMatchers to check properties.
(e) => e.message) instead of generic ones like p0 to improve readability.This provides detailed failure messages indicating exactly which property failed.
completion(matcher):
await expectLater(...) to ensure the future completes before
the test continues.await expectLater(future, completion(equals(42))).throwsA(matcher):
await expectLater(future, throwsA(isA<StateError>())).expect(() => function(), throwsA(isA<ArgumentError>())) (synchronous
function throwing is fine with expect).expectLaterUse await expectLater(...) when testing async behavior to ensure proper
sequencing.
if statements or for loops for
assertions; let matchers handle it.containsPair for maps instead of checking keys manually).package:matcher to modern
package:checks.// GOOD: Waits for future to complete before checking side effects
await expectLater(future, completion(equals(42)));
expect(sideEffectState, equals('done'));
// BAD: Side effect check might run before future completes
expect(future, completion(equals(42)));
expect(sideEffectState, equals('done')); // Race condition!