笔者按: 在学生时代,参与过一些软件项目,也开发过一些模块,但对软件测试几乎一片空白、没有任何概念。进入工业界后,有幸在软件测试部门工作近两年。在实践中,深深体会到软件测试之于软件质量的重要性。测试自动化(Test Automation, TA)作为软件测试的发展方向,日益受到重视。笔者在对TA的学习、实践、交流中,逐渐形成了一些关于TA的认识和思考。在此稍作整理,分享给大家。文章纯属一家之言,难免有纰漏甚至谬误之处,还望读者批判性地看。
TA的好处我们知道多少?
测试自动化(Test Automation, 简称TA)是软件工程中的一个名词。维基百科对TA的定义是:
测试自动化就是用特定的软件去控制测试步骤的执行并且对测试结果和期望结果进行比较。
与TA相对应的是传统的手动测试(Manual Test),即人工地去执行测试和比较测试结果。根据定义可知,TA就是把本来需要人去完成的测试任务,以软件(即程序)的形式,交给计算机去完成。为什么要以软件的形式?因为这是计算机能够理解的。对于软件测试来说,TA是典型的”机器换人”,是一个重大的技术变革。那么,具体来说,这种变革到底能够带来什么好处呢?
提升测试效率
所谓效率提升,本质上就是生产力的提高。对此,我们从多个角度进行理解:
-
单次测试的时间消耗大大减少。测试工作通常包含一系列顺序执行的测试步骤。计算机不仅执行单个测试步骤更快,而且步骤与步骤之间的切换也是瞬时的。如果由人工执行,不仅执行单个步骤更慢,而且测试步骤之间的转换也会存在明显延迟。另外,对于计算机来说,我们很容易通过硬件能力的扩展(多核、多机器),来让单个测试步骤执行得更快。但是对于人工来说,我们却无法通过增加人数来达到同样的目的。
-
在相同时间内,可以执行更多的测试。我们知道,人要下班,而计算机一直在岗;人要休息,而计算机不知疲倦。计算机可以在深夜、在周末、在任何时候重复执行测试,而人却无法做到。相同的时间周期内,计算机重复执行测试的次数是人工无法比拟的。另一方面,计算机能够并行地执行多种测试工作,而人却很难同时开展两项不同的测试。
-
通过快速和重复的测试,有利于及早和更多地发现产品问题。事实上,一切测试工作的出发点和落脚点都在于更快、更多地发现软件问题(即Bug,下同)。测试执行得越快,发现问题的时间就越早,软件开发人员经历的反馈时间就越短。这将有利于他们快速地定位问题和解决问题。另一方面,由于计算机很容易重复地执行测试,我们有可能发现(以及复现,Reproduce)更多偶现的(Occasional)软件问题。偶现问题通常很难由手动测试发现,而问题一旦漏到客户那里,有可能产生严重的后果。
承担特定测试
有些测试工作,人工很难、甚至几乎无法完成,从而只能由计算机承担。比如说性能测试(Performance Testing),我们希望测试软件在大用户量或高并发量下的性能指标。在实际中,我们几乎无法去构造成千上万用户使用产品的测试场景。这时,我们可以用计算机来模拟这样的场景。通常,单台计算机就能够完成模拟成千上万用户的任务。又比如压力测试(Stress Testing),我们希望测试软件在长时期、不间断运行时的性能变化。这时,几乎不可能使用人力去持续不断地监测软件的运行状态,而计算机(例如一个简单的脚本程序)就能够很好地承担这样的工作。
测试工作全过程自动化
一项完整的软件测试工作,包含: (1) 设计并实现测试用例(即Case,下同) (2) 部署和升级被测软件 (3) 执行测试用例 (4) 收集各种软件日志 (5)分析并反馈测试结果等步骤。其中,除了第(1)步外,其他几步均是高频工作,通常是每一次软件迭代都需要做的事情。狭义的TA,实际上仅仅是第(3)步,即测试执行层面的自动化。仅仅单个环节的自动化,对于测试工作整体效率的提升是有限的,因为其他步骤可能成为瓶颈。事实上,在测试执行自动化的基础上,将测试工作的其他高频步骤,例如升级被测软件、收集软件日志、反馈测试结果等,也以自动化的形式实现,是一件水到渠成的事情。将这些繁琐的、重复的、技术含量低的操作交给计算机去做,不仅进一步提升测试效率,缩短测试反馈时间,而且能够解放测试工程师,让其把更多的精力投入到设计并实现更好的测试Case、软件Bug定位和分析等更有挑战性的工作上。而这部分工作,通常是计算机难以胜任的。一般来说,能让计算机做的就不要由人来做;人作为比计算机更宝贵的资源,应当去做计算机无法或很难胜任的事情。
测试进入软件CI
现代软件开发,越来越强调以增量开发和快速迭代为特征的敏捷模式。在实际操作中,开发人员会频繁提交代码。每次代码的提交,都会自动触发软件持续集成(Continuous Integration, CI )系统的运行。CI在拿到软件代码的改动后,会自动触发一系列工作,例如静态检查代码、运行单元测试用例、编包等。CI系统高速、并行地运转着。单元测试通常由开发人员自己完成,并且以代码的形式存在,天然就是”自动化的”。而后续的功能、性能、集成等方面的测试,通常是在CI发布软件包之后,才开始以某种形式介入,是低速、串行地运转着。如果后续的测试能够实现自动化,那么也可以进入CI系统,成为CI的一部分。测试进入软件CI带来的好处可以从多方面解读:
-
助力ATDD(Acceptance Test Driven Development)思想落地。如果说测试驱动开发(TDD)只是软件开发内部的实践(Practice),那么验收性测试驱动开发(ATDD)则是业务、开发和测试三方合作下的实践,更有利于确保软件的实现符合产品的需求。具体来说,软件开发的完成应以验收性测试Case通过为标准。在新功能(Feature)开发阶段,验收性TA Case完全可以早于软件代码准备好(Ready)。每次软件代码的提交,均会自动触发对应TA Case的运行。TA Case通过了,软件的开发才算完成。如果TA Case自身存在问题,那么也可以像修改软件代码一样通过版本控制工具(例如git)快速地修改、提交和生效。TA Case一旦通过,软件开发工作和对应的测试工作便同步完成。每一个新Feature完成,对应的TA Case便会加入TA的回归测试集(Regression Pool)。
-
确保后期代码改动不破坏已有功能。软件代码的改动是一个高频率的事情。实现新的需求、修复软件Bug、重构等,都会造成代码的改动。那么,如何确保每次改动都不破坏已有的功能?在CI系统中,每次代码提交,自动触发TA回归测试集中所有Case的运行。只有所有的Case都通过了,这次代码提交才被认为是有效的,才能被合进代码的主分支(Master)。在软件功能一个接着一个完成的同时,回归测试集也相应地逐步扩大。回归测试集的执行贯穿于软件开发的整个过程,而不是等到软件开发全部结束后,再去做回归测试。在笔者当前参与的软件项目中,软件的功能测试实现了自动化,并且从第一个功能点开始,就进入了CI系统。据统计,功能测试回归集平均每个工作日在CI中被执行200多次,一个月内能达到5000次。这样的回归强度是手动测试时代完全不可想象的。
-
开发和测试通过CI实现高度协同工作。开发和测试之间的”相爱相杀”,是软件公司一个永恒的话题(本文不展开)。测试进入软件CI为开发和测试人员提供了一种全新的工作模式。在实践中,开发和测试人员在同一个软件仓库,甚至在同一个分支上协同工作。开发人员实现产品代码(SW Code),测试人员实现测试代码(Test Code)。任何一方做出改动,CI系统会自动进行验证,并将验证结果反馈给相关人员。这种在线的、同步的工作模式,实现了软件开发和测试验证的”共振“。
-
进一步完善CI系统。软件的质量,最终是由用户来评判。CI系统完不完善,取决于自身与最终用户之间的距离。笔者认为,CI系统应该是面向交付的。从结果上看,CI输出的软件包应当以可供用户使用为目标。因此,CI应该尽可能地将软件开发之后的各个测试和验证阶段纳入进来,以进一步完善自身。TA,恰恰为测试进入CI提供了必要的前提条件。
我是肖哥shelwin,一个高质量软件工程实践者和推动者。欢迎扫描下方二维码,添加我的个人公众号测试不将就,获得更多自动化测试, 持续集成, 软件工程实践, Python编程等领域原创文章。