test-best-practices

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

When to use this skill

何时使用此技能

In a Dart or Flutter project. When a user asks to "enforce test best practices" or similar. When modifying or creating test files.
在Dart或Flutter项目中。 当用户要求“推行测试最佳实践”或类似需求时。 在修改或创建测试文件时。

Workflow

工作流程

  1. Search: Use the grep commands below to identify candidates.
  2. Analyze: Check if the code violates the best practices defined below.
  3. Apply: Refactor the code to use the recommended matchers.
  4. Verify: Run tests (
    dart test
    ) to ensure no regressions.
  1. 搜索:使用以下grep命令识别候选代码。
  2. 分析:检查代码是否违反以下定义的最佳实践。
  3. 应用:重构代码以使用推荐的匹配器。
  4. 验证:运行测试(
    dart test
    )确保没有回归问题。

Search Strategies

搜索策略

  • .length
    :
    grep -r "\.length,\s*equals\(" test/
  • Boolean properties:
    grep -rE "expect\(.*\.(is(Empty|NotEmpty)),\s*(isTrue|true|isFalse|false)" test/
  • Manual loops:
    grep -r "for (var .* in .*)" test/
    (manual review required)
  • .length
    grep -r "\.length,\s*equals\(" test/
  • 布尔属性:
    grep -rE "expect\(.*\.(is(Empty|NotEmpty)),\s*(isTrue|true|isFalse|false)" test/
  • 手动循环:
    grep -r "for (var .* in .*)" test/
    (需手动审查)

Best Practice Patterns

最佳实践模式

Collections

集合

Use
hasLength

使用
hasLength

Prefer
expect(list, hasLength(n))
over
expect(list.length, n)
. Applies to:
Iterable
,
Map
,
String
.
优先使用
expect(list, hasLength(n))
而非
expect(list.length, n)
适用范围
Iterable
Map
String

Use
isEmpty
/
isNotEmpty

使用
isEmpty
/
isNotEmpty

Prefer
expect(list, isEmpty)
over
expect(list.isEmpty, true)
. Prefer
expect(list, isNotEmpty)
over
expect(list.isNotEmpty, true)
or
expect(list, isNot(isEmpty))
. Applies to:
Iterable
,
Map
,
String
.
优先使用
expect(list, isEmpty)
而非
expect(list.isEmpty, true)
。 优先使用
expect(list, isNotEmpty)
而非
expect(list.isNotEmpty, true)
expect(list, isNot(isEmpty))
适用范围
Iterable
Map
String

Declarative Verification

声明式验证

Prefer
expect(list, everyElement(matcher))
over manual loops with assertions.
优先使用
expect(list, everyElement(matcher))
而非带断言的手动循环。

List Equality

列表相等性

Prefer
expect(actualList, expectedList)
over manual loops checking elements by index.
package:test
provides readable diffs for list mismatches.
优先使用
expect(actualList, expectedList)
而非按索引检查元素的手动循环。
package:test
会为列表不匹配情况提供易读的差异信息。

Maps

映射

Use
containsPair

使用
containsPair

Prefer
expect(map, containsPair(key, value))
over
expect(map[key], value)
.
Note: If verifying a key is missing, use
expect(map, isNot(contains(key)))
.
优先使用
expect(map, containsPair(key, value))
而非
expect(map[key], value)
注意:若要验证某个键不存在,使用
expect(map, isNot(contains(key)))

Strict Equality

严格相等性

Prefer
expect(map, {'k': 'v'})
over multiple
containsPair
calls when the full map is known.
当已知完整映射内容时,优先使用
expect(map, {'k': 'v'})
而非多次调用
containsPair

Types & Objects

类型与对象

Declarative Type Checks

声明式类型检查

Prefer
expect(obj, isA<T>())
over
expect(obj is T, isTrue)
.
优先使用
expect(obj, isA<T>())
而非
expect(obj is T, isTrue)

Grouped Assertions

分组断言

Prefer chaining
having
on
isA<T>
for multiple property checks.
dart
expect(obj, isA<MyType>()
  .having((o) => o.prop1, 'prop1', a)
  .having((o) => o.prop2, 'prop2', b));
优先在
isA<T>
上链式调用
having
来进行多属性检查。
dart
expect(obj, isA<MyType>()
  .having((o) => o.prop1, 'prop1', a)
  .having((o) => o.prop2, 'prop2', b));

Constraints

约束条件

  • Verify Types: Ensure subject is strictly
    Iterable
    /
    Map
    before applying collection matchers. Some custom classes (e.g.
    PriorityQueue
    ) may have
    .length
    but don't implement
    Iterable
    .
  • Do NOT migrate to package:checks: Unless explicitly requested. This skill focuses on
    package:test
    matchers.
  • Preserve Behavior: Ensure refactorings do not change strictness.
  • 验证类型:在应用集合匹配器前,确保目标对象严格为
    Iterable
    /
    Map
    。部分自定义类(如
    PriorityQueue
    )可能有
    .length
    但未实现
    Iterable
  • 请勿迁移至package:checks:除非明确要求。此技能专注于
    package:test
    匹配器。
  • 保留行为:确保重构不会改变严格性。