如何创建可维护的自动化验收测试

发表于:2012-01-20来源:未知作者:Dale. H.Emery点击数: 标签:
如何创建可维护的自动化验收测试这里的测试指的是自动化测试,从软件的本质上看,测试的自动化乃是测试方面的软件开发,万变不离其宗,这也就意味着那些凡是属于软件开发的定律或者原则也同样适用于测试自动化。对于没有写过代码或者代码经验较少的人来说,或

  测试开发

  这里的测试指的是自动化测试,从软件的本质上看,测试的自动化乃是测试方面的软件开发,万变不离其宗,这也就意味着那些凡是属于软件开发的定律或者原则也同样适用于测试自动化。对于没有写过代码或者代码经验较少的人来说,或许这其中的道理不能一眼就瞧得出来。

  通常情况下软件开发的很大一部分开销是维护——修修补补,更新不断。软件的可维护性强,则开发成本低,同理,测试的自动化开发成功与否也很大程度上体现在它的可维护性成本大小上。我接触过的很多试图尝试引进自动化测试的机构没几个月就决定放弃自动化测试,问之弃因,你会发现大多是因为自动化脚本过于不稳定以及随之衍生的难维护性。举个例子,界面上重命名一个按钮会导致大批的测试用例失败,而与此同时花费在调通和更新这些用例身上的时间成本又太高。

  有些团队或机构在自动化测试上取得了成功,难道他们的自动化就可以避免掉这样的维护费用问题?当然不可能。而成功与失败的团队之间一个重要的区别就是:在对待测试开发的维护问题上,失败者往往是被昂贵的维护费用吓住而放弃自动化计划,而成功者则是从一开始就做足了应对措施。那些在自动化取得成功的团队懂得测试即开发这一道理,明白测试开发一旦开始,维护在所难免,所以他们会深思熟虑,想方设法降低维护成本。

  软件需求的变更和系统实现的变更会影响测试,需要测试做出相应的调整,这二者任意一种变更都可能导致一系列的自动化测试失败。如果一些自动化测试不能同步新的软件变更和产品新特性,那么它们将会被淘汰,其测试结果也不会得到运用。而要使其回归正常,我们必须不断调整测试以配合需求和系统实现的变更。维护的成本开始显山露水。

  因此如果需求和实现的变化是必然的,那么降低自动化测试维护成本的方法只有一个,即编写适应性强的测试脚本。

  暴露太多无关紧要的细节或者重复这两大关键因素使得修改代码的困难大大增加,无数惨痛的经验教训让软件开发人员对此深有体会,对于那些正在从事和将要从事的自动化测试开发者们,也肯定不想重蹈覆辙。

  验收测试和系统的任务

  验收测试用来检测一个系统是否正确履行了某一特定任务。也就意味着,验收测试的核心是关注它所要验证的功能点是否正确,而不考虑用了何种技术、何种方法去测试。

  现在假定我们要测某个系统的创建账号这个特性,系统通过传递给Create命令用户名和密码来创建新账号。创建账号特性的功能之一是验证密码的有效性。一个合法的密码长度必须介于6~16字符之间且至少包含一个字母、一个数字以及一个标点符号。如果用户提交的密码合法,Create命令创建成功并报告Account Created;反之,Create命令不会执行创建过程,同时报告Invalid Password。这就是功能职责的本质。无论软件系统以何种技术实现,Web应用也好,GUI桌面应用也罢或者是命令行执行的程序,也不管会不会有人像德州电锯杀人狂里的休维特一样,挥舞疯狂的电锯恐吓要锯断那些输错密码童鞋的指头,总之,系统需执行此项职责(密码检查是系统必须实现的职责)。

  无关紧要的细节

  表1 不良自动化测试用例脚本

  列表1展示的是一段不良自动化测试用例脚本,该测试用例用来检测Create命令的密码有效性检查这一职责。

  这段测试脚本问题很多,一眼望去,最明显的是可读性很差,我们看到第二行The create command validates passwords,这是测试的标题,表明该测试的测试点和职责,但往下读时,我们会发现,里面充斥了太多累赘的单词和烦人的诸如“{$@^”这样的符号,让人不知其所言。

  仔细看一下,我们可以挑出来几个密码,比如1234!@$^!紧接着再加把劲,啊哈,我们会发现一些密码会导致status值为Invalid Password,而另一些会使得status值为Account Created。从另一方面看,我们可能也会注意不到上述内容因为该测试脚本在密码和状态status之间夹杂了太多的实现细节,或曰:测试噪声。试想,这些特殊的符号$、@、^以及单词Run、Ruby、fred究竟和密码及其有效性有什么关系!对于自动化测试的脚本来说,从用例的可读性和可维护性角度看这些都是无关紧要的过程实现细节。

  过多无关紧要的细节是怎样毁掉可维护性的?假设我们的系统安全分析师指出六位长度的密码本身不安全。于是为了增强安全性,我们将密码长度下限由六改成十,这是一个典型的需求变更,请思考,这时候列表1的测试脚本哪里需要修改?怎样改?答案恐怕没那么简单。

  让我们再来考虑一个更有挑战性的需求变更。假如我们想让系统管理员能够为任一种情况设定具体的密码长度最长与最短值。这时候该怎么修改刚才的测试脚本?答案还是无法一眼看出。恐怕没那么简单。

  这其中的原因“恐怕”在于测试脚本没有清晰表达它所要测试的功能职责。当看不出一段测试用例脚本的本质 ,通常意味着需求变更之时测试人员会需要花数倍的代价来修改原测试脚本。

  因此,为方便识别本质就要隐藏非必要细节的,以使自动化脚本用户更容易看到测试的本质,在上面创建用户的例子中,大多数非必要的细节是如何调用Create命令。该系统是基于Ruby的命令行程序,现在让我们再次返回列表1的测式脚本里解读一番,黑色字体加深的第一行告诉自动化测试框架Robot启动Ruby解释器,加载被测程序文件app/cli.rb,并调用Create命令,参数值为用户名fred以及密码1234!@$^,最后命令返回的结果存在变量${status}中,呵,数数不必要的实现,细节至少有5~6个之多!

  再来看字体加深的第二行,实现命令返回值和期望值Invalid Password的比较,虽然看起来比刚才那一行较容易理解 ,但措辞笨重,并且过分的语法细节容易分散人们的注意力。

  通过Robot自动化框架我们可以把实现细节提炼成关键字(Keyword),使之以类似子函数的形式为测试用例脚本调用,一个完整的自动化测试用例便可由数个关键字组合而成。

  现在我们演示如何使用关键字来隐藏不必要的实现细节。一个可行的方法就是问自己这样一个问题:假设自己对被测系统实现一无所知,该如何写出自动化测试脚本的第一步?是的,即使对实现一无所知也无大碍,我们只需 知道我们要测试创建用户这个产品特性——被测系统显然要提供的功能。继而我们知道创建用户即是被测系统的必要职责,而且从系统需求分析可知创建用户需要提供用户名和密码。

原文转自:http://www.ltesting.net