ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Flutter 集成测试套件实践:dev/integration_tests 的两种形态、本地调试与 Devicelab 运行机制

Flutter 集成测试套件实践:dev/integration_tests 的两种形态、本地调试与 Devicelab 运行机制 Flutter 集成测试套件实践dev/integration_tests 的两种形态、本地调试与 Devicelab 运行机制【免费下载链接】flutterFlutter makes it easy and fast to build beautiful apps for mobile and beyond项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutterdev/integration_tests是 Flutter 仓库中专用于真机自动化集成测试的目录它存放的每个测试套件要么是完整 Flutter 应用 flutter_driver驱动规范的组合要么是为测试 Flutter 集成而准备的原生宿主应用。这些套件主要服务于 Devicelab 真机实验室开发者也可以在本地用flutter drive命令直接调试单个套件。读完本文你将理解该目录下两类套件的差异、如何在本地运行与调试一个 driver 测试、Devicelab 框架在底层如何包装flutter drive与flutter test以及新增测试时 CI 注册的约束。测试套件的两种形态根据 dev/integration_tests/README.md 的定义目录下的每个套件属于以下二者之一完整 Flutter 应用 flutter_driver规范一个可独立运行的 Flutter 应用配合test_driver/目录下的驱动代码从 UI 层驱动测试。这是最典型的形态原生宿主应用一个 native app用于测试 Flutter 以嵌入/集成方式接入宿主环境时的行为例如 iOS 的 add-to-app、Android 的 hybrid views 场景。从目录结构可以印证这一点像 channels、flavors、platform_interaction 这类套件都是标准 Flutter 应用加驱动代码而 ios_add2app_life_cycle、ios_host_app、hybrid_android_views 等则以原生工程为主体。此外从仓库中各套件的 README 可以看到部分套件还承担更细粒度的职责例如dev/integration_tests/ui/README.mdui套件是不依赖插件的 UI 集成测试集合设备端代码在lib/驱动端代码在test_driver/两者协同工作通常经由 devicelab 运行dev/integration_tests/keyboard_hot_restart/README.md一个专门验证热重启后键盘应被隐藏的最小应用dev/integration_tests/spell_check/README.md用于测试EditableText拼写检查功能的 Flutter 工程。本地运行与调试flutter drive原 README 给出的核心操作是想在本地跑一个 driver 测试比如调试某个挂掉的测试时进入对应套件的子目录执行flutter drive -t test --driver driver原文档给出的实例flutter drive -t lib/keyboard_resize.dart --driver test_driver/keyboard_resize_test.dart这个例子的真实来源是ui套件中的键盘尺寸测试。设备端目标lib/keyboard_resize.dart负责渲染被测界面驱动端 test_driver/keyboard_resize_test.dart 则通过FlutterDriver.connect()建立连接后用find.byValueKey定位带 ValueKey 的控件来验证行为。以键盘弹出/收起时视图是否正确缩放为例其核心逻辑是先读取初始状态下高度文本keys.kHeightText的文本内容作为基准高度点击文本框keys.kDefaultTextField弹出软键盘由于检测软键盘开合的唯一实用方式是轮询等待布局变化测试以 300ms 间隔轮询最多 200 次约 60 秒比较键盘弹出后的高度是否小于基准高度点击取消聚焦按钮keys.kUnfocusButton收起键盘再验证高度恢复。驱动代码中值得注意的工程细节是轮询上限的注释在本地真机上Pixel 8 Pro (API 36) 通常一次轮询即可观察到布局变化而较老的 Galaxy Tab S3 (API 28) 需要 23 次由于有 issue 记录显示键盘弹出偶尔最长可耗时 21.3 秒所以把轮询总窗口放宽到 60 秒。这类注释体现了真机测试对设备差异的容忍策略。ui套件的 pubspec.yaml 也展示了 driver 测试套件的典型依赖形态flutter_driver与integration_test两个 SDK 包同时引入——test_driver/走flutter_driver路线integration_test/目录则走integration_test包路线Devicelab 对这两条路线分别用flutter drive和flutter test驱动后文详述。Devicelab 如何驱动这些套件DriverTest与IntegrationTest这些套件Intended for use with devicelab tests原 README 原话其背后的执行器是 Devicelab 框架。dev/devicelab/README.md 描述了整体机制任务声明目标设备类型linux_android、mac_ios等实验室中空闲设备领取任务执行成功则上报性能指标失败自动重跑最终全部失败才上报为失败。具体到dev/integration_tests下的套件Devicelab 侧的入口集中在 dev/devicelab/lib/tasks/integration_tests.dart它提供两个核心执行器DriverTest包装flutter driveDriverTest对应上面完整应用 driver 规范形态。其call()的执行链为通过devices.workingDevice选定设备并unlock()或接受外部传入的deviceIdOverride在套件目录下执行flutter packages get组装参数并执行final options String[ --no-android-gradle-daemon, -v, -t, testTarget, -d, deviceId, ...extraOptions, ]; await flutter(drive, options: options, environment: env);也就是说本地手敲的flutter drive -t test -d device --driver ...在 Devicelab 里由DriverTest以--no-android-gradle-daemon -v的附加参数自动完成。它还会向驱动进程注入环境变量FLUTTER_DEVICE_ID_NUMBER与FLUTTER_ADB_PATH让驱动代码如需操作 ADB 的场景可以直接引用设备号。各套件到执行器的映射函数也在这个文件里例如createEndToEndKeyboardTest()→ui套件的lib/keyboard_resize.dart即上文本地调试的例子createChannelsIntegrationTest()→channels套件的integration_test/main_test.dart走IntegrationTestcreateDisplayCutoutTest()→display_cutout_rotation套件并在setup中通过cmd overlay enable ...给设备注入合成刘海、在tearDown中移除dartDefinesTask()→ 向flutter drive追加--dart-define参数验证自定义 define 的透传。IntegrationTest包装flutter test对于integration_test包路线的套件如channels、spell_check、ui/integration_testDevicelab 使用IntegrationTest执行器其关键步骤为await flutter(packages, options: String[get]); await setup?.call(await devices.workingDevice); // 可选为纯 Dart 套件动态生成平台目录 if (createPlatforms.isNotEmpty) { await flutter(create, options: String[--platforms, createPlatforms.join(,), --no-overwrite, .]); } final options String[-v, -d, deviceId, testTarget, ...extraOptions]; await flutter(test, options: options, environment: environment);相比DriverTest它还多了三项能力setup/tearDown钩子在设备对象上执行前置/后置操作如display_cutout_rotation的刘海开关、Android 版本校验getprop ro.build.version.sdk要求 API 30createPlatforms对缺少原生工程目录的套件现场执行flutter create --platforms list --no-overwrite .例如engine_integration_golden_test只为windows平台补目录withTalkBack仅在 Android 设备上启用 TalkBack 以运行android_semantics_testing套件测试结束后自动关闭。特殊形态会改源码的keyboard_hot_restartdev/devicelab/lib/tasks/keyboard_hot_restart_test.dart 展示了集成测试的一种更重的玩法。由于该测试必须对应用执行热重启XCUITest、integration_test均不支持它直接使用flutter run拉起应用然后通过解析 stdout 实现状态机waitUntilDartVmAvailable → waitUntilKeyboardOpen → waitUntilHotRestart → waitUntilKeyboardClosed流程是先把套件源码 lib/main.dart 中的const bool forceKeyboard false;改写为true使应用启动即弹出键盘看到日志flutter: Keyboard is open后再把源码改回false并向 stdin 写入R触发热重启确认Restarted application in ...后等待flutter: Keyboard is closed写入q结束。finally块保证无论成败都会把main.dart恢复原内容。这是原生宿主/工具级测试的一个典型样本测试逻辑与flutter工具链本身的交互run、热重启、日志解析紧密耦合。CI 集成新测试需要新的 CI 目标原 README 最后一节强调了一条重要规则Adding code to this directory will not automatically cause it to be run by any already existing ci tooling. This directory is intentionally a choose your own adventure piece of tooling.也就是说往dev/integration_tests下新增代码不会自动被任何现有 CI 工具运行——该目录有意保持自选路线的开放性。要让一个套件真正进入 CI需要在 .ci.yaml 中新增对应的 target。仓库中现存目标可作参照- name: Mac_ios spell_check_test ... task_name: spell_check_test_ios - name: Mac keyboard_hot_restart_ios ... task_name: keyboard_hot_restart_ios - name: Linux windowing_test ... task_name: windowing_test_linux可以看到 target 名按平台 设备 特性组织如Mac keyboard_hot_restart_ios、Windows windowing_testtask_name则与 Devicelab 任务名对应最终由 dev/devicelab/lib/tasks/integration_tests.dart 中的工厂函数如createSpellCheckIntegrationTest落到具体套件目录与测试入口文件。按 dev/devicelab/README.md 的说法测试跨多个操作系统时要为每个操作系统各建一个 target本地验证则可在dev/devicelab目录下用../../bin/cache/dart-sdk/bin/dart bin/test_runner.dart test -t {NAME_OF_TEST}以与 CI 相近的方式运行任务支持--exit跳过自动重试支持--local-engine系列参数针对本地引擎构建验证。小结dev/integration_tests下的套件分两类Flutter 应用 flutter_driver驱动规范以及用于 Flutter 集成测试的原生宿主应用它们服务于 Devicelab 真机实验室也可在本地以flutter drive -t test --driver driver的方式直接调试本地调试实例flutter drive -t lib/keyboard_resize.dart --driver test_driver/keyboard_resize_test.dart对应 ui 套件的键盘缩放验证驱动端通过轮询布局变化来检测软键盘开合Devicelab 侧由 integration_tests.dart 中的DriverTest包装flutter drive与IntegrationTest包装flutter test附带 setup/tearDown、平台目录生成、TalkBack 开关等钩子驱动这些套件由于该目录是choose your own adventure式工具集新增测试不会自动接入 CI必须在 .ci.yaml 中显式新增 target并按需跨平台各建一份。【免费下载链接】flutterFlutter makes it easy and fast to build beautiful apps for mobile and beyond项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表