---
id: gh-dart-migrate-to-checks-package
name: "dart-migrate-to-checks-package"
url: https://skills.yangsir.net/skill/gh-dart-migrate-to-checks-package
author: dart-lang
domain: testing
tags: ["dart", "testing", "migration", "checks", "refactoring"]
install_count: 17800
rating: 4.60 (120 reviews)
github: https://github.com/dart-lang/skills/tree/main/skills/dart-migrate-to-checks-package
---

# dart-migrate-to-checks-package

> 帮助 Dart 开发者将测试代码中的 `package:matcher` 断言语句迁移到更现代、可读性更强的 `package:checks` 语法。通过自动化工具和清晰的指导，简化测试断言的重构过程，提升测试代码的清晰度和维护性。

**Stats**: 17,800 installs · 4.6/5 (120 reviews)

## Before / After 对比

### 测试断言迁移效率提升

**Before**:

手动将 Dart 测试代码中的 `package:matcher` 断言语句逐一替换为 `package:checks` 语法，过程繁琐、耗时且容易引入错误，尤其对于大型测试套件。

**After**:

利用本 Skill 提供的自动化指导和示例，快速、准确地将 `package:matcher` 断言迁移至 `package:checks`，显著减少手动工作量和潜在错误，提升测试代码质量。

| Metric | Before | After | Change |
|---|---|---|---|
| 迁移时间 | 120分钟 | 20分钟 | -83% |

## Readme

# Migrating Dart Tests to Package Checks

## Contents
- [Dependency Management](#dependency-management)
- [Syntax Migration Guidelines](#syntax-migration-guidelines)
- [Utilizing Dart MCP Tools](#utilizing-dart-mcp-tools)
- [Migration Workflow](#migration-workflow)
- [Examples](#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<Type>())` with `check(actual).isA<Type>()`.
- **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
1. Run the `analyze_files` tool on the modified test directories.
2. Review any static analysis warnings or errors (e.g., missing imports, incorrect generic types on `isA`, unawaited futures).
3. Fix the warnings.
4. Repeat until the analyzer returns zero issues.

### Feedback Loop: Test Validation
1. Run the `run_tests` tool.
2. If tests fail, review the failure output. `package:checks` provides detailed context (e.g., `Which: has length of <2>`).
3. Adjust the `check()` expectations or the underlying code to resolve the failure.
4. Repeat until all tests pass.

## Examples

### Basic Assertions
**Input (`matcher`):**
```dart
expect(someList.length, 1);
expect(someString, startsWith('a'));
expect(someObject, isA<Map>());
```

**Output (`checks`):**
```dart
check(someList).length.equals(1);
check(someString).startsWith('a');
check(someObject).isA<Map>();
```

### Composed Expectations
**Input (`matcher`):**
```dart
expect('foo,bar,baz', allOf([
  contains('foo'),
  isNot(startsWith('bar')),
  endsWith('baz')
]));
```

**Output (`checks`):**
```dart
check('foo,bar,baz')
  ..contains('foo')
  ..not((s) => s.startsWith('bar'))
  ..endsWith('baz');
```

### Asynchronous Futures
**Input (`matcher`):**
```dart
expect(Future.value(10), completion(equals(10)));
expect(Future.error('oh no'), throwsA(equals('oh no')));
```

**Output (`checks`):**
```dart
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`):**
```dart
var stdout = StreamQueue(Stream.fromIterable(['Ready', 'Go']));
await expectLater(stdout, emitsThrough('Ready'));
```

**Output (`checks`):**
```dart
var stdout = StreamQueue(Stream.fromIterable(['Ready', 'Go']));
await check(stdout).emitsThrough((it) => it.equals('Ready'));
```


---
*Source: https://skills.yangsir.net/skill/gh-dart-migrate-to-checks-package*
*Markdown mirror: https://skills.yangsir.net/api/skill/gh-dart-migrate-to-checks-package/markdown*