关于 dart-add-unit-test
为 Dart 和 Flutter 项目提供单元测试编写与执行指南,面向开发者。内容涵盖测试文件组织、测试结构、异步测试、模拟依赖和运行命令。
主要功能
- 01按 lib 目录组织测试文件
- 02使用 group、test 和 expect
- 03编写异步测试及生命周期钩子
- 04使用 Mockito 模拟依赖
- 05运行单元及集成测试
适用场景
- 01为 Dart 包创建单元测试
- 02为 Flutter 应用编写测试
- 03验证依赖注入场景
- 04执行集成测试套件
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ dart-lang/ skills --skill dart-add-unit-test安装后在 Claude Code 中输入/dart-add-unit-test确认已加载。
详细介绍
测试 Dart 和 Flutter 应用
目录
测试文件的组织方式
将测试文件的结构与 lib 目录保持一致,以确保结构清晰、易于预测。
- 将所有测试代码放在包根目录下的
test目录中。 - 所有测试文件名均以
_test.dart结尾(例如,应在test/src/utils_test.dart中测试lib/src/utils.dart)。 - 如果编写集成测试,请将其放在包根目录下的
integration_test目录中。
编写测试
将 package:test 用作 Dart 应用的标准测试库。
- 导入
package:test/test.dart(Flutter 项目则导入package:flutter_test/flutter_test.dart)。 - 使用
group()函数将相关测试分组,以共享上下文。 - 使用
test()函数定义单个测试用例。 - 使用
expect()函数和匹配器(例如equals()、isTrue、throwsA())验证结果。 - 使用标准的
async/await语法编写异步测试。测试运行器会自动等待Future完成。 - 使用
setUp()和tearDown()回调管理测试的设置和清理。 - 如果测试依赖注入相关代码,可将
package:mockito与package:test搭配使用,以生成模拟对象、配置固定场景并验证交互。
运行测试
根据项目类型和测试位置选择合适的测试运行器。
- 如果是纯 Dart 项目,使用
dart test命令运行测试。 - 如果是 Flutter 项目,使用
flutter test命令运行测试。 - 如果运行集成测试,请明确指定目录路径,因为默认运行器会忽略该目录:
dart test integration_test或flutter test integration_test。
测试实现工作流
实现新的测试套件时,请按以下顺序进行。复制此清单以跟踪进度。
任务进度
- 1. 在
test/目录中创建测试文件,并确保其以_test.dart结尾。 - 2. 导入
package:test/test.dart和目标库。 - 3. 定义
main()函数。 - 4. 使用
setUp()初始化共享资源或模拟对象。 - 5. 使用
group()按功能分组编写test()用例。 - 6. 使用合适的 CLI 命令运行测试套件。
- 7. 反馈循环:运行测试 -> 查看失败的堆栈跟踪 -> 修复实现或断言 -> 重新运行直至通过。
示例
标准单元测试套件
演示如何进行分组、设置、同步测试和异步测试。
import 'package:test/test.dart';
import 'package:my_package/calculator.dart';
void main() {
group('Calculator', () {
late Calculator calc;
setUp(() {
calc = Calculator();
});
test('adds two numbers correctly', () {
expect(calc.add(2, 3), equals(5));
});
test('handles asynchronous operations', () async {
final result = await calc.fetchRemoteValue();
expect(result, isNotNull);
expect(result, greaterThan(0));
});
});
}
使用 Mockito 进行模拟
演示如何配置模拟对象以测试依赖注入。
import 'package:test/test.dart';
import 'package:mockito/mockito.dart';
import 'package:mockito/annotations.dart';
import 'package:my_package/api_client.dart';
import 'package:my_package/data_service.dart';
// Generate the mock using build_runner: dart run build_runner build
@GenerateNiceMocks([MockSpec<ApiClient>()])
import 'data_service_test.mocks.dart';
void main() {
group('DataService', () {
late MockApiClient mockApiClient;
late DataService dataService;
setUp(() {
mockApiClient = MockApiClient();
dataService = DataService(apiClient: mockApiClient);
});
test('returns parsed data on successful API call', () async {
// Configure the mock
when(mockApiClient.get('/data')).thenAnswer((_) async => '{"id": 1}');
// Execute the system under test
final result = await dataService.fetchData();
// Verify outcomes and interactions
expect(result.id, equals(1));
verify(mockApiClient.get('/data')).called(1);
});
});
}
评论
支持 Markdown