可维护的自动化验收测试

阅读数:1410 2009 年 12 月 14 日

话题:敏捷语言 & 开发架构文化 & 方法

Dale Emery认为,有些自动化测试因为比较脆弱而且维护成本高,已导致很多公司放弃了实施测试自动化的意愿。在一篇最近发表的文章中,Dale 共享了一些避免测试自动化中这些共性问题的实用方法。他以一些比较典型的自动化代码做引子,推演出一些有利于增强代码健壮性,降低维护成本的方法。

Dale 文章背后的基本理念其实是:测试自动化也是软件开发。这个简单但却毋庸置疑的事实,是他从Elisabeth Hendrickson的理念中借鉴而来的。

对大多数软件而言,在代码的整个生命周期中,维护成本很可能比开始的开发过程成本还要高。在测试自动化领域,这点在录制 - 回放脚本的应用中体现得尤其明显。这些脚本容易创建,但往往难于维护。

Dale 认为,要让自动化测试脚本更易于维护,有两个必知的关键因素:附属信息和代码重复。

附属信息泛指那些可以让测试正常运行所需的所有“材料”,但本质上并非测试的真正组成部分。变量赋值、循环、调用下级子程序、自动点击按钮,甚至是脚本语言自己的语法都可以算是附属信息。所有这些都是必需的,它们描述了测试代码的工作方式,但也正因为它们,代码真正要达成的目标也变成了雾里看花。

重复就是指多次重复出现的简单代码;众所周知,这是可维护性的死敌。一个系统的小改动就可能牵动有重复代码的每个实例。这是录制 - 回放类型的自动化测试的一个关键问题:到处充斥着重复代码。

为了明确概念,Dale 举了个测试账户创建程序的代码实例。这是段正确而且很常用的代码,但有很多附属信息和重复。通过成功重构,Dale 把那些附属信息藏了起来,去掉了重复代码。重构后的代码显然更易维护。还有一个额外的好处:重构后的代码清晰显示了每段测试想要验证的本质目标。即使对测试工具或相关上下文一无所知,当这段代码运行失败时,我们仍然能够知道是因为没能实现哪个系统需求才导致失败。

回溯到 1997 年,在洛斯阿尔托斯软件测试研讨会(LAWST)上,齐聚一堂的软件测试专家们也发现了类似的测试自动化方面的问题。Cem Kaner记录了这次集会的成果并在 97 年的 Quality Week 上做了相关演讲。在名为《改进自动化测试套件的可维护性》的论文中,Cem 指出:

写测试用例最常见的方法是利用你自动化测试工具的捕获功能。太荒谬了……对程序中的用户界面所做的任何微小改动都会导致脚本瘫痪。与录制测试用例紧密相连的维护成本实在让人难以接受。

针对改善自动化测试的可维护性,以下是洛斯阿尔托斯软件测试研讨会 (LAWST) 小组提出的三条建议:

认识到测试自动化开发也是软件开发

不论别人如何,测试人员都必须认识到:软件开发要遵循一定的纪律,而不能采用“快而脏”的方式设计和实现,这至关重要。如若不然,我们只能像自己测试过的程序那样,无数次吞咽失败的苦果。

使用数据驱动的架构

很多测试用例的实现逻辑都是相同的,但这个逻辑要经历各种各样的输入和相应的期望输出的检验。通过将数据从测试逻辑中分离出来的方法,就可以去掉代码重复。这样,假设要做一个用户界面的改动,只要在相对底层的测试代码上做个简单修改就能修复一大片测试用例了。

使用基于框架的架构

框架使用共享的函数库的一系列函数,可以把要测试的应用程序和测试脚本分离开来。测试脚本编写者们或许可以把这些函数当成是测试工具程序设计语言的基础命令。这样一来,他们就能独立地编写脚本,不受 UI 的限制了。

这只不过是良好的编程习惯:从杂乱无章的实现细节中解脱出来。基于接口、面向对象的设计流派宣传这样做的好处已经很多年了,尽管这个概念其实可以追溯到由来已久的子程序理念。

基于一个设计良好的框架,使用数据驱动的实现方式可以大幅降低维护成本。真正的问题是如何做到这一点。Dale 的文章给出了这样的答案:通过一系列重构不断改良已有代码,直至它显示出我们所期望的这些属性。当你把测试自动化也当成是软件开发时,这一切就显得合情合理了。

你有什么样的自动化测试经历呢?你遇到过可维护性的问题吗?你用了什么方法来克服这些问题呢?结果又如何?留下你的意见,和大家分享一下你的经历吧。

查看英文原文:Maintainable Automated Acceptance Tests