聊聊UI自动化
学习做自动化的同学一开始都是偏向于UI自动化,自己这些时间也写过很多:python的,Java的,以及RF关键字驱动的。。。今天就说下UI自动化的一些东西吧,希望对大家有些帮助,少走些弯路。
测试生命中三大幻觉:
[*]今天能发布
[*]明天能发布
[*]UI自动化实现了,测试就可以不用测了
正是第三点赋予了UI自动化测试错误的价值。让UI自动化测试验证UI, 利用图片比较去做自动验证,甚至利用截图定位按钮。真是找死的节奏呀。
UI自动化应该做的事情是什么呢?
1. 验证逻辑而非UI
UI的验证会引入大量的不稳定因素。换句话说,像当年的测试大牛段念说的,你跑过了UI自动化,你就相信没问题了吗?不会相信,原因是啥?因为聪明的你会发现,你验证的东西越多,例如界面的每个按钮,颜色,排布,互联网应用变化最大的就是UI, 你的用例就越不稳定,所以你最终肯定不会验证全部UI。那结果就是”然并卵”了, 你根本不会相信这个用例真的通过了。因此给大家定个UI自动化能做的,验证逻辑(另外一种说法,说这种叫功能自动化)。什么叫验证逻辑?例如验证qq是否登录成功,验证到了好友列表,就是登录成功,甚至有登录成功的日志都可以,怎么稳定怎么行。
2. 代替大量的UI重复操作
简单来说就是UI自动化你要投入5元,只是执行4次,每次赚5毛的话,那你还亏3元的问题。什么时候会大量呢?像手机apk, 编译百个市场的包,每个包要验证核心功能。或者像性能UI自动化监控,同一个用例为了多次采样,也会执行多次。还有每日构建,集成,都可以。关键点就是用次数来增加价值,UI自动化能帮你确保不出死人的问题,如登录不了,登录了又卡死,或者是监控UI之外的其他,如性能。这些都有机会让其价值高于成本的。
最大难点:维护
无间道: 出来混,迟早要还的。 这句话,最好用来说明,为什么自动化测试构造得越快越随便,未来的维护成本也就越大。更甚者,脚本依赖录制得来的,这是找死的节奏。 无数的故事告诉我,很多UI自动化都是死在一开始就写或者录一堆脚本,结果每天都要花大量时间排查错误,错误有脚本错误,有功能的变更,有bug,甚至问题是随机出现的,但是无论你的问题或者是功能的问题,反正你排查错误的时间是花进去了,哪怕你不用改脚本。
所以这里看来,要解决维护的难点,终极招数就是不要碰UI自动化。其实很多大牛都是说不要做UI自动化的,或者这个事情不是最高优先级,但是现实是,大家都做了,优先级还不低。所以当然不说不做了,要做就只能要狠狠地干一场,要成功,不要失败。
记得有句话是这样的:如果你不喜欢做一件事,那么就去努力的做好它。下面给大家有两点建议,一是策略,二是技术。
策略上:维护成本的控制,脚本要慢慢上,先做核心的BVT,人均维护的脚本1~2个,定目标,如稳定运营1个月,后面增加的脚本要在测试环境稳定跑上一周,才能切换到正式环境。 组织培训,知识分享,分享写自动化遇到的坑,沉淀最佳的实践,让大家知道写UI自动化也是在自我提升,而不是简单的工作任务。
技术上:降低维护成本的方法如下
脚本里不要有坐标,图像识别这些,想都别想,想都别想,想都别想!这些都是不稳定的因素。
脚本里不要有sleep。sleep就是UI自动化的稳定性的克星,绝对不能有。一方面,如果帮助建立或者直接使用UI自动化测试等待界面稳定的阻塞方法,例如waitForIdle,等待控件出现和消失的方法,如waitForInvisiable之类的。另外一种,就是封装一个timeout的类,里面包含重试和sleep的策略,让脚本直接使用。反正,不要单单看到sleep。
要用脚本要基于面向对象。脚本不需要编译,调试方便,学习门槛低,像python,能使用的库也丰富。所以自动化测试最佳的使用Python,再配合pydev、pycharm,用起来还是很舒服的。而说到面向对象,它有个作用,就是通过隔离变化来提升代码的可维护性。说多了,可能你都不明白,
我举个例子来说说, 用了面向对象的UI自动化脚本的样子(python的哈)。
app = Application("XYD")
loginPanel = app.launch()
buddylistPanel = loginPanel.login("18223292304","123456")
aioPanel = buddylistPanel.findAndOpenAIO("18223292304")
aioPanel.sendMsg("hi")
好,这个伪脚本,有什么特点呢?对,没有见到控件。控件要封装到界面类里面(RF所说的关键字)。具体一下说,自动化脚本的隔离变化基本上可以分四个层次:
[*]a. 用例逻辑,通常有个用于继承的TestCaseBase, 用来封装用例的逻辑,类似teardown, setup,run之类。
[*]b. 业务逻辑,通常就是继承TestCaseBase,用例实现的本身。封装业务逻辑的变化。
[*]c. 界面逻辑,通常就是界面类,例如上面的LoginPanel。隔离了控件与业务逻辑,让控件位置,ID的变化,可以控制在界面类中。
[*]d. 控件驱动,通常就是基本的获取控件树,检索控件。封装控件获取方式。
控件定位要用类似XPath的方式。这种方式的好处就是方便阅读,把复杂的位置描述封装到一条短短的字符串里面了。(有些朋友误会了,是XPATH,是类似XPATH的东西,但是要把他比较复杂的部分去掉,只支持属性,节点的简单定位就行。不然跟正则表达式一样,又是一对学习成本了)
通过分Step的脚本化繁为简。UI自动化脚本都有个特色。长~!一个脚本通常我们希望验证好几点,登录,打开聊天窗口就不容易了,因此除了验证发消息,我们还希望可以发图,发表情,那么这个时候,最好可以把用例分割成几个Step。出了问题,就集中排查某个Step的日志就OK了。补充一下,大家肯定想个一个问题,每个用例都要独立的,要互不影响,重新登录,为了稳定,多补点时间我不在意,但是现实你有发现这些时间会增加用例出错之后的修复,验证的时间成本。所以“分Step”无疑意思是给大家一个合并用例来提升用例执行速度,但是又不影响用例与用例之间的独立性。这个也是为什么我提出数据分离,模块化脚本的原因,可能一开始大家会很痛苦,越写就会发现越简单。。。
不要再给UI操作/验证本身压力了。例如输入文本这些操作,也没有必要用键盘事件来触发,如果你是注入方式的,获取到控件对象,直接setText吧,这样会稳定很多。还有端到端的UI自动化,如QQ发消息到另外一端的QQ的测试,我们就可以利用网络协议,发送消息,另外一端用UI验证接收消息。
定时重启手机和电脑,出错的用例再跑一次,可能会帮助回避一些问题,可以做,但是不能以此来麻木自己对错误的敏感的感觉。
稳定你的环境,这些环境包括网络,系统,账号资源,电脑/手机。
[*]a.网络, 假如我们的UI自动化是验证功能逻辑的,那网络就一定要被牢牢地控制,独立的路由器,并且监控着网络情况,如果存在严重的丢包和断连,这信息一定要及时同步出来,甚至可以自动控制你的用例,在网络差时暂停,网络回复后再跑。
[*]b. 系统, 系统经常有各种更新的弹窗,特别是IOS。利用网络,屏蔽这些无用的推送把。android则是找个稳定的ROM。
[*]c. 账号资源,有很多软件账号资源都是不能重用的,或者重用了之后,用例之间会相互影响。这里需要有账号资源池的概念,类似SVN, 通过CGI, 来取了资源,可以加锁,还回去,再解锁。
[*]d. 手机与电脑,肯定不能长时间运行,不然他们也会发脾气。所以定期重启手机和电脑,似乎是必不可少的一步。
UI自动化测试的未来
有很多人问, UI自动化应不应该投入,有没有前途?这个问题没有绝对的,要看项目的类型,像做Android手机的,因为项目相对来说比较稳定,CTS本身就有一定的用例量,几千个UI自动化测试,都能维护过来,而且通过率极高。做前端应用的,像我们PC QQ,开发在控件唯一标识的问题上,给予了不少支持,因此用例的量和稳定性也是非常高。说虚一点的,如果这个事情至上而下都是支持的,想做的,投入的方向没有错,价值认识正确,肯定是有积极的产出的。另外,UI自动化是测试生来无法回避的一种能力,可以不依赖他,但是你需要他。
That’s all:
UI自动化是一种能力,常常无法回避。
UI自动化会给人幻觉,要看清现实与价值。
UI自动化最适合一句话,喜欢是放肆,爱是克制。而克制是UI自动化能发挥作用的关键。
图像识别新势力:airtest就是和楼主说的理念有点出入,他的核心一面就是单纯的图像识别。
本人也是粗略的了解了一下,对于airtest,我也觉得做UI入门还可以,但实际项目可能会有点难度(没有实施过,没有发言权,这句是废话)
对于现在普遍的敏捷开发模型来说,UI自动化确实不太友好,但是也不是说没必要或者完全没作用。因为如果单纯的使用接口来做那不符合大多数软件的应用场景,毕竟,
软件是要为人服务的(交互才是王道)。所以UI测试对于大多数来说不可缺少,这样就回到了最初的矛盾,也是自动化出现的原因,如何去代替大量的甚至是当时的全面UI
测试运动,显然,UI自动化是一条路。
UI自动化也不是向很多人说的那样查,还是要看被测系统和测试经理对测试的理解程度,有些很稳定很稳定的用UI自动化来做的确是能轻松不少的。这一方面我觉得不是
简单看看技术文章能掌握的,这是大量的测试经验和测试嗅觉自然而然体现的。
另外,现在很多的开源自动化测试框架,大家用的很多也很好,但是如果在开源的基础上扩展开发一些测试管理的功能会更好,也更对得起"开源"一词 支持下
页:
[1]