首先我们需要先想清楚做自动化测试核心目标是什么? 质量?效率?还是都要?答案肯定是都要,但是在某一个时间段肯定只能择重点在一个方面。那么如何实现既能提高质量,又能提高效率? 如果只能选择其一那么目前现阶段优先考虑哪个?
质量是有成本,而且往往这种成本很难用收益来衡量。目前现阶段我们做自动化测试更多是预防,这里就会存在一个难点,预防的成本与收益的不可预估性。比如:我们投入了大量的自动化测试脚本开发,但是无法证明这样做了之后质量越来越好,效率越来越高,这是不一定的。因为有可能随着业务的变化、架构的变化软件本身就在腐化,只是通过加强质量预防,减少或缓解了这种腐化。通过投入 “成本” 预防事故发生的可能性,这件事成本是可估算的。但我们无法估算当事故出现之后需要花费多少 “成本” 才能解决这个事故。预防本质是在做一个兜底,其思想是假设未来出现这个事情我们可以提前花费一定的” 成本 “去兜底。同样一个 P0 级别的事故,10 分钟验证和 100 分钟验证,事故带来的影响是截然不同的。最终其实就是我们花费一个 “可定” 的成本去防范未来可能出现一个不可预估性事故带来的影响。就像我们无法证明去年有 100 个线上缺陷,今年由于引入了自动化测试线上缺陷减少了 50 个,这个是不一定的,也许是因为今年研发本身代码的质量提高了。一个缺陷的诞生不能简单粗暴认为是单个 “因子” 带来的直接结果。但是自动化测试可以保障已经被自动化覆盖的缺陷永远不会重现。
效率提升也是有成本的,但是相对与质量的成本,效率的提升的可预估性会高一些。通常效率的提升肯定是当我们做出一些 “改变” 之后带来的结果,那么我们可以通过衡量做出 “改变” 的成本与最终得到收益的周期是否符合预期。这个是一个投资回报比计算的过程,但是软件研发因为对人的依赖性太强,所以这种投资回报比也只是理想情况下的预估,因为随着软件的变化、复杂性的提高维护的成本也在增加。所以需要经常对软件架构进行重构,减少技术债。没有自动化测试作为保障重构就是灾难。
测试工作的本质目标就是通过投入最小的成本,获得对软件质量最大的保障。我们可以通过推理和估算的方式设想一下自动化测试实施之前和之后,带来的改变是什么? 。以外卖场景举个例子:用户通过登录 App,挑选自己心仪的商品,加入到购物车,结算并确认优惠信息,支付订单;商家接收到用户的订单之后开始备餐、出餐;骑手通过 App 进行抢单配送商品到用户手里,用户收到商品之后确认取餐并评价,完成整个点餐过程。如果针对这样一个场景做自动化需要花费多少成本?得到的收益又会是多少呢?
自动化实施之前一名测试工程师通过手工完成整个流程预计花费 30 分钟,登录->加购->结算->核对优惠金额->支付->商家备餐->出餐->骑手接单->取餐->配送->拍照送达->用户确认收到货物->评价->流程结束。
自动化实施之后一名测试工程师通过自动化方式完成整个流程预计花费时间假设 480 分钟。那么原先手工测试花费 30 分钟的工作量是不是就可以省下来了?这就是自动化测试的价值吗?对,但是不完全对。我们衡量收益还需要看成本。刚才我们说的一名测试工程师将这个场景转换为自动化这个就是自动化的重要成本之一。假设我们为了开发这样一个场景测试工程师花费了 8 小时,也就是480 分钟。
那么基于这样一个场景投入自动化测试投资回报比 ROI:产出/投入 = 30 / 480 = 0.0625。这里将产出 (收益) 和投入都用作时间来计算 (暂不考虑人员差异成本),结果不到 7%(乘以 100,换算成百分比)。投入了 8 小时,才收益了 0.5 个小时,结果肯定是亏本的。但是这个计算公式只计算了运行一次自动化的 ROI,实际上自动化测试肯定是不止运行一次的,每运行一次就会多省下来一份工作时长(这里暂不考虑运行自动化的机器成本)。如果用 n 来代表运行次数, t 代表单次测试时间,那产出就变成 n * t,n 越大,产出就越大。就像上面的例子:n(1 次) * t(30 分钟) = 30 分钟,每一次运行都会节省 30 分钟。那么基于上面的场景需要运行多少次才能收回成本呢? 1 / 0.0625 = 16,也就是说只要这个自动化测试运行超过 16 次,那么我们就可以让 ROI=100,收支平衡,收回成本。 但是,还有一笔账没有算,除了开发脚本的时间,还有维护成本,自动化测试开发出来之后还需要维护版本、数据、环境、稳定性等,这些维护成本是需要持续投入的。那么如何减少维护成本,就成为了自动化 ROI 的最大难点,这里就会涉及到用例开发的效率、环境的可维护性、测试数据的管理等手段。当然自动化还需要考虑产品本身的生命周期等其他因素。
最终自动化测试的 ROI 计算公式变为:产出 / 投入 = N(运行次数) * T(节省时间) /(开发成本 + 维护成本) 。比如上面的场景:1 * 30 / (480 + 维护成本),运行 1 次,节省 30 分钟,除以 480 分钟的开发成本 + 维护成本 (假设是 60 分钟),最终结果:1 * 30 /(480+60)= 0.0555555。需要运行 1 / 0.0555555 = 18 次收支平衡,收回时间成本。用中文表示此公式为:自动化测试 ROI = T(手工运行时间) * N(运行次数) / D(开发成本) + M(维护成本) 。
$$
自动化测试 ROI= {t 手工运行时间 * n 运行次数 \over d 开发成本 + m 维护成本 } X 100
$$
上面的公式可以帮助我们判断一个场景是否需要做自动化,当ROI 大于 100 就是赚,小于 100 就是亏。自动化测试是一个长收益模式,在短时间内很难达到 ROI=100(除非有些场景做自动化成本小于手工,比如一些手工极难测试的业务场景)。这个公式主要是在时间维度去考虑投入产出,我们也可以将其转换为金额为单位计算回报比,其中节省的费用代表自动化测试取代手工所节省的费用,成本代码自动化测试用例开发所投入的费用。在人员成本相同的情况下也可以简单的用人日的方式计算效益。
关于自动化测试的开发成本估算可以借鉴常用的项目管理需求规模估算方法进行评估,比如:功能点、故事点等方法。在做过一段时间自动化之后这估算值会越来越精准。
关于自动化测试的维护成本,影响的因素就太多了,比较难估算。而且随着时间的推移、架构的腐化、需求的变更、人员交替、自动化测试工具、框架、环境、测试数据、人员协作等因素维护工作量增加速度是以非线性来增长的。所以需要做分层自动化提高 ROI,关于分层自动化可以参考我写的另一篇文章持续交付下的分层自动化测试。
通过 ROI 公式的思想我们可以了解自动化测试投资收益比的量化思路,实际情况可能比这个更加复杂。当你对量化了解越多,对自动化测试的理解就会更加深入全面。
在实际工作场景中通常我们的测试策略会这样设置 “新功能探索性测试 + 修改影响范围测试 + 核心功能回归测试 + 非功能性测试”,从自动化测试的角度来看,我们应该优先解决 “回归测试”,因为相对而言回归用例都是系统比较核心的场景,必须要保障。
在敏捷项目开发过程中非常重视自动化程度,常规的敏捷项目一般以两周为一个迭代版本,每次迭代都需要进行一次回归测试,那么这一年里需要迭代的次数是 52 / 2 = 26 次。如果还要考虑紧急发布,那么实际回归次数肯定是大于 26 次,这样就得出一个 N 的估算值,比如 30。有了估算值之后对于是否需要做自动化的决策就不再依赖于直觉,而是有了可量化之后的思考逻辑。30 次是否能收回成本?如果能那么这个测试场景就适合做成自动化。不能,那么从时间效率来讲就可能是亏本的风险,质量因素暂不考虑进去。
我们做 ROI 的估算,并不是说给定一个公式,然后将参数填入进去就能计算出准确的 ROI,因为真实工作场景下大概率是给不出一个明确的数字去证明未来的事情,而是用 ROI 的思维去解释自动化测试的工作!就像我们无法证明通过看一本书,一个课程,跑一次步,就能带来多少收益。
管理学大师彼得· 德鲁克(Peter Drucker)曾经说过,“一个事物,你如果无法度量它,就无法管理它”。从研发效能的角度来看研发效能中度量指标一般分为几大类,交付速率、交付质量、交付能力、交付价值、交付成本、持续改进。其中交付质量是结果,内建质量是过程,做好过程是为了得到好的结果。自动化测试就是属于内建质量的活动之一。
交付质量度量常用的一个指标就是 “线上 Bug 数量 “,因为这个比较好理解。我们交付给客户的软件,如果 Bug 越少那么就证明质量越高。传统项目管理过程铁三角分别是时间、成本、范围,质量在中间,我们软件交付的质量就取决于这个铁三角的制约。其中某一项的变更都会影响另外两项,从而导致质量范围发生变化。那么如何保障在某一项发生变更时交付的质量能够得到保障这个就是我们度量需要考虑的。从交付的时间、范围、成本、质量的指标中我们可以得到自动化测试就是用于提升这三项指标的数据的。自动化测试的程度高,覆盖的功能越广,可以大面积回归,质量就能得到保证。而自动化测试执行速度也快,这样交付时间也会缩短。交付质量的度量指标确定了后,相当于目标确定了。
内建质量度量是因,交付质量是果。而且是多因一果。软件研发是一个复杂的活动,里面任何一个环节没做好,都有可能影响最终质量。就像木桶原理一样,质量通常取决去最短的那一块板。内建质量活动的每一项都相当于是木桶的一块板。剩下的就是我们如何找到最短的那一块板,然后对其进行增长。自动化测试就属于测试质量其中的一项指标,具体制定多少百分比比较合适需参考 ROI。质量的度量就像我们去体检,只有各项指标都符合预期的范围,才能说明你的身体某方面是符合预期的。
度量本身也是有成本的,如果我们需要准确的度量出自动化测试的 ROI,那么就需要进行 A/B 测试,但是实际在工作中研发的数字化程度都不高,如果在去做测试的数字化就会更难。从 ROI 的公式中我们可以得出最大的成本在于开发和维护自动化测试用例,那么我们可以定义度量集合,通过收集度量集合的数据合并到一个具体的累积数据获得我们公式中的计算因子。
计算因子 | 因子项 | 累计值 (h) 示例 | 备注 |
---|---|---|---|
开发成本 | 自动化测试框架选型 | 24 | 自动化实施之前的预研成本 |
开发成本 | 自动化测试框架开发 | 120+8+16 | 累积值,第一次会大。后面每个迭代基本趋于稳定。 |
开发成本 | 自动化测试框架维护 | 2+2+4 | 累积值,第一次会大。后面每个迭代基本趋于稳定。 |
开发成本 | 自动化测试用例设计 | 80+2+2+2 | 累积值,第一次会大。后面每个迭代基本趋于稳定。 |
开发成本 | 自动化测试用例开发 | Xxx | 不固定值,根据场景复杂程度而估算 |
开发成本 | 千行代码用例数 | Xxx | 度量一条用例大概需要多少行代码 |
维护成本 | 测试数据维护 | Xxx | 累积值,第一次会大。后面每个迭代基本趋于稳定。 |
维护成本 | 测试环境维护 | 累积值,第一次会大。后面每个迭代基本趋于稳定。 | |
维护成本 | 被测系统修改导致用例失败 | 反推团队协作中存在的问题 | |
维护成本 | 测试脚本假报错维护 | 对问题进行分类细化,逐个解决 | |
维护成本 | 测试框架维护成本 | 递减值,第一次会大,后面成收敛趋势。 | |
运行次数 | 测试用例被执行的次数 | 1+1+1+1 | 自动统计累积需要执行的次数。 |
节省时间 | 手工测试执行测试用例的时间 | 3+2+3+4+2+1 | 手动统计每一条用例的手工执行时间。 |
通过定期统计收集数据我们可以发现自动化生命周期中的瓶颈,从而有针对性的去解决问题,并且能观测到其他指标的变化。
以订单场景为例,登录->加购->结算->核对优惠金额->支付->商家备餐->出餐->骑手接单->取餐->配送->拍照送达->用户确认收到订单->评价。自动化实施之前一名测试工程师通过手工完成整个流程预计花费 30 分钟。这是一个最简单的场景流程,如果稍微复杂一点,测试时长会更长。简化估算手工测试执行一个场景需要 60 分钟,转换为自动化测试用例需要 480 分钟。
假设目前全场景测试用例数为:7+2+2+2+1+3+2+5+5+15+6+6=56。
订单场景执行一次自动化得到的 ROI
$$
ROI = 0.104166= {3360 * 1 \over 26880 + 5376 } X 100
$$
如果要达到收支平衡那么自动化测试需要执行 1 / 0.104166 = 9.6 次才能达到收支平衡。假设2 周执行一次订单场景回归,那么需要19.2 周订单的自动化测试 ROI 才能等于 100,收回成本 约 5 个月。如果一周发一次版本那么 9.6 周收回成本,约 2 个月。
回归周期(周) | ROI=100(9.6 次) | 回本时间 (周) | 回本时间(月) | 备注 |
---|---|---|---|---|
1 | 1 * 9.6 | 9.6 | 约 2.4 | 每周一发 |
2 | 2 * 9.6 | 19.2 | 约 4.8 | 两周一发 |
3 | 3 * 9.6 | 28.8 | 约 7.2 | |
4 | 4 * 9.6 | 38.4 | 约 9.6 | 一月一发 |
5 | 5 * 9.6 | 48 | 约 12 | |
8 | 8 * 9.6 | 76.8 | 约 19.4 | 两月一发 |
以上是批次交付(56 条用例)交付的情况,实际情况一般是单件流,一个场景开发完成就可以投入到生产之中,所以每开发一个场景用例执行 9.6 次就能收回成本,同时质量也在递增。
需要注意的是,这里我们只考虑了度量表格中的用例开发、维护计算因子项,其他因子项未在这里考虑进去,实际 ROI=100 的周期肯定会大于这个,而且这里也只是理想情况下的估算。
最早越好,一般是在当前迭代,这样可以避免重复工作量。比如自动化测试作为提测门禁、冒烟用例、当前迭代测试执行等,都是有好处的。如果放在后置会带来负向循环。当前迭代不做后面就更没有时间会去做了。如果当前迭代实在没时间做那么就优先考虑把冒烟用例或回归用例先自动化掉吧。当然也需要考虑自动化测试的ROI 和稳定性,所以现在基本都会推荐做单元、集成、接口自动化,而不做 UI 自动化,因为基于 GUI 的自动测试稳定性相对差很多。
根本原因是测试用例的后置。因为测试用例的后置导致功能已经被开发、测试、线上已经验证过没有问题,那么自动化测试当然发现不了 Bug。如果发现了 Bug,那可能是修改影响导致的。但是大部分产品都是在原有的功能上做加法,而不是重构业务本身,所以老的模块代码出现问题的概率自然减少了。
从当前迭代来看测试周期不一定变短,从一个较长周期来看肯定是变短了。因为测试执行时间变快,软件发布周期缩短,又反过来增加回归次数 N,自动化测试的收益也在增加。所以又得到一个结论:软件发布周期变短是自动化测试 ROI 提升的产物。 只要我们把注意力关注放在 ROI 上,后面的好处都会相继而来,测试质量提高了,发布周期缩短了,团队也更加有信心了。
代码覆盖率、需求覆盖率、缺陷逃逸率。
限于篇幅针对文章中的很多细节没有展开详细讲解,后续根据反馈会考虑推出系列文章。欢迎志同道合的朋友添加我的微信 (Miller_Shan) 一起交流,互相学习,共同进步。如果你觉得这篇文章不错麻烦动动你的小手帮我点个赞,让我知道这篇文章对你有帮助,谢谢~