news 2026/9/11 18:16:40

如何为 Flutter devicelab 编写新的内存测试用例并接入 CI

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何为 Flutter devicelab 编写新的内存测试用例并接入 CI

如何为 Flutter devicelab 编写新的内存测试用例并接入 CI

【免费下载链接】flutterFlutter makes it easy and fast to build beautiful apps for mobile and beyond项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutter

Flutter 的 CI 系统会对每个 commit 在真实设备上运行 DeviceLab 测试,其中内存性能是高优先级指标。如果你的场景是"给某个 benchmark 应用新增一个内存测试,让 CI 持续测量其内存表现",操作路径在 如何为 Flutter 编写内存测试 中给出:为测试应用编写main入口、在 devicelab 的bin/tasks目录添加一个任务文件、并把任务注册进 CI。

这条路径的适用前提是:

  • 宿主机装有 Flutter SDK,并且测试环境可以访问 ADB(Android 类测试要求);
  • 本地运行 Android 测试时需要设置ANDROID_SDK_ROOT环境变量。如果你有一份本地 engine 构建,Android SDK 位于.../engine/src/third_party/android_tools/sdk,也可以用flutter doctor -v找到自己的 Android SDK 位置(见 dev/devicelab/README.md)。

选择哪一类内存测试

文档给出了 DeviceLab 目前实际使用的三类内存测试,先按目标平台选定一类,再按该类步骤操作:

类型位置关键特性(摘自文档)主要限制(摘自文档)
MemoryTest(直接轮询 adb)perf_tests.dart 中的 MemoryTest 类开销低;release 模式可用;测试自行控制测量起止只有开始/结束两次读数;轮询 ADB 可能触发 Java heap GC;仅 Android;需要 ADB 环境和装好 Flutter SDK 的宿主机
DevTools 内存测试perf_tests.dart 中的 DevToolsMemoryTest 类约每秒一次读数,还能拿到 Dart VM 内存信息;可以把已有的速度类 driver 测试转成内存测试对测量起止的控制较少;无 release 模式,profile/debug 模式可能带来额外内存开销;仅 Android
iOS 内存测试由 driver 测试 + 任务文件中measureMemory: true触发(见 perf_tests.dart)采样频率可调;采样开销比调 adb 小;宿主机不需要 Flutter SDK仅 iOS;无 release 模式;内存轮询机制本身可能有额外开销

三类机制的区别:MemoryTest在可覆写的useMemory函数前后直接通过 adb 采样,默认的useMemory行为是应用以 release 模式运行并等待 logcat 中的 "done" 消息;DevTools 测试在普通 Flutter driver 测试运行期间通过 DevTools 轮询 adb 和 Dart VM;iOS 测试利用 iOS 嵌入层在运行时采样内存并写入 Dart timeline,事后从 timeline profile 中解析内存信息。

下面的主路径以MemoryTest(Android)为例。文档给出的完整示例可对照 complex_layout 的内存测试任务文件、macrobenchmarks 的大图滚动内存测试,以及它们的被测应用入口 dev/benchmarks/complex_layout/test_memory/scroll_perf.dart 和 dev/benchmarks/macrobenchmarks/test_memory/large_images.dart。

第一步:为测试应用写 main 入口

按文档要求,在 benchmark 工程的test_memory/目录下创建一个文件,例如test_memory/some_memory_perf.dart,其中包含测试应用的main函数。被测应用负责跑你想测量的操作,并在 logcat 中输出约定格式的标记日志(形如==== MEMORY BENCHMARK ==== <消息> ====),供MemoryTest通过prepareForNextMessage等待——例如READY表示应用启动完成,TAPPED表示点击已被确认。

MemoryTest的构造函数参数是:项目目录、main文件相对路径、Android 包名,以及可选的requiresTapToStart(启动后需要点击才开始的场景,如 complex_layout 示例)。

第二步:在 bin/tasks 下编写 devicelab 任务文件

dev/devicelab/bin/tasks/目录添加与测试同名的some_memory_perf.dart。任务名就是该文件的 basename(不带.dart扩展名),CI 中引用的task_name与此一致。一个任务文件只允许一个task。文档示例(complex_layout 场景)的内容如下,可作为模板改写:

// 文件:dev/devicelab/bin/tasks/complex_layout_scroll_perf__memory.dart(仓库现有示例) import 'package:flutter_devicelab/framework/devices.dart'; import 'package:flutter_devicelab/framework/framework.dart'; import 'package:flutter_devicelab/framework/utils.dart'; import 'package:flutter_devicelab/tasks/perf_tests.dart'; Future<void> main() async { deviceOperatingSystem = DeviceOperatingSystem.android; await task( MemoryTest( '${flutterDirectory.path}/dev/benchmarks/complex_layout', 'test_memory/scroll_perf.dart', 'com.yourcompany.complexLayout', requiresTapToStart: true, ).run, ); }

写完后把三个占位信息替换为你自己的值:benchmark 工程路径(project)、test_memory/下 main 文件的相对路径(test)、被测应用的 Android 包名(package)。如果你的测试需要自定义测量过程(比如像 fast_scroll_large_images__memory.dart 那样覆写useMemory、覆写iterationCount),在该任务文件中定义一个继承MemoryTest的子类即可。

iOS 分支(可选):任务文件改为指定measureMemory: true的 driver 测试任务,例如 large_image_changer_perf_ios.dart;Android 的 DevTools 分支类似,任务是 large_image_changer_perf_android.dart 这类 driver 测试任务。

第三步:把任务注册进 CI

文档正文要求为新测试在dev/devicelab/manifest.yaml中添加一个条目。需要注意:在当前仓库快照中,dev/devicelab/下已没有manifest.yaml文件,CI 目标实际定义在仓库根目录的 .ci.yaml 中。因此当前有效的注册方式是按 dev/devicelab/README.md 的 "Adding tests to continuous integration" 一节操作:在.ci.yaml中新增一个 target,镜像一个已有的devicelab_dronerecipe target,task_name填你的任务名。

仓库中现有的真实 target 示例(可直接对照改写):

# .ci.yaml 中现有条目(Linux mokey benchmark 段) - name: Linux_mokey complex_layout_scroll_perf__memory recipe: devicelab/devicelab_drone presubmit: false timeout: 60 properties: tags: > ["devicelab","android","linux","mokey"] task_name: complex_layout_scroll_perf__memory dependencies: >- [ {"dependency": "open_jdk", "version": "version:21"} ]

README 同时说明:如果测试需要在多个操作系统上运行,为每个系统创建独立的 target;presubmit 的 DeviceLab 容量有限,是否加入 presubmit 需要先提team-infraissue 论证可行性,不要直接加presubmit: true

本地运行并验证

README 要求先本地通过再部署到 CI。以下副作用需要提前知道:本地运行 DeviceLab 测试会自动在你机器上启停 Gradle,并且设备在累计运行若干测试后会被自动重启(对应checkForRebootRequired()device.reboot())。

dev/devicelab目录下运行({NAME_OF_TEST}换成你的任务名,即bin/tasks文件 basename):

# from the .../flutter/dev/devicelab directory ../../bin/cache/dart-sdk/bin/dart bin/test_runner.dart test -t {NAME_OF_TEST}

默认带自动重试(失败测试最多额外重试 2 次);想禁用重试复现问题时加--exit

../../bin/cache/dart-sdk/bin/dart bin/test_runner.dart test --exit -t {NAME_OF_TEST}

成功的判断方式来自 perf_tests.dart 中 MemoryTest.run 的实现:任务对每轮迭代的开始、结束和差值做统计,以TaskResult.success返回,指标键为startenddiff三组统计数据。CI 侧的行为见 README:任务成功时 runner 上报成功并把性能指标上传到 Flutter 基础设施;失败会自动 rerun,某次 rerun 成功即整体记为成功并标记 flake;全部 rerun 失败才上报失败且不采集指标。

限制与边界

  • MemoryTest只适用于 Android 目标,且需要能访问 ADB 的环境;它的两次读数(begin/end)之外没有更细的测量。
  • DevTools 与 iOS 两类内存测试均没有 release 模式,profile 或 debug 模式下可能带来额外内存开销;iOS 侧的内存轮询机制本身也可能增加开销。
  • 若你的测试还需要区分构建与测试阶段(例如在 host-only bot 上构建 apk 再上设备测试),README 提供了 build and test 模型的迁移路径(继承BuildTestTask并覆写getBuildArgsgetTestArgs等),该模型下.ci.yamltarget 需镜像Linux_build_testMac_build_test平台的现有 target,并在 CI 验证通过后移除bringup: true正式启用。

参考文件

  • 内存测试编写文档:三类内存测试的机制、优缺点与三步流程
  • devicelab README:本地运行命令、注册 CI target、presubmit 与 build/test 模型
  • MemoryTest / DevToolsMemoryTest 实现
  • 现有任务文件目录

【免费下载链接】flutterFlutter makes it easy and fast to build beautiful apps for mobile and beyond项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutter

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 18:13:07

深度迁移学习水质预测算法源码解析与实战指南

简介&#xff1a;基于深度迁移学习的水质预测研究算法源码&#xff0c;是一份面向计算机、数学、电子信息等专业课程设计、期末大作业及毕设项目的完整工程代码。项目以水质预测为应用场景&#xff0c;覆盖数据加载、时间特征生成、模型构建、迁移学习训练和结果评估等环节&…

作者头像 李华
网站建设 2026/9/11 18:07:43

2026年IT从业者必备的5大黄金认证与备考策略

1. 为什么2026年IT从业者需要职业护身符&#xff1f;过去三年里&#xff0c;我面试过上百位技术候选人&#xff0c;发现一个明显趋势&#xff1a;2023年头部企业的技术岗位JD中&#xff0c;83%明确要求特定技术认证。这不是偶然——当ChatGPT能写基础代码、低代码平台吞噬初级岗…

作者头像 李华
网站建设 2026/9/11 18:07:21

G-Helper:单文件替代奥创的笔记本控制工具

G-Helper&#xff1a;单文件替代奥创的笔记本控制工具 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenbook, Expertbook, R…

作者头像 李华
网站建设 2026/9/11 18:05:40

基于SSM框架的养老院管理系统实战:从权限控制到部署避坑指南

简介&#xff1a;基于SSM框架的Java毕业设计项目——养老院管理系统的完整源码包&#xff0c;面向计算机相关专业学生及Java开发者&#xff0c;可作为毕业设计参考或养老信息化系统的业务原型。系统采用B/S架构与MySQL数据库&#xff0c;后台管理与前台管理并行&#xff0c;按管…

作者头像 李华