Migrating Dart Tests to Package Checks
Contents
Dependency Management
Syntax Migration Guidelines
Utilizing Dart MCP Tools
Migration Workflow
Examples
Dependency Management
Manage dependencies using the Dart Tooling MCP Server
pub
tool or standard CLI commands.
Add
package:checks
as a
dev_dependency
using
dart pub add dev:checks
.
Remove
package:matcher
if it is explicitly listed in the
pubspec.yaml
(note: it is often transitively included by
package:test
, which is fine).
Import
package:checks/checks.dart
in all test files undergoing migration.
Syntax Migration Guidelines
Transition test assertions from the
package:matcher
syntax to the literate API provided by
package:checks
.
Basic Equality:
Replace
expect(actual, equals(expected))
or
expect(actual, expected)
with
check(actual).equals(expected)
.
Type Checking:
Replace
expect(actual, isA())
with
check(actual).isA()
.
Property Extraction:
Replace
expect(actual.property, expected)
with
check(actual).has((a) => a.property, 'property name').equals(expected)
.
Cascades for Multiple Checks:
Use Dart's cascade operator (
..
) to chain multiple expectations on a single subject.
Asynchronous Expectations:
If checking a
Future
,
await
the
check
call:
await check(someFuture).completes((r) => r.equals(expected));
.
If checking a
Stream
, wrap it in a
StreamQueue
for multiple checks, or use
.withQueue
for single/broadcast checks.
Utilizing Dart MCP Tools
Leverage the Dart MCP Server tools to automate and validate the migration process.
Use
pub
to run
dart pub get
or
dart pub add
.
Use
analyze_files
to run static analysis on the project or specific paths.
Use
run_tests
to execute Dart or Flutter tests with an agent-centric UX. ALWAYS use this instead of shell commands like
dart test
.
Use
dart_fix
to apply automated fixes if applicable.
Migration Workflow
Copy and use the following checklist to track progress when migrating a test suite:
Task Progress
Add
package:checks
as a dev dependency.
Identify all test files using
package:matcher
(
expect
calls).
Import
package:checks/checks.dart
in target test files.
Rewrite all
expect(...)
statements to
check(...)
statements.
Run static analyzer (
analyze_files
).
Run tests (
run_tests
).
Feedback Loop: Static Analysis
Run the
analyze_files
tool on the modified test directories.
Review any static analysis warnings or errors (e.g., missing imports, incorrect generic types on
isA
, unawaited futures).
Fix the warnings.
Repeat until the analyzer returns zero issues.
Feedback Loop: Test Validation
Run the
run_tests
tool.
If tests fail, review the failure output.
package:checks
provides detailed context (e.g.,
Which: has length of <2>
).
Adjust the
check()
expectations or the underlying code to resolve the failure.
Repeat until all tests pass.
Examples
Basic Assertions
Input (
matcher
):
expect
(
someList
.
length
,
1
)
;
expect
(
someString
,
startsWith
(
'a'
)
)
;
expect
(
someObject
,
isA
<
Map
(
)
)
;
Output (
checks
):
check
(
someList
)
.
length
.
equals
(
1
)
;
check
(
someString
)
.
startsWith
(
'a'
)
;
check
(
someObject
)
.
isA
<
Map
(
)
;
Composed Expectations
Input (
matcher
):
expect
(
'foo,bar,baz'
,
allOf
(
[
contains
(
'foo'
)
,
isNot
(
startsWith
(
'bar'
)
)
,
endsWith
(
'baz'
)
]
)
)
;
Output (
checks
):
check
(
'foo,bar,baz'
)
.
.
contains
(
'foo'
)
.
.
not
(
(
s
)
=
s
.
startsWith
(
'bar'
)
)
.
.
endsWith
(
'baz'
)
;
Asynchronous Futures
Input (
matcher
):
expect
(
Future
.
value
(
10
)
,
completion
(
equals
(
10
)
)
)
;
expect
(
Future
.
error
(
'oh no'
)
,
throwsA
(
equals
(
'oh no'
)
)
)
;
Output (
checks
):
await
check
(
Future
.
value
(
10
)
)
.
completes
(
(
it
)
=
it
.
equals
(
10
)
)
;
await
check
(
Future
.
error
(
'oh no'
)
)
.
throws
<
String
(
)
.
equals
(
'oh no'
)
;
Asynchronous Streams
Input (
matcher
):
var
stdout
=
StreamQueue
(
Stream
.
fromIterable
(
[
'Ready'
,
'Go'
]
)
)
;
await
expectLater
(
stdout
,
emitsThrough
(
'Ready'
)
)
;
Output (
checks
):
var
stdout
=
StreamQueue
(
Stream
.
fromIterable
(
[
'Ready'
,
'Go'
]
)
)
;
await
check
(
stdout
)
.
emitsThrough
(
(
it
)
=
it
.
equals
(
'Ready'
)
)
;