转载请注明出处:https://lizhaoxuan.github.io
前言
这篇博客,我会站在小微团队的角度,介绍一下我对App自动化测试的一些看法。在帮助你降低对App自动化测试的期望的同时说服你开始实践App自动化测试。
App自动化测试一直是小微团队很少会去涉足的领域,在互联网快速迭代这个大场景下,随着业务发展,回归压力逐渐增大。相信每次因为回归覆盖不足而导致线上事故,懊恼郁闷到要砸桌子的绝对不止我一个。
一般情况小微团队的测试包括回归测试都是人工进行的,一些偏离主流程却又比较关键的业务往往是人工回归测试容易遗漏的。人力有穷尽,这个时候自动化测试这个念头就从你的脑袋里冒出来了,然后就是去研究嘛。但可能最终也就止步于研究了。不谈自动化框架的搭建,种种细分的边界case,一个必然很繁琐的东西想一想就更繁琐了。如果你是App开发,本来业务开发上的人手就不是很充足,再去开发自动化脚本,有心无力!如果你是测试,每个迭代的业务需求测试就填满了你的排期,更何况承担的可不只是App测试任务。作为小微团队,自动化我们也想,但我们没有资源……
首先我们要明白App自动化测试并没有你预想中的那么强大,但如果你像我一样面临着回归测试痛点,它绝对可以满足你的需求。没有那么强大,所以也没有你预想中的那么复杂,同时它的参与者也绝不只应限制在Tester或Developer上,所以在资源上你可以有更灵活的调配。当然,自动化测试是一个长期的过程,它的未来,也绝不仅是回归……
最后我会为你安利一款偏冷的自动化测试工具:Calabash。并奉上Calabash入门教程博客和一点我的使用心得。介绍Calabash,是因为Calabash的特性在我个人看来更为适合资源紧缺的小微团队。
大话App自动化测试
仅代表个人观点,见识还浅,欢迎多多打脸。
现状
先说点大家都知道的。以Android为例,从2010年开始,Android开发环境以及其迅猛的态势发展到今天,几近趋于成熟,开发者的目光早已不在局限于这单一的开发平台,开始寻求Android,iOS在开发上的统一:ReactNactive,WEEX,H5……
开发环境已经成熟,但移动客户端的测试环境却有些滞后。这中间的几座大山是很多团队正在面对且驻足的:
1.App测试不像服务端测试通常只需对数据本身进行验证即可,App涉及到界面展示及交互,自动化识别难度大。
2.互联网企业一直都在追寻快速迭代,且App直接对接用户,App的界面与逻辑变更更是家常便饭,编写自动化测试脚本的稳定性很差,可能设计对界面的一次改动,之前与这个页面挂钩的所有脚本就都废掉了。
3.Android iOS 双平台,web页面。多平台的情况下想要依靠一套代码进行自动化测试几乎是不可能的。再考虑需要经常变更,你懂得。
4.比起人工来说,自动化测试可能需要为种种边界case编写很多的脚本。同比人工测试,可能需要的只是事先设计几个场景,其他的异常边界case通过测试中人为观察就好了。自动化测试成本倍增!
所以往往一个完善的移动自动化测试环境需要一个庞大的测试团队支撑,但一个庞大的测试团队只有大公司才能负担的起。移动的自动化测试,一直都在被中小型的创业公司所忽略。小型公司开发自测了事,中型公司依靠测试人员人工操作进行验证。
自动化测试真的对于小微团队紧闭大门吗?
Just do it
上面说的这些现状只能说是难题,也许现在讨论解决这些问题还早了些。我觉得你有些东西还没确定清楚,要不然先跟着我的思路走一走?等下面一些事情都想明白了,也许这些问题能避也就避过了,需要硬上的,也有足够心理准备了。
1.设定阶段计划试错
其实让小微团队面对自动化测试左右徘徊最大的一个问题就是:投入产出比!
很难去预估实行自动化测试后,在页面频繁变更与脚本的开发和维护之间,测试或开发人员会不会陷入泥潭。
但纸上谈兵永远也不会有结果,其他大公司的借鉴意义也不是很强,因为这涉及到团队、资源分配、业务变更频度、测试工具、脚本开发的解耦程度等等。不过自动化测试是一个必然的趋势,所以行动是最首要的!
你的团队目前到底适不适合,只有试了才知道。不妨先设定几个阶段,然后用第一阶段试错:
阶段1:抽出一个人一个迭代的资源完成主流程业务的自动化测试case,试运行两到三个迭代,并在这期间增加主流程异常case。利用这三个迭代来评估后续发展可行性!
阶段2-(阶段1成功度过):如果你认为阶段1的状态还不错,那么在维护阶段1成果的基础上从剩余业务场景中按照业务关键程度、变更频率来选取一个新的业务,以一个人一个迭代一个业务的节奏编写自动化测试case!
阶段2-(阶段1过度失败):当然,经过三个迭代的评估,随着异常case增多,同步维护难度越来越大,你可能认为实行自动化测试的成本过大,但也不要轻易放弃这三个迭代的成果。请先利用编程思维检查所有的测试脚本,是否有抽取相似代码,封装特定View操作,抽离与业务无关指令的可能。同时考虑利用全组资源就此维护这套主流程自动化case。直到将来资源充足或找到更好的替代方案后进行阶段3或重新阶段1。
阶段3:大概在5~8个迭代后,你成功撑过了阶段2,说明你的自动化测试环境已经步入正轨,那么这个时候可以按照团队资源情况适当加快自动化case覆盖率!
利用一人一个迭代的资源进行试错,相信是你可以接受的一个损失。当然,先不要急着做,你也许只是决定了要进行自动化测试,但还是要定一些详细的计划和一些思想、实际行动上的准备!
2.确定明确且简单的目标
有了大的计划,还要明确具体的需求,可选的需求大概有这么些:
1.黑盒测试还是白盒测试
虽然是UI自动化测试,但也可以分为黑盒或白盒,这个取决你想要的测试精密度,也就是在这个时候,可以初步确定要使用什么自动化测试工具。比如通常我们为了可以双平台会选择Appium这种可以跨平台的测试工具,但假如你有很高的测试要求,以Android为例,建议你使用Android官方推荐的测试框架:Espresso,直接在Android工程项目中写Test。
这样说出来好像谁都明白,但如果你不能在前期就明确你的需求,可能会在后期带来很大的困扰!选择Appium,因为是黑盒,遇到某些特殊的场景或需求,导致个别case无法测试。或者选择了Espresso,但后来发现其实并没有那么精密的测试需求,导致后期无法跨平台或者认为Espresso编写成本过高,还很难移交给测试团队。
2.前端UI还是整体业务
举个例子,抢单并且进行配送这个场景。发现一个订单并点击抢单,然后进行取餐,最后完成配送这一套只能用肉眼观察到的UI层操作,我们暂定为这是前端UI逻辑。但在这一系列操作背后订单状态流转引起其他数据变动,比如:钱包数据变更,活动奖励数据变更,欺诈单判定等等这个范围,就属于整体业务范畴了。
而我们需要现在确定的,就是你想要达到的测试期望是UI测试,还是整体业务测试。这直接决定了你测试脚本的复杂度。而我的建议是仅测UI逻辑,也是我想让你降低期望一个点。
先确定一个明确且简单的目标,然后一头扎进去。如果想的多了,困难也就多了,最后可能也就只是想想了,这就是下面紧接着要说的点:降低期望!
3.降低期望
在人工(对着手机点点点)测试的环境下,我们通常都是通过操作App进行各种case验证,只要操作app验证通过了那基本可以确定前后端没什么问题了。但这个前提是人工验证是人脑加肉眼,它会有更准确的主观判断。
涉及到前后端交互会增加极大的复杂性,你的测试case不会无限多无限精细,但作为人脑你可以在有限的case执行中发现更多不符合常理的bug:文字不合理的折行,不准确的数值显示,按钮颜色不对,Toast展示数量有误等等等。自动化测试会死板的跟着你写的脚本走,你能保证你的case覆盖到了所有了吗?
这也是谈到自动化测试,好多人都会抛出的一个疑问,那么多异常case怎么写啊,想想都累,考虑一下投入产出比要不还是人工测试吧。
首先要明确的一点,前后端自动化测试一定要分开,一套解决不了问题,这样在前端测试中可以忽略很多的case。
另外自动化测试是一个与项目成长一样的长期过程,自动化完全代替人工依然还需要走一段时间,你不要想着一步到位。
依然还是会有很多的case要写对吧?资源不够我们可以先跑通主流程再说,跑通主流程也就意味着脚本依赖(环境搭建,view定位)已经较为成熟了,其他异常case脚本对着主流程脚本修改即可,这个我们慢慢来嘛,而且这个时候你就可以放开给别的开发或测试让他们照猫画虎了。这也就是我们上面说的阶段1。
如果这些问题不能想通,你会发现在App自动化测试条件有限的情况下,并不能实现你想要的结果,从而迫于压力而放弃了。说服自己降低期望!
- 降低期望,先以回归为目标
- 降低期望,前后端自动化测试都要有,一套解决不了问题
- 降低期望,客户端自动化测试限制依然很多,人工测试验证不能全部丢下
- 降低期望,一口吃不成个胖子,自动化测试也是需要慢慢迭代完善的,先跑通再关心验证异常case。快速迭代,逐步完善
4.术业有专攻
也许你的团队里是开发或者测试中的某一方无法承受压力,从而开始探索App自动化测试。
开发去做自动化测试的优点在于因为有更丰富的开发经验,测试环境的搭建更为熟练,且因为是自己写的代码,会更了解风险点在哪里,能写出有针对性的case。测试去做自动化测试的优点在于发现更多的边界场景,写出更全面的测试case。
在自动化测试上,开发和测试各具不同的优势,但同时这也是对方的劣势。
测试case一定要越全面越好,而且自动化测试本身就是一个工程项目,在写脚本时,如果更多的考虑一些编程思想,合理的耦合和解耦,将会让之后的脚本编写更便捷。
所以,非常不建议自动化测试完全单独交给测试人员或开发人员来负责,最好是一种紧密合作的关系。同时也是应对资源不足的一个解决之道。虽是测试,但有开发的加入,会让测试工程朝着更优的方向发展。
5.一个巴掌拍不响
首先再次明确我的一个观点:在没有足够的资源的情况下,移动客户端自动化测试,主要针对的应该是回归测试。
自动化测试相比起人工测试,是非常死板的,那么就需要非常“死板”的数据支持.如果是App开发(就像我)去做自动化测试这件事,难道所有数据我都要mock一遍吗?虽说前后端自动化应该分开,前面也说了应该只关心前端逻辑。但一定还是要在真实的服务环境(测试环境,非生产环境)进行测试。
mock数据过于死板,很多case可能就无法验证了,比如注册场景,要验证注册过的账号无法再注册时的异常提示,mock数据显然较难兼顾正常注册和异常注册两种。而且在真实环境中测试,万一测出来一个后端bug不挺好么。
而且,手机淘宝这样完全2C的应用直接在生产环境测试好像没什么太大问题,但像蜂鸟配送这样半2C的应用来说就比较尴尬,直接去抢线上单明显不可能,那么在测试环境这个订单谁来发怎么发呢?
所以这个时候你就不能自己单干了,去找测试同学,看能不能搞一个配合自动化测试的测试环境,拿抢单来说,我希望这个环境上永远有好多单让我抢。我就是抢单的app,没单我还玩什么。
如果测试同学搞不定,那么就去拉后端的同学啦,我相信为了项目越来越好,他们是不会拒绝你的。
自动化测试,不仅是自动化测试工具就够了,同样还需要测试环境的支持。
小结
其实说了这么多,就是想要你降低期望,并付诸行动。
App的自动化识别和多平台自然会有大批的自动化工具帮你实现,而学会降低期望的同时也会降低脚本开发和维护的难度。
难道你还在纠结细分case太多的问题?先放一放又如何?反正你都裸奔这么久了,穿裤子不也要先穿个裤衩才行么,裤子慢慢来!
或者你依然徘徊在投入产出比的问题上?买衣服不也要先试穿才知道码号的吗?
OK,下面我们聊聊这个裤衩,和怎么穿这个裤衩!
测试工具
做好了思想工作,具体实现还是需要选择一个具体的测试工具,工具没有好坏,只有适不适合。
Calabash是我个人建议小微团队使用的测试工具,因为其兼具门槛低、跨平台、脚本维护容易的特性,而这正是小微团队最急需的。
且其BDD(行为驱动开发)的思想虽然有点乌托邦,但从远瞻的角度来看,实现测试脚本先于程序开发编写的这种先进项目管理可能性也大于其他工具,让测试不仅仅是测试!
下面我会对Calabash的特性做一个简单介绍,详述其优缺点,你可以根据自身团队经验进行选择是否使用,如果喜欢,文末会附上Calabash由浅入深的入门教程,加之更详细的特性介绍和我自己的使用建议。
Calabash
谈Calabash前,先要交代清楚Calabash是啥。
Calabash的核心是Cucumber,Cucumber是一个能够用自然语言编写实例的协作工具,其核心思想是行为驱动开发(BDD),回归测试是其自然而然的副带结果。你可以简单的理解为Calabash-android 或 Calabash-iOS是在Cucumber上进行了一次扩展,从而可以对Android或iOS进行自动化测试。
在解释一下BDD,我从网络摘了一段介绍:你可以在Cucumber中编写用户场景,让它表现出业务规则而不仅仅是UI功能。这样你就能够让业务分析师加入这个过程,在编码工作开始前编写场景。程序员们就能够按照这个清晰的规范进行编码工作了。这种方式就是行为驱动开发(BDD)。
OK,关于BDD我们就此打住,毕竟还是很未来的事情,下面我们聊点实在的。
Calabash与appium,Espresso类似,都是通过脚本去操作界面,作出点击、滑动等操作,同时可以对界面的上UI组件进行一定识别。run起来就是那么回事,模拟控制手机。主要是脚本的编写上不同,我们来看一下Calabash的脚本,相信我,爱上它,就从看到它脚本开始:
1 | Feature: Login feature |
我觉得我不需要再解释这脚本的含义了,这就是大白话!!
Calabash最大的魅力在于,将难以理解的编程语言转换为谁都可以看得懂得自然语言。从而降低学习门槛和维护难度。
特点1:极高的可读性,可读性越高的测试脚本,意义越大。当测试脚本的编写先于或与开发同步时,测试脚本也可以成为开发过程中的设计文档及参考手册。
在可读性非常高的基础上,其编写难度也变得非常的低。特点2:语法简单易懂,谁都能写。
同时可喜的是,这个代码同时支持Android 和iOS,web也有一定的支持!RN就更不用说了,跑起来的RN就是原生代码!WEEX还要再考察考察~在合理的解耦与耦合的情况下,Android 和iOS只需提供一套各自的View定位封装即可共用一套场景case脚本。特点3:支持多种平台,代码复用性强。
一段使用自然语言编写的脚本,其底层当然要费一番功夫。上面我们看到一段测试用例是使用Calabash预定义的Steps写的一段测试用例。
而这些大白话一样的Steps的实质是这样的:
1 | Then /^I press "([^\"]*)"$/ do |identifier| # ---方法名 |
很傻瓜的解释一下:你可以很简单的认为上面这一段是一个函数、一个方法。
第一行就是一个自然语言夹杂着正则符号的方法名,方法名随便起。第二行是用Ruby实现的方法体。
不要被这段代码吓到,在大部分时候,你都不需要接触到这些大白话的具体实现(Ruby语言),而是直接用大白话写小作文就好了。
预定义的Steps肯定不能满足我们的需求,所以Calabash灵活的支持不同程度自定义steps,样子大概就像上面那样,你可以简单理解为Calabash支持不同程度的,代码到自然语言的转换。最大程度的满足业务需求。
正是这种灵活的转换方式,让我们有了更多的想象:
特点4:Steps的开发与脚本的开发解耦分离,降低入门门槛,容纳更多的脚本开发人员
再简单解释一下:先让一部分(实际情况可能是一个)人学起来,写出一个个大白话似的Steps。再接纳另一部分人进来,比如其他的开发或测试人员,甚至是产品经理!直接用这些大白话写测试case,熟悉了之后有想法的话再去学自定义Steps。甚至产品都不需要学自定义Steps,给开发提需求好了,当你有一个非常丰富的Steps库的时候,你所烦的无穷无尽的边界case,不过就是全民小作文~
特点5:自定义语法糖
Steps的方法名定义完全自由,在带来可读性提高的同时也降低了Steps的记忆和脚本编写速度。但这其实完全依赖于你定义的规范,你完全可以自定义一套符合大多数人习惯的语法糖,从而在保证可读性的同时固化大部分指令格式,提高Steps的记忆和脚本编写速度。
还有哦,如果你一直抱怨现在正在使用的某种语言的某个语法多么的没人性,使用体验糟糕透顶!现在好了,做好开发一套属于自己的语言的准备了嘛?
特点6:维护简单,我不知道小作文维护起来有什么难的~
特点7:case也有设计感,不在那么枯燥
在加一个最起码我觉得很兴奋的特点,考虑复用的话,自定义的Steps就要考虑与业务的解耦问题了,有的要解耦有的却要耦合一点。而且如果为了最小程度修改代码从而保证Android iOS在代码上通用,Android和iOS的开发上就会有更多的交流,测试脚本的编写也会有更通用的设计。这里面就有设计的快感了。
特点8:除模拟事件以外,Calabash还支持各种hook,如App生命周期的hook
特点9:丰富的元素定位辅助方法。
App自动化测试一个普遍的痛点就是元素定位,Calabash有非常多的元素定位辅助方法,且都较为简单且无脑。
最后我们在看一个从网上摘下来的一段Calabash脚本:
1 | Feature: 登陆 |
完全纯中文的脚本编写有木有?是不看起来屌屌的~恩,虽然博主自身并不建议这样纯中文的step定义,我们就看看,你只要知道Calabash很强大就行了。
最后我们总结一下Calabash的大方向的优点:
- 极高的可读性
- 语法简单易懂,学习门槛低
- 一种语言支持多种平台,代码复用性强
- Steps的开发与脚本的开发解耦分离,降低入门门槛,容纳更多的开发
- 自定义语法糖
- 小作文维护简单
- case也有设计感
- 除模拟事件以外,Calabash还支持各种hook,如App生命周期的hook
- 非常多的元素定位辅助方法
- 对代码无侵入性,纯黑盒测试。
- 用Calabash搭一个自有的云测平台可行性很高
这只是大方向的几个优点,文末会奉上Calabash的入门文章,更详细的介绍Calabash的各种特性,利用这些特性,你会发现Calabash有太多的想象。
Calabash缺点
说了那么多优点,缺点当然也是有的啦~我们吐槽一下
资料、Demo稀少
Calabash大概有五年以上的历史,最早的first commit是2012年2月份,对于一个技术工具来说,这已经可以算是很老了,但Calabash依然是一个小众产品,然后导致的问题是资料非常非常少……官方Github只给了很简单很基础的API,还基本没有Demo,(官方Demo就几行代码~)
资料少也意味着后面有很多坑需要自己往过趟,不过有了文末的入门教程,快速上手应该是没问题啦~
我大胆的怀疑了一下Calabash小众的原因,可能大厂还是更钟爱appium这种主流测试框架,毕竟语法复杂也意味着功能强大,而小厂呢,相比起维护一套自动化测试框架,不如就手点点人工测试好了,所以Calabash这样的,就处于一个很尴尬的位置了(这篇文章不就是让你破解这种尴尬的嘛!)
不支持跨进程
Calabash底层是Robotium,Robotium不支持跨进程操作,所以Calabash也不支持。当你跳出当前测试App时,calabash便无法响应并做任何操作了。
在个别需要跨进程调用业务较多的App中,这个点是很痛的,甚至基本上就可以放弃Calabash了。
以蜂鸟众包为例,需要跨进程的业务有分享和拍照(拍照调用了系统相机),分享对于蜂鸟众包来说是一个很边界的业务,暂不讨论,但拍照影响到了主流程。
不过如果修改拍照为自定义相机,而是不调用系统相机的话,将不会存在这个问题,并且可以解决不同手机系统相机样式不同,脚本需要进行兼容的困扰。所以即使是为了测试而对业务代码做了这种程度的改动,也是值得的!
另外通过最近研究发现,Calabash支持跨进程似乎也是有希望的!Espresso实现跨进程操作的方式是调用了uiautomator的API。而Calabash作为开源项目,想要修改其源码也是完全OK的。 以Android为例,其内部核心是通过java调用Robotium API实现的,所以我们只要修改其源码调用uiautomator的API即可实现跨进程。恩……实现思想是这样的,只是不知道官方为什么没有这样去做,具体情况还待研究……(2015年底之前Calabash相关的博客中可以很容易的找到修改其源码进行功能扩展的博客,但Calabash在2015年年底将Calabash的源码抽离到了另一个项目中,所以这些博客中提到方案便无法使用了,后续的具体实现方式还待研究,详情会在文末的教程中提到)
不够严谨的自然语言
可能大部分人会对Calabash这样的自然语言抱有怀疑,认为Calabash这样Cucumber风格的语言(就是上面的我们看到的测试脚本)不够严谨。无法向代码那样简练且规范严格,在某种程度也降低了编写速度,且非常不够严谨易错度高!
首先要澄清一点的是,Java、Python等隶属编程语言,而Cucumber风格的脚本更倾向于是一种描述性语言。他们是两种不同的领域。
所以不能站在编程语言的角度去要求Cucumber风格的脚本的严谨程度,而“严谨”也不过是作为编程人员的一种惯性思维。
而从记忆与编写速度考虑,还记得我们上面曾说到的语法糖吗?不恰当的定义Steps确实会导致这样的问题。举个例子吧
#我跳过欢迎界面
Then I skip welcome page
#我完成登录操作
Then I have finished the login
上面是两个滥用自然语言特性的自定义操作。如果你的所有测试脚本都是这样写的,虽然读起来没有问题,但写起来就完全离不开文档了。下面看一下较为建议的写法:
#我跳过欢迎界面
Then I pass "welcome" scenario
#我完成登录操作
Then I pass "login" scenario
两个Steps的实际含义其实仅只是直接通过某种操作,如果我们规范的定义适合自己的语法糖,非常杂乱的脚本将变得很有规律可循,保证可读性的同时你只需记住几个特定的指令,从而提高脚本编写速度。
当然,确实是因为Calabash过于宽松的语法,导致这个致命的缺点需要通过严格的管理进行约束,稍有不慎会埋有祸根。所以这确实是Calabash的缺点之一。
End
最后,虽然我个人建议使用Calabash,但对于小微团队,合适的才是最好的! 资源紧张情况下想要实行自动化测试,我的建议是在提高人效的基础上调动更多的人力来分摊压力。那么这对低学习门槛和低推广成本的要求就会很高,所以学习门槛和推广成本应该是你选择自动化工具最需要考察的点。
正是因为Calabash的特性非常契合这两点,我才会极力推荐,同时如果你想在未来的某一天尝试一下BDD这种思想,或者想让产品经理参与到这个环节做一些尝试,同样是非常建议使用Calabash的。当然如果你有较为宽松的资源、或者追求更加工程化的自动化测试,还可以选择Appium这样主流的测试工具。还是那句话:合适的才是最好的!
最后,奉上Calabash的入门博客: