在第一次接手 Flutter 项目之前,我对"Flutter App 如何测试"这件事的理解,其实非常简单:
UI 是 Flutter 写的,逻辑在 Dart 里,照着官方文档把 widget test、integration test 跑起来,应该就差不多了。
但真正把 Flutter App 跑在 iOS 真机上,经历过几轮测试和线上反馈之后,我发现Flutter 的测试问题,很少只发生在 Flutter 层。
Flutter 自带测试,解决的是"代码正确性"
在项目初期,我们确实按部就班做了这些事情:
- widget test 覆盖核心组件
- 部分逻辑用 Dart test 校验
- CI 上跑 integration test
这些测试非常有价值,它们能保证:
- UI 结构不会被误改
- 状态更新逻辑符合预期
- 基础交互不会直接出错
但当测试同事开始反馈一些问题时,我们发现这些测试并不能回答所有问题。
真正的问题,出现在"跑起来之后"
测试反馈并不是"功能不对",而是一些很典型的运行期描述:
- 页面来回切换后变得不流畅
- 使用一段时间后内存明显上升
- 某些设备上发热比较明显
- WebView 页面偶发白屏
这些问题,Flutter 层的测试是看不到的。
Flutter App 测试,绕不开平台层
在 iOS 上,Flutter App 的运行形态其实很清晰:
- UI 由 Flutter Engine 驱动
- Dart 代码通过 Engine 调度
- 渲染、线程、内存、能耗最终仍然落在 iOS 系统层
这意味着,Flutter App 的测试,必须同时关注:
- Flutter 层行为
- iOS 系统层表现
- 原生插件的影响
如果只盯着 Dart 和 Widget,很容易遗漏真正的瓶颈。
Instruments:理解 Flutter 在 iOS 上"怎么跑"的起点
在第一次性能排查时,我直接用了 Instruments。
Time Profiler 很快就能看出一些特点:
- Flutter Engine 占用一定比例的 CPU
- 某些页面切换时渲染线程明显活跃
- 原生插件调用集中在特定时段
这些信息并不会告诉你"哪里写错了",但能帮你判断:
问题是出在 Flutter 本身,还是出在某个插件或业务逻辑。
当问题不是因为一次操作而产生的
但 Instruments 很快遇到瓶颈:
问题并不是在某一次页面切换时立刻出现,而是 跑久了才慢。
这时候,我开始更多依赖真机上的长期观察,而不是短时间采样。
把 Flutter App 当成"普通 iOS App"来看
在这一步,我引入了 克魔(KeyMob)。
原因很简单:
Flutter 写的是 UI,但在 iOS 上,它终究是一个 iOS App。
通过 KeyMob,我开始从 iOS 视角看 Flutter App:
- CPU 使用是否随操作次数上升
- 内存是否在页面退出后回落
- FPS 在多次进入同一页面后的变化
- 网络、日志是否在后台持续活跃
这些信息,是 Flutter 测试框架本身提供不了的。
一个真实的测试发现过程
在一次回归测试中,我们用 Flutter App 连续跑了二十多分钟,反复操作几个核心页面。
现象并不剧烈,但很一致:
- 内存呈现缓慢上升
- FPS 在前几次操作后开始下降
- CPU 均值比初始状态高
回头用 Instruments 定位,发现是某个 Flutter 页面在 dispose 时,并没有完全释放资源,而对应的 iOS 侧对象也被间接保留。
如果没有 KeyMob 这类持续观察工具,很难意识到这是一个"累积型问题"。
Flutter + WebView,测试复杂度会再上一个台阶
项目里有一部分页面是 Flutter + WebView 混合。
这时,问题就不再只属于 Flutter 或 iOS 任何一侧。
我通常会这样配合使用工具:
- Safari Inspector:查看 JS 是否还在运行
- KeyMob:观察 WebView 页面切换前后的内存、CPU
- Instruments:确认线程与渲染开销
在一次白屏问题中,就是通过这种组合,确认 WebView 在 Flutter 页面销毁后仍然短时间存活,导致资源占用叠加。
网络问题,在 Flutter 测试中同样不可忽视
Flutter 的网络请求通常封装得很好,但这也带来一个问题:
你很容易忽略网络行为对性能的影响。
通过 Charles 抓包,我们发现:
- 某些接口在弱网下会频繁重试
- 返回数据不大,但解析频率很高
- 对 Flutter UI 刷新有间接影响
如果只看 Flutter 层的测试结果,这些问题是不会暴露的。
Flutter App 测试,本质是"多层测试"
慢慢地,我对 Flutter App 测试的理解变成了这样:
- Flutter 测试:保证 UI 和逻辑正确
- iOS 工具:理解运行期行为
- 真机监控:发现长期、累积问题
在这个过程中,KeyMob 更像是一个连接 Flutter 行为与 iOS 系统表现的中间层,而不是单独存在的工具。
Flutter 让跨平台开发变得更高效,但它并没有消除性能、资源、系统行为这些问题。
只是把它们隐藏在了更深的一层。
当你开始用 iOS 工程师的视角去测试 Flutter App,很多解释不清楚的问题,才会慢慢变得具体。