第 13 章 调试与测试
13.1 调试手段
debugPrint():打印日志(长文本不被截断,优于 print)。
- 断点调试:IDE 里直接打断点,配合 Dart DevTools。
- Widget Inspector:DevTools 的组件树检查器,点选界面元素直接定位到代码。
flutter analyze:静态检查,提交代码前必跑。
- 布局溢出(黄黑条纹):日志会精确报告溢出像素,按 5.2.1 的 Expanded 方案处理。
13.2 三层测试
// test/counter_test.dart —— 单元测试 + 组件测试,可直接 flutter test
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
// 实际项目里这两个符号来自 lib/,测试文件用 import 引入;
// 这里为了让示例独立可跑,直接定义在测试文件中。
int add(int a, int b) => a + b;
class CounterPage extends StatefulWidget {
const CounterPage({super.key});
@override
State<CounterPage> createState() => _CounterPageState();
}
class _CounterPageState extends State<CounterPage> {
int _count = 0;
@override
Widget build(BuildContext context) => Scaffold(
body: Center(child: Text('点击了 $_count 次')),
floatingActionButton: FloatingActionButton(
onPressed: () => setState(() => _count++),
child: const Icon(Icons.add),
),
);
}
void main() {
// ① 单元测试:验证纯逻辑,毫秒级完成
test('加法', () {
expect(add(1, 2), 3);
});
// ② 组件测试:模拟点击并断言界面文本
testWidgets('点击按钮后文本变化', (tester) async {
await tester.pumpWidget(const MaterialApp(home: CounterPage()));
expect(find.text('点击了 0 次'), findsOneWidget);
await tester.tap(find.byIcon(Icons.add));
await tester.pump(); // 触发一帧重建
expect(find.text('点击了 1 次'), findsOneWidget);
});
}
flutter test # 跑全部测试
flutter test --coverage