移动应用测试自动化实践
从“手工点点点”到自动化测试:我在移动项目中的实践之路

记得我刚接手第一个移动项目的时候,团队里每个人都还停留在“手动点击+截图记录”的测试阶段。那时候,我们每个版本上线前都要安排一整组人花上两三天时间在各种设备上点来点去,遇到崩溃就截图保存日志发到群里。虽然听起来挺原始,但当时确实没人想搞自动化——大家普遍觉得“移动端太复杂了”、“环境不统一”、“脚本维护成本太高”。
但我心里一直有个疑问:为什么 Web 应用可以做 CI/CD 自动化构建和测试,而移动端却还在靠人力?
这个问题最终促使我去推动团队在那个项目中第一次引入了移动应用的自动化测试方案。今天我想把这段经历写出来,分享给那些也正在考虑要不要迈出这一步的朋友。
项目背景:一个电商类 App 的挑战
这个项目是一个面向国内用户的电商类 App,初期主要是 Android 平台,后来逐步拓展到 iOS。用户量不算特别大(几十万 DAU),但需求变更频繁,平均每两周就有一次上线。每次发布前都需要在不同机型上进行回归测试,尤其是一些核心流程:登录、搜索商品、加入购物车、支付等。
随着业务模块越来越多,手动测试的工作量剧增。更头疼的是,在一些低端机或小众系统上(比如魅族、锤子旧机型),经常会出现偶现性问题。手动测试难以复现,开发定位困难。我们甚至因为一个兼容性问题导致某地区大量用户无法下单,影响了好几天的销售额。
正是这些问题,让我下定决心尝试搭建一套可落地的自动化测试体系。
遇到的第一个坑:选型难
当时摆在我们面前的选择有好几种:Appium、EarlGrey、Calabash、Robotium、Espresso……对于一个刚开始接触移动自动化的人来说,光看文档就能被绕晕。而且 iOS 和 Android 的技术栈完全不一样,要同时支持两个平台简直像在写两个独立项目。
一开始我们想先从 Android 入手,看看效果。最初尝试了 Robotium,结果发现它已经有点过时,社区活跃度不高。又试了 Espresso,功能很强大,但是对控件识别能力有限,碰到 WebView 就束手无策。再加上项目中有不少 H5 页面嵌套在 native 组件中,Espresso 就完全歇菜了。
这时候,我们决定转向 Appium——它的优势很明显:
- 支持跨平台(iOS + Android)
- 可以混合同步原生和 WebView 操作
- 社区活跃,资料相对丰富
- 可以使用熟悉的语言编写测试脚本(我们用 Python)
不过用了没多久,我发现一个问题:Appium 的运行速度太慢了! 每次启动一个会话,Android 上平均需要 1 分钟左右,iOS 更夸张,甚至要 2~3 分钟。跑个简单的测试流程就得十几分钟,根本没法融入日常的 CI 流程。
而且,脚本稳定性也不太行。有时候同一个步骤执行多次结果不一致,查来查去是 Appium 在查找元素时有时延迟,或者页面还没加载完成就开始操作导致失败。
这明显不符合我们的预期——我们想要的不是另一个“拖慢节奏”的工具,而是能真正帮我们提升效率的自动化手段。
转折点:自己封装中间层 + 并行执行
既然市面上的工具不能完全满足需求,那就只有自己动手了。我们做了几件事来优化整个流程:
1. 针对 Appium 做封装抽象
我们基于 Appium 客户端封装了一套自己的 UI 操作库,核心在于:
- 增加重试机制:查找控件时如果失败,自动重试几次再报错
- 实现同步等待:通过监听特定控件出现或消失,避免硬等待 sleep
- 提供断言封装:简化常见判断逻辑,比如某个按钮是否可见
- 统一报告输出格式:方便后续集成到 Jenkins 或其他 CI 平台中
这样不仅提升了代码可读性,也大大提高了脚本的健壮性。
2. 引入并行执行机制
原来的脚本是一个 test case 接一个顺序跑,效率很低。我们通过参数控制,让多个设备并行运行不同的测试用例。
实现方式很简单:
- 把所有测试用例按场景分类
- 每个设备分配一组彼此无关的用例
- 使用 pytest-xdist 插件实现多线程调度
效果非常明显:原来单机执行一个完整的回归测试要 30 多分钟,并行后只花了不到 8 分钟,节省了近 70% 的时间。
3. 适配多平台问题
在适配 iOS 和 Android 时,我们也遇到了一些细节上的差异:
- iOS 中没有类似
resource-id的字段,需要用 AccessibilityId 来识别控件(这也倒逼我们在开发阶段就加上合适的 accessibilityLabel) - 有些手势操作 iOS 和 Android 的实现方式不一样,我们需要在封装层做平台判断
- 特别是在处理 WebView 时,iOS 必须手动启用开发者模式才能允许远程调试器连接,否则 Appium 访问不到网页内容
为了方便统一管理,我们在配置文件中为不同平台设置了差异化参数,比如:
ios:
driver_type: "XCUITest"
bundle_id: "com.mycompany.shopapp"
android:
app_activity: ".MainActivity"
app_package: "com.mycompany.shopapp"
有了这些基础结构后,整个框架变得清晰可控了。
效果与收益:从“点点点”到“真自动化”
实施半年后,我们对比前后的情况发现:
| 指标 | 手动阶段 | 自动化后 |
|---|---|---|
| 回归测试耗时 | 40 min(单机) | <10 min(多设备并行) |
| 发布前 QA 人力投入 | 至少 2 人半天 | 0 人值守 |
| 异常检测覆盖 | 依赖人为记忆 | 关键路径全链路覆盖 |
| 环境适配问题发现率 | 偶尔漏掉 | 自动触发异常警报 |
最重要的是,我们不再惧怕频繁上线带来的回归压力。新功能开发过程中也能快速添加对应的自动化用例,确保改动不会破坏已有流程。
有一次我们上线前突然发现某个老版本在某些手机上点击不了“立即购买”按钮,自动化回归测试立刻发现了这个问题,而如果是靠手动测试的话,几乎不可能在短时间内全覆盖测试。
一些小插曲与感悟
在整个过程中,有几个关键时刻到现在想起来都还印象深刻。
还记得第一次跑通所有测试用例的时候,我在办公室兴奋地拍桌子,把邻座同事吓得一激灵。那时候真的感觉像是突破了一个巨大的障碍。
也有几次因为 Appium 升级之后接口变化,导致一堆脚本失效。当时我很沮丧,差点就想放弃自动化,改回手动。但冷静下来后还是决定坚持改进封装层,让它屏蔽底层变动,从此以后升级 Appium 再也没出过大的兼容问题。
最让我感触的是,当测试团队第一次看到自动化跑出来的完整报告时,他们的眼神从怀疑变成了信任。那一刻我知道,这套体系终于算是真正落地了。
我的建议与经验总结
如果你也在考虑引入移动测试自动化,以下是我亲身经历后的几点建议:
✅ 从小范围开始,不要追求一步到位
很多团队一开始就想着要实现“全自动 CI/CD”,结果往往因为前期准备不足导致半途而废。我们是从几个核心流程开始写测试脚本的,比如登录、注册、下单这些高频率路径,然后逐步扩展。先跑起来,再追求覆盖率。
✅ 重视控件标识命名规范
这是很多人容易忽略的一点。如果开发没有统一的控件 ID 或 AccessbilityLabel 格式,后期维护脚本会非常痛苦。我们在推进自动化的同时,也推动了前端团队制定了一套命名规则,比如:
login_button
product_name_textview
submit_order_imagebtn
✅ 利用云真机平台降低成本
自己维护真机池的成本很高,特别是 iOS 设备,种类繁多且价格昂贵。后期我们接入了云真机服务,比如阿里云 MQC、Testin、BrowserStack 这样的平台,可以在云端直接执行测试,极大地降低了硬件投入。
✅ 不要把自动化当成万能药
自动化并不是用来替代人的,而是辅助 QA 做更复杂的探索性测试。UI 变化频繁的功能目前还不太适合过度依赖自动化脚本,可以用 mock 数据 + 单元测试的方式来覆盖。
结语:让自动化真正服务于业务
移动测试自动化这条路,说难也不难,关键是要找准切入点,结合实际业务场景来做设计。它不是为了炫技,也不是为了省几个人工,而是为了让我们在快节奏的开发中,依然能保持稳定的质量保障。
回想当初我们也是从“点点点”一步步走过来的,现在回头看,那段时间的坚持和尝试,为我们后续的很多项目打下了坚实的基础。
希望这篇文章能给你带来一点启发,也希望你能在自己的项目中少走弯路,顺利建立起属于你们自己的自动化测试体系。
如果你有任何问题,或者你也正在实践中遇到了类似的挑战,欢迎留言交流。我们一起进步,一起把这个“点点点”的活儿干得更有技术含量 😄

评论 0