进阶 flutter.dev 2026-10-10 05:26:19 · 6 阅读

第24章 使用 flutter_driver 进行集成测试

用 flutter_driver 做集成测试

单元测试能保证应用的各个部分按预期工作,但整个应用表现如何呢?这就轮到集成测试出场了。

Flutter driver

如果你从没在 Flutter(或其他平台)做过集成测试,别担心!在 Flutter 里给应用添加集成测试很简单,下面这组文章可以带你上手:

集成测试入门:这到底是什么,如何搭建?

处理滚动:如何处理常见的“滚动到某个元素”场景?

做到这一步,你就能确保应用运行不崩溃、能到达指定页面、某些操作会产生预期结果,等等。具体写哪些测试取决于你的需求:可以写一个测试遍历应用的每个页面,也可以针对具体的用户使用路径编写测试。

flutter_driver 还能更进一步,用来做性能测试。

性能分析

只要把测试包在 flutterDriver.traceAction 里,就能在测试运行时记录应用的性能数据。输出的数据(JSON 格式)可以用在持续集成(CI)测试中,比如确保某些指标保持在特定阈值之上或之下;也可以用来排查性能问题。具体如何做性能分析,请参阅文章集成测试中的性能分析部分。

供参考:Flutter Gallery 有一个集成测试,会遍历所有 demo,并为其中一部分收集性能指标。

截图测试

截图测试的思路是:渲染 UI、截取输出图像,然后与预期图片做对比。给应用添加截图测试最简单的方式是使用 flutterDriver.screenshot。想了解更多并查看真实代码示例,可以阅读社区成员 Darshan Kawar 撰写的 Medium 文章《Testing Flutter UI with Flutter Driver》。

这种方法可以轻松整合进你的持续集成流程,防止 UI 回归。Flutter Gallery 就包含几个截图测试和一份 GitHub workflow 配置,会自动对收到的 PR 进行测试。

dart await pumpWidgetWithImages( tester, const GalleryApp(initialRoute: demoBannerRoute), homeAssets, ); ​ await tester.pumpAndSettle(); ​ await expectLater( find.byType(GalleryApp), matchesGoldenFile('goldens/demo_desktop_dark.png'), );

无障碍(a11y)测试

a11y 即无障碍测试,属于可用性测试的一种,目的是确保应用对残障人士(如视障、听障、行动不便等)同样可用。可以用 flutterDriver.getSemanticsId 来校验语义标签,例如确保所有图片都有语义标签。

dart final imageLabel = find.bySemanticsLabel('Company logo'); int id = await flutterDriver.getSemanticsId(imageLabel); expect(id, isNotNull);

想深入了解无障碍测试,推荐阅读 Darshan Kawar 的另一篇好文《Developing and testing accessible apps in Flutter》。

国际化(i18n)测试

i18n 即国际化测试,用来验证应用无需修改代码就能在不同语言和地区下正常使用。

根据本地化代码的写法,你可以通过本地化 delegate 来切换 locale。

dart ExampleAppLocalizationsDelegate.load(Locale('fr'));

另一种方式:使用 MaterialApp 时,直接允许覆盖 locale,让应用以其他语言运行。

dart void main() { runApp(const ExampleApp()); } ​ class ExampleApp extends StatelessWidget { const ExampleApp({ Key key, this.locale, }) : super(key: key); ​ final Locale locale; ​ @override Widget build(BuildContext context) { return MaterialApp( locale: locale, ... ); } }

然后在启动应用的 driver 文件里设置 locale。

dart void main() { runApp(const ExampleApp(locale: Locale('fr'))); }

额外技巧

想知道某个元素是否存在于页面上?

dart /// Returns a [Future] that resolves to true if the widget specified by [finder] /// is present, false otherwise. Future isPresent(SerializableFinder finder, FlutterDriver driver, {Duration timeout = const Duration(seconds: 1)}) async { try { await flutterDriver.waitFor(finder, timeout: timeout); return true; } catch (exception) { return false; } }

超时时间可以根据你的应用自行调整。

结语

看到这里,你应该已经清楚 flutter_driver 能做些什么了。各种方法可以按需组合,比如在不同 locale 下执行截图测试。如果有遗漏之处,欢迎在评论中告诉我们!更多信息请参阅 flutter_driver API 文档。

关于作者:Pierre-Louis 是滑铁卢大学应届本科毕业生,现居慕尼黑,所在的团队负责维护 Flutter Material 库。他对 UI、UX 和应用开发有浓厚兴趣。你可以在 LinkedIn 和 GitHub 上与他联系。

来自 Flutter 的更多内容

我是如何把 GenLatte 迁移到全栈 Dart 的 顺便降低了应用的服务器开销

Craig Labenz 2026 年 9 月 22 日 · 7 分钟阅读

用 A2UI 的 Client-Side Functions 实现快速可靠的计算 了解 client-side functions 如何让 agent 把本地操作直接交给运行在用户设备上的 Dart 代码处理。

Andrew Brogdon 2026 年 8 月 28 日 · 5 分钟阅读

评论 (0)