之前也写过一篇文章
Appium 做 flutter 自动化测试实践&采坑 appium-flutter-deriver 驱动来测试 flutter 应用,这个插件有不少 bug ,之前也改动了下驱动源码解决了 ios 真机无法连接问题,但是真正使用上这个三方库,元素识别,输入等是真的难用,混合应用没啥办法,而且必须还要是 debug 模式。

现在做 iOS UI 自动化的同学大多都在使用 Wda XCUITest 框架,但是 XCUITest 驱动看不到元素树,这篇主要记录下使用 XCUITest 来测试 Flutter 的过程。

网上搜索好多资料 flutter issues 看了好多,也问了好多,不知道是问的不对,官方最终建议使用:flutter_driver 驱动做 UI 自动化😹 😹 😹 ,总之都没啥好的解决方案, 没办法自己找找吧
官方盖楼 https://github.com/flutter/flutter/issues/17988

用真机安装 Flutter app 看看实际效果,好吧果然是没有元素树的

但是使用模拟器启动,居然可以看到元素树内容

既然模拟器可以看到,真机看不到,那么官方必然做了某些限制,开始各种找资料
看了一篇大佬写的 flutter 视图渲染流程 RendererBinding 主要负责的是视图渲染相关的,跑去看看官方
RendererBinding api 有什么重要的内容,发现一个 api

setSemanticsEnabled(bool enabled) → void
Whether the render tree associated with this binding should produce a tree of SemanticsNode objects.

感觉很靠谱去官方源码里面一阵乱看,搜到了一段源码,inspector is enabled on the simulator 感觉好像找到了原因。

#if TARGET_OS_SIMULATOR
  // There doesn't appear to be any way to determine whether the accessibility
  // inspector is enabled on the simulator. We conservatively always turn on the
  // accessibility bridge in the simulator, but never assistive technology.
  platformView->SetSemanticsEnabled(true);
  platformView->SetAccessibilityFeatures(flags);
#else
  bool enabled = UIAccessibilityIsVoiceOverRunning() || UIAccessibilityIsSwitchControlRunning();
  if (enabled)
    flags |= static_cast<int32_t>(flutter::AccessibilityFeatureFlag::kAccessibleNavigation);
  platformView->SetSemanticsEnabled(enabled || UIAccessibilityIsSpeakScreenEnabled());
  platformView->SetAccessibilityFeatures(flags);
#endif

https://github.com/flutter/engine/blob/0c504da039beb48105bdd336335ab146d6ddd59f/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm#L1053

如果是模拟器,默认开启 inspector,真机则需要需要开启 UIAccessibilityIsVoiceOverRunning() 或者 UIAccessibilityIsSwitchControlRunning() 方法

https://developer.apple.com/documentation/uikit/1615187-uiaccessibilityisvoiceoverrunnin

意思是需要真机开启手机的 VoiceOver 读屏功能才会开启元素树展示,试一下
通用->辅助功能->语音 开启

再来看下真机 App 到此元素终于能出来,元素终于出来了,打包一个 release 也看下,依然能识别, flutter app 和 混合 app 用 XCUITest 测试好像有救了啦,过程比较艰辛,结果确如此简单😤


↙↙↙阅读原文可查看相关链接,并与作者交流