本文转自来自地球的专项测试 (opens new window),经过排版整理有删改,技术上降低维护成本的方法加入了自己的总结。

# 如何体现真正价值

让 UI 自动化测试验证 UI, 利用图片比较去做自动验证,甚至利用截图定位按钮,真是找死的节奏呀。 现在我带大家认识下它的真正价值。

# 1. 验证逻辑而非 UI

UI 的验证会引入大量的不稳定因素。换句话说,像当年的测试大牛段念说的,你跑过了 UI 自动化,你就相信没问题了吗?不会相信,原因是啥?因为聪明的你会发现,你验证的东西越多,例如界面的每个按钮,颜色,排布,互联网应用变化最大的就是 UI, 你的用例就越不稳定,所以你最终肯定不会验证全部 UI。那结果就是 "然并卵" 了,你根本不会相信这个用例真的通过了。因此给大家定个 UI 自动化能做的,验证逻辑(另外一种说法,说这种叫功能自动化)。什么叫验证逻辑?例如验证 QQ 是否登录成功,验证到了好友列表,就是登录成功,甚至有登录成功的日志都可以,怎么稳定怎么行。

# 2. 代替大量的 UI 重复操作

简单来说就是 UI 自动化你要投入 5 元,只是执行 4 次,每次赚 5 毛的话,那你还亏 3 元的问题。什么时候会大量呢?像手 Q, 编译百个市场的包,每个包要验证核心功能。或者像性能 UI 自动化监控,同一个用例为了多次采样,也会执行多次。还有每日构建,集成,都可以。关键点就是用次数来增加价值,UI 自动化能帮你确保不出死人的问题,如登录不了,登录了又卡死,或者是监控 UI 之外的其他,如性能。这些都有机会让其价值高于成本的。

# 最大难点:维护

无间道:出来混,迟早要还的。 这句话,最好用来说明,为什么自动化测试构造得越快越随便,未来的维护成本也就越大。更甚者,脚本依赖录制得来的,也是找死的节奏。 无数的故事告诉我,很多 UI 自动化都是死在一开始就写或者录一堆脚本,结果每天都要花大量时间排查错误,错误有脚本错误,有功能的变更,有 Bug,甚至问题是随机出现的,但是无论你的问题或者是功能的问题,反正你排查错误的时间是花进去了,哪怕你不用改脚本。所以这里看来,要解决维护的难点,终极招数就是不要碰 UI 自动化。其实很多大牛都是说不要做 UI 自动化的,或者这个事情不是最高优先级,但是现实是,大家都做了,优先级还不低。所以我当然不说不做了,要做就只能要狠狠地干一场,要成功,不要失败。下面给大家有两点建议,一是策略,二是技术。

# 策略上

维护成本的控制,脚本要慢慢上,先做核心的 BVT,人均维护的脚本 1~2 个,定目标,如稳定运营 1 个月,后面增加的脚本要在测试环境稳定跑上一周,才能切换到正式环境。 组织培训,知识分享,分享写自动化遇到的坑,沉淀最佳的实践,让大家知道写 UI 自动化也是在自我提升,而不是简单的工作任务。

# 技术上

降低维护成本的方法

  1. 不要硬编码,脚本里不要有绝对坐标,图像识别这些,这些都是不稳定的因素。可靠些的方法是获取相邻控件的坐标,然后减去或加上一个比较小的 px 值,再点击计算后的相对坐标即可。

  2. 不要依赖偶然性编程,直接的 sleep 就是 UI 自动化的稳定性的克星,绝对不能有。可以封装一个 timeout 的类,里面包含重试和 sleep 的策略优化等待。

  3. 使用 PageObjects 模式,整体思想是分层,让不同层去做不同类型的事情,让代码结构清晰,增加复用性,实现用例和元素分离。

  4. 动态界面静态解析,有那么一些界面通过 UI Automator Viewer 抓取是会报错的,通过直接点击元素的方法速度也很慢,可以通过解析 Source 的 xml 获取到 bounds 计算相对座标并点击,这样操作更稳定更快。

  5. 通过分 Step 的脚本化繁为简,UI 自动化脚本都有个特色~长!一个脚本通常我们希望验证好几点,登录,打开聊天窗口就不容易了,因此除了验证发消息,我们还希望可以发图,发表情,那么这个时候,最好可以把用例分割成几个 Step。出了问题,就集中排查某个 Step 的日志就 OK 了。补充一下, 大家肯定想个一个问题,每个用例都要独立的,要互不影响,重新登录,为了稳定,多补点时间我不在意,但是现实你又发现这些时间会增加用例出错之后的修复,验证的时间成本。所以 “分 Step” 无疑意思是给大家一个合并用例来提升用例执行速度,但是又不影响用例与用例之间的独立性。

# 文章参考

浅谈如何提高自动化测试的稳定性和可维护性 (pytest&allure) (opens new window)
UI 自动化到底要不要用 Page Object 模式?(续 - 深入了解 PO 模式,并改造 PO 模式) (opens new window)
小心!做 UI 自动化一定要跨过这些坑 (opens new window)
Airtest 增加了观察者函数 (opens new window)