电脑技术学习

我们是否应该做更多的自动测试呢?

dn001
内容:
我们是否应该做更多的自动测试呢?

确定是否自动测试对你的应用有意义

作者:Ben Teese

译者:xMatrix


版权声明:任何获得Matrix授权的网站,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
作者:Ben Teese;xMatrix
原文地址: http://www.javaworld.com/javaworld/jw-03-2005/jw-0307-testing.html
中文地址:http://www.matrix.org.cn/resource/article/43/43915_automated_testing.html
关键词: automated testing

摘要
为了帮助开发人员确定是否他们应该做更多的自动测试,Ben Teese在这篇文章中表达了两个疑问:1、开发人员在当他们可以完成应用时是否对测试抱有很现实的态度?2、什么时候自动测试对应用是有意义的?

这篇文章有关是否我们(指专业软件开发人员)应该做更多的自动测试。他的目标对象是那些发现他们始终在重复手工测试的开发人员,测试人员及其他。
在这篇文章中我提出了两个问题:
·我们是否现实地对待我们将会做的那些测试?
·什么时候自动测试是可行的?

注意这篇文章不讨论是否我们需要测试(自动或手工测试)。不管是什么类型的测试,单元测试、系统测试或者用户验证测试。
实际上,这篇文章倾向于一些提示性的讨论及包含了基于我自身经验的一些意见。

一个实际的例子,第一部分
让我们从我最近工作的一个项目开始。这涉及到对一个中等复杂的在线网站的小修改,没什么特别的,只是增加一些新的动态文本和图片。

因为系统没有单元测试而且不是根据有利于单元测试的方式来设计的,所以分离及对我修改的代码进行单元测试是困难的。后来,我的单元测试更像是小型的系统测试因为他们通过网络接口的新功能间接测试了我的修改代码。

我认为自动化测试是没有意义的,因为我猜想这些测试只会被运行几次而已。因此我只简单写了下描述执行测试的手工操作步骤的测试计划。

编码和测试第一个修改还是很容易的。第二个修改也很容易,但我必须重新执行第一个修改的测试用例来保证我没有改变什么。第三个修改也很容易,但我必须重新执行第一和第二个修改的测试用例来保证我没有改变什么。第四个修改也很容易,但。。。你知道我要说什么。

什么是累赘
每次我不得不重运行这些测试用例,我在想“运行这些用例真是个累赘
我继续运行这些用例,一次偶然我发现自己引入了一个问题。这时候我想:“很幸运我还在运行这些用例。

既然这两种想法看起来是矛盾的,我开始计算究竟我运行这些用例需要多长时间。
一旦我得到了一个稳定的开发版本,我布署我的修改到一个系统测试环境,那儿会有别的人员来测试他们。然而由于环境的不同,我认为我应该重新执行那些测试用例来确保修改的正确性。

后来有人通过系统测试发现我的修改有一个问题(在我的用例没有覆盖到的地方)。于是我在我的环境下修正了这个问题,重新运行测试用例确保没有引入新问题,然后就重新布署一下。

最终结果
到我完成所有的时候,我发现我已经执行了整个测试用例不下八次了。每次测试所花费的时候大概需要10分钟。这就意味着我的手工测试大概花费了80分钟。于是我问自己:“是否我使用自动测试会更简单些?

你是否曾经只需要几次测试周期来完成所有的测试呢?
我相信我低估了测试我修改的工作量的错误其他开发人员也会犯。开发人员常犯低估工作量的情况,我并不认为对测试工作量的估计有什么不同。实际上,如果不考虑许多开发人员有测试的经验,他们对测试代码的工作的低估程度要远高于对其他估计。

这种测试工作量爆涨的主要原因不是因为测试的时间比预期的长,而是测试周期的数目比预期的要多。以我的经验,大部分开发人员认为他们最多只需要测试代码几次就可以了。对这些开发人员我想问一个问题:“你真的只需要测试几次吗?我确信不是。

但是如何应对JUnit测试用例呢?
是的,你可能写了许多底层的JUnit测试用例,但我讨论的是高层的用来测试系统功能的测试用例。许多开发人员考虑写这样的测试用例,但由于看起来为只会执行几次的测试用例花费那么多时间不太值得而导致这些用例往往被延迟了。于是他们手工执行这些测试直到发现这个活变得累赘,往往这是在他们不想再执行这些测试用例的时候。

另一种情况是工作在已有产品的少量改动的开发人员(像我开始提到的)也会导致这种情况。因为这看起来是非常小的工作,没有必要写自动测试用例。你只会执行几次这些用例—但事实是这样吗?当然不是,就像我从我的实际例子中学到的一样。

可能有人想要修改你的代码
虽然开发人员通常都会低估测试周期的个数,但是他们甚至没有考虑以后需要测试代码的工作量。在完成软件的一部分并且手工测试了几次之后他们可能不再想考虑这些代码了。但这样做的话,他们就忽略了在某些时候别的开发人员可能会再次测试这些代码。

许多开发相信一旦他们完成了软件的一部分功能后,就不会再有什么改变因此也不需要什么测试了。但根据我的经验,从来没有代码可以一次完成编码/测试/发布的生命周期而不需要再次修改的(特别是那些给别人写的代码)。实际上,即使代码的需求者告诉我我的代码会很快被抛弃,这也不会发生(我做过很多“抛弃型的原型后来都被带入产品中并且一直保持着)。

即使软件没有改变,环境也会改变
即使没有人修改你的代码,他所在的环境依然会改变。大部分软件并不是独立存在的,因此他不能规定改变的步伐。

虚拟机升级/数据库驱动升级/数据库升级/应用服务器升级/操作系统升级,这些变化都是必然的,实际上,可能有人会争论,作为一个最佳实践,系统管理员应该保证他们的数据库/操作系统/应用服务器是最新的,特别是需要最新的补丁和问题修复。
那么这儿只可能存在你公司内部的软件修改了。例如,一个由其他部门开发的企业级datasource升级了,而你的软件又完全依赖于是他。或者说,假设你的软件会发布在一个包含其他内部应用的服务器上,而为了其他应用可以运行,服务器必须升级到最新版本,这时你的应用就要考虑是否可以继续运行了。

但究竟什么是变更管理呢?
一些人认为管理应该负责协调变更;应该跟踪依赖并且确保如果某个依赖发生变更你可以重新测试。跨系统的变更需要和发布同步。然而根据我的经验,这些依赖都很复杂难以成功跟踪。我建议另一种方式—软件系统应该更好地处理自身测试并考虑必然的变更。

如果你没有自动测试会怎么样呢?
就像我所见的,没有处理这种变更的组织通常会有两种情况:或者减少测试来保证进度或者减缓进度来保证测试。每一种方式都有自己的问题。

减少测试来保证进度
这些组织倾向于:手工测试会花费太多时间,而自动测试又太复杂,因此无们不需要测试太多。当然他们就得承担所有因测试不足而导致的各种问题。然而,就像我在介绍的提到的那样,这篇文章不会讨论测试的必要性,因此我也不再继续讨论这个问题了。

减缓进度来保证测试
这些组织倾向于:测试是重要的,但写自动测试太复杂了,因此我们倾向于手工测试。这比没有测试强,但我不认为在一个企业级环境中的大系统中手工测试可以跟上必要的变更步伐。减缓进度是系统前进的障碍。例如:应用服务器没有升级导致新项目被迫使用旧的平台,因为手工重新测试一个已经发布到平台上的软件是不实际的。

有一次我工作于一个项目,团队使用一个内部的五年前艺术级的持久层实现,但相对于现在的技术已经落伍了。在这种情况下(特别是设计很好的系统),看起来好像变更的代价并不大—只需要确保变更不会破坏其他东西就可以了。

这个问题可能导致错误的循环:架构不够先进是因为没有时间来做手工测试并且没有人想引入问题,但是因为架构的问题使软件变得更加难以维护了。

什么时候应该使用自动测试?
因此说我们在理想世界中是一致的,我们应该为软件做自动测试。然而在实际中,我们知道写自动测试是需要时间的。因此问题在于:在什么时候自动测试是有价值的?

如果我们假设执行自动测试的代价相对于手工测试是可以忽略的,那么我们可以说在自动测试的代价小于手工测试时自动测试是有价值的。这在下面的图中有所表示,蓝线和红线分别代表自动和手工测试的在一定测试周期中的代价:



两线的交点代表自动测试开始变得有价值了。然而,即使我们知道这些线的交点,我们也不能确定是否我们的系统可以担保自动测试是有价值的,除非我们能够回答下面的问题:
1、我们需要手工执行测试周期多少次?
2、编写自动测试需要多少时间?

问题是通常我们不能预先知道这些问题的答案。然而我们还是可以以过去的经验作为基础来估算一下。
让我们重新考虑一下我前面描述的工作。我们知道特定测试周期的执行次数—那么将他自动化又需要多久呢?

一个实际的例子,第二部分
通过jWebUnit,我在1.5个小时内将我设计的7/10的手工测试改为自动测试(剩余的测试使用的特性超过了这个工具的能力),也就是每个测试13分钟。但是如果你手工执行10个测试需要10分钟。假设每个测试需要1分钟,我们可以推断出如果一个测试执行时间超过13分钟那么自动测试是值得的。
在这个案例中看起来自动测试是不值得的。可能在开发的开始阶段还不能确定,但以后肯定有大量的变更会发生在同一个代码库中。在变更后,重新执行这些测试来检查是否引入了新的问题是有用的。实际上也是这样。因为我已经为前一版本写了一些jWebUnit测试用例,因此我可以重新执行他们来确定是否引入了问题。

公平地讲,我用的衡量方式并没有计算熟悉测试框架的时间。我也至少花了几个小时来学习使用jWebUnit。我想其他开发人员也是这样。但是,因为开发人员熟悉了测试框架后,这样的时间应该会逐渐减少。


小结
这篇文章并没有要求适用所有系统中的自动测试。相反,这只是请你考虑如下问题:
1、一个系统或变更确实需要测试的力度?
2、在什么时候对我们来说启动自动测试是值得的?

虽然前一个问题可能需要一些考虑,但后一个就像你衡量你花在测试代码的时间一样简单。如果时间超过你设想的话,你就应该考虑编写一些自动测试来比较一下了。这时你就可以得到结论是否或什么时候你可以在将来的项目中从自动测试中获益。

我很期望得到您的反馈。在这篇文章中我没有讨论一些领域—如自动测试的维护代价。此外,如果你也做过一些这方面的尝试,我很高兴您与我联系分享你的结论。

关于作者
Ben Teese是hine Technologies的一名软件工程师

资源
·更多有关自动测试的资料,请参考“Swing应用的自动GUI测试
http://www.javaworld.com/javaworld/jw-11-2004/jw-1115-swing.html
·更多有关测试的文章,可浏览JavaWorld的主题索引的测试部分
http://www.javaworld.com/channel_content/jw-testing-index.shtml
·javaworld.com:javaworld.com
·Matrix-Java开发者社区:http://www.matrix.org.cn/

Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd

标签: