本文不会介绍持续集成的概念、理论以及相关工具的用法,而是基于实际的项目案例,分享如何利用自动化测试保障持续集成的有效性,同时也借助持续集成提升自动化测试用例的价值。
在本系列的前几篇文章中,首先分析了测试不够敏捷的原因,然后从“降低测试脚本维护成本”和“优化断言机制”两方面分享了Web自动化测试的改善实践。
前面几篇文章其实都在讲“如何成功实施Web自动化测试”,本文将要涉及一个很敏感,但不应该回避的话题“自动化测试的意义到底有多大?”。
做过自动化测试的同仁都应该对“自动化测试用例能发现多少缺陷”这话题不陌生,业界也有很多支持“自动化测试用例主要不是用来发现缺陷,而是提高回归测试效率”这个观点的文章。即便这样,“发现缺陷”也像是自动化测试人员“肉中的一根刺”,很多时候大家不愿意去触碰它(不碰就不痛)。这样时间久了,很可能会让自动化测试人员丧失发现缺陷的斗志。笔者在这里就尝试拨动一下这根“刺”,希望可以再次引发大家的思考。
“自动化测试主要不是用来发现缺陷”这一观点的主要依据是“自动化测试是严格按照已有用例进行的自动回归测试”。说白了就是“它每次做的事儿相同的”,所以不能像手工测试那样依靠人的主观能动性来发现新的缺陷。
“它每次做的事儿相同的”,这一点我们改变不了。
但我们能做的是在不同的场景中做“相同的事儿”!从而增加发现缺陷的几率,降低软件释放后风险。
下面就通过实际案例分享笔者在提升自动化测试价值方面的经验:“在持续集成中对每日构建的版本进行回归测试”,并对一些里程碑版本进行“在各种环境组合下(应用服务器、数据库、浏览器、操作系统)的兼容性测试”和“7*24小时的稳定性测试”。
本案例中的产品是面向云计算领域的通用云环境管理软件,在云数据中心构建及运维过程中提供全方位、多层次的管理能力,基于云环境实现应用的快速部署及其资源的弹性供应,通过简化管理极大地降低成本、提高效益。
产品的逻辑架构、主要技术路线及对应的自动化测试方案如下图所示:
该产品大致可以分为三层:
持续集成方案选择的CI工具是Jenkins,具体步骤如下图:
对每个步骤的要点简述如下:
更新编译代码
项目采用分布式开发,需要从不同的配置管理库中更新各个模块的功能代码和自动化测试用例。
代码质量检查
项目要求开发人员使用Findbugs和PMD对自己的代码进行质量检查并修正相关问题。同样也在持续集成过程中通过Sonar(集成Findbugs和PMD)使用相同的策略进行代码检查,以确保该要求的执行效果。
更新数据库
在更新功能代码和测试脚本之后,自动化测试还是可能出现大面积无法通过的情况。其中一个很常见的原因就是“当天开发库中的数据库结构发生了变化”,而持续集成所使用的数据库并没有更新。
所以我们执行自动化测试用例之前增加一个“检查开发库和持续集成库的表结构是否一致,如果不一致就做增量同步”的任务。
执行单元测试
通过单元测试确保系统与虚拟化资源或物理资源的交互是没问题的。如果这个环节出现严重问题,后面的持续集成任务就没必要执行了。
部署后台服务
单元测试通过之后,把后台服务(即,上面说的中间层)发布到目标服务器并启动服务。
执行REST接口测试
基于上面发布的后台服务,对其提供的大量REST接口进行回归测试。如果这个环节出现严重问题,就没有必要再部署前台应用并进行后续测试了。
部署前台应用
REST接口测试通过之后,才把各个前台门户应用发布到目标服务器并启动服务。
执行Web UI测试
基于上面发布的前台应用,执行各自Web UI层面的自动化测试用例(采用本系列前面几篇文章中介绍的方案)。
发布构建结果
通报每日构建结果(如下图所示),测试用例按照模块进行分类,对不通过的用例进行分析然后提交相关缺陷。
上述持续集成案例的关键是“自动化测试”,而无论从技术还是从管理的角度,其难点也是“自动化测试”。
从技术角度来说,在上面三类自动化测试中最困难的是UI层面的自动化测试。笔者在本系列前面几篇文章中主要分享的就是这方面的改善实践。
从管理角度来说,要对自动化测试相关数据(比如,用例通过率、用例增长率、代码覆盖率等)实施公开、准确的度量,如下图所示。
度量的最终目标不是为了考核,而是为了改善。
从度量结果中团队能看出问题,才能有的放矢的改善;
从度量结果中团队能看出进步,才能得到激励和信心。
众所周知,没有自动化测试的持续集成是“伪”持续集成。但笔者了解的很多做持续集成的项目都存在着“自动化测试用例很不充分”的问题。 上述持续集成案例中是如何做到充分自动化测试的呢?笔者认为有如下几个要点,希望可以引发大家的思考:
|
现在软件需要兼容的环境越来越多,包括操作系统、应用服务器、数据库、浏览器,像上面案例中的产品还要兼容主流虚拟化服务(比如,VMware 、XenServer、KVM)的各种版本。如果全靠人工测试来保证兼容性,是不太现实的事情。
兼容性测试有个特点,就是如果不兼容,往往在一些主要流程上就能明确的体现出来,一般不用深入到每个业务细节,也不用靠人来主观分析。因此也非常适合通过自动化测试来完成。
下面分享一个笔者在撰文的前一天刚刚遇到的实际案例(如下图所示)。
这个一个最基本的用户维护界面,里面包括必填信息和可选信息(比如,生日)。在一次自动化测试中,Web UI层面的“用户信息修改”用例出现了如下异常:
Caused by: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect datetime value: '' for column 'ext_date' at row 1
这个功能后台业务接口是有单元测试用例对应的,并且也做了一些边界值测试(比如,“生日”属性为空),但遗漏了另外一个边界条件(空字符串),而恰恰如果界面不选择“生日”,传到后台的就是空字符串。Web UI层面最基本的测试用例恰恰弥补了这个缺憾。
有些人可能会质疑:如果界面不选择“生日”,传到后台的也是空(null),那么这个Web UI测试用例不也一样发现不了这个Bug嘛。 确实如此,但换个角度想一下,如果这样的话,这个“Bug”即使遗漏出去,也永远不会被用户发现。 这正体现了Web UI层面自动化测试的意义——比其它层面的自动化测试更代表用户! |
写到这里,可能会有敏锐且尖锐的读者继续提出质疑:“这么表面的缺陷在手工测试阶段一定会发现的,怎么会轮到通过Web UI自动化回归测试来发现呢?”
我们来回顾一下上面的异常信息“Caused by: com.mysql.jdbc.MysqlDataTruncation…”。是的,这个缺陷只有在使用MySQL数据库时才出现,而日常开发和手工测试使用的都是Oracle数据库。
我们把在各种组合环境下的兼容性测试交给自动化用例来完成。因此,如果有兼容性方面的Bug,也是“得来全不费工夫”!
稳定性测试可以分为“服务端稳定性测试”和“客户端稳定性测试”。其中服务端(比如,应服务器、数据库等)的稳定性测试是最常见的,笔者这里不做赘述。
RIA(Rich Internet Applications)技术的广泛应用为Web用户提供越来越赞的使用体验。与此同时,也比传统应用占用更多的客户端(浏览器)资源。所以对此类应用的客户端稳定性测试也是非常关键的。
验证客户端的稳定性需要两个条件:长时间的不间断操作、监控浏览器资源占用。
我们通过对Web UI自动化测试用例的循环执行可以模拟长时间的不间断操作。另外,在自动执行的同时,自动获取并记录浏览器资源占用,就可以达到验证客户端稳定性的目的。
如果系统前端代码出现内存泄露(比如,弹出页面关闭后未销毁生成的DOM对象),Web UI自动化用例长时间运行后生成的浏览器内存占用报告就会如下图所示:
而正常应该是整体呈水平趋势的锯齿状图形。如果出现上述情况,其表现出来的现象是用户感觉操作响应越来越慢,严重的情况下会导致浏览器宕掉。
至此,本系列文章就结束了。下面用三句短话总结一下本系列的主要内容:
最后分享笔者这几年在实施自动化测试和持续集成工作中的一些心得体会:
殷坤,东软集团资深测试经理、技术讲师,10年软件研发、实施、测试及项目管理工作经验。
目前专注于敏捷项目管理及质量控制、过程改善、自动化测试、持续集成、用户体验提升等方面。