分类:
2008-10-15 16:42:38
摘要
这篇文章主要阐述这样一个问题:为什么要进行烦人的单元?那些刚刚接触完全概念的开发人员常常遇到这个问题。我们这里将采用"反调论证"的方法来回答这个问题,先提出一些反对单元测试的普遍论点, 然后我们会证明这些论点是站不住脚的。 那些公开发表的文章和数据充分证实了单元测试的有效性。
IPL是一个独立的软件开发机构, 成立于1979年, 基地设在Bath。 IPL在1988年通过了ISO9001认证, 并在1991年通过Tick。 IPL开发并提供AdaTEST和Cantata等软件验证产品。
AdaTEST和Cantata的开发遵循了这些标准的要求。
1。 简介
在使新的产品和业务的开发过程工业化的尝试中, 软件的质量和可靠性常常被看作是薄弱环节。
在最近的十年里, 随着越来越多的人在开发过程中采用了设计方法论和使用CASE工具, 软件质量和可靠性的问题越来越受到重视。
大多数软件设计人员都接受了这方面的培训, 并且在这些正规的软件设计方法的使用中取得了很多经验。
但不幸的是, 软件测试并没有得到同样的重视。 很多使用这些软件设计方法的开发活动并没有使软件质量和可靠性得到控制。
修改最初的软件开发活动遗留的Bug一般要在软件维护费用中占到50%的比例, 这是不正常的, 这些Bug应该在有效的软件测试过程中被排除掉。
这篇文章主要阐述这样一个问题:为什么要进行烦人的单元测试?那些刚刚接触完全测试概念的开发人员常常遇到这个问题。我们这里将采用"反调论证"的方法来回答这个问题,
先列出一些反对单元测试的普遍论点, 然后我们会证明这些论点是站不住脚的。 那些公开发表的文章和数据充分证实了单元测试的有效性。
2。 什么是单元测试
单元测试是在软件开发过程中要进行的最低级别的测试活动, 在单元测试活动中, 软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。
在一种传统的结构化编程语言中, 比如C, 要进行测试的单元一般是函数或子过程。 在象这样的面向对象的语言中, 要进行测试的基本单元是类。
对Ada语言来说, 开发人员可以选择是在独立的过程和函数, 还是在Ada包的级别上进行单元测试。
单元测试的原则同样被扩展到第四代语言(4GL)的开发中, 在这里基本单元被典型地划分为一个菜单或显示界面。
单元测试不仅仅是作为无错编码一种辅助手段在一次性的开发过程中使用。单元测试必须是可重复的, 无论是在软件修改, 或是移植到新的运行环境的过程中。
因此, 所有的测试都必须在整个软件系统的生命周期中进行维护。
经常与单元测试联系起来的另外一些开发活动包括代码走读(Code review), 静态分析(Static analysis)和动态分析(Dynamic analysis)。 静态分析就是对软件的源代码进行 研读, 查找错误或收集一些度量数据,
并不需要对代码进行编译和执行。 动态分析就是通过观察软件运行时的动作, 来提供执行跟踪, 时间分析, 以及测试覆盖度方面的信息。
3。 一些流行的误解
在明确了什么是单元测试以后, 我们可以进行"反调论证"了。 在下面的章节里, 我们列出了一些反对单元测试的普遍的论点。
然后用充分的理由来证明这些论点是不足取的。
3.1 它浪费了太多的时间
一旦编码完成, 开发人员总是会迫切希望进行软件的集成工作, 这样他们就能够看到实际的系统开始启动工作了。 这在外表上看来是一项明显的进步,
而象单元测试这样的活动也许会被看作是通往这个阶段点的道路上的障碍, 推迟了对整个系统进行联调这种真正有意思的工作启动的时间。
在这种开发步骤中, 真实意义上的进步被外表上的进步取代了。 系统能够正常工作的可能性是很小的, 更多的情况是充满了各式各样的Bug。 在实践中,
这样一种开发步骤常常会导致这样的结果:软件甚至无法运行。 更进一步的结果是大量的时间将被花费在跟踪那些包含在独立单元里的简单的Bug上面,
在个别情况下, 这些Bug也许是琐碎和微不足道的, 但是总的来说, 他们会导致在软件集成为一个系统时增加额外的工期,
而且当这个系统投入使用时也无法确保它能够可靠运行。
在实践工作中, 进行了完整计划的单元测试和编写实际的代码所花费的精力大致上是相同的。 一旦完成了这些单元测试工作, 很多Bug将被纠正,在确信他们手头拥有稳定可靠的部件的情况下, 开发人员能够进行更高效的系统集成工作。 这才是真实意义上的进步,所以说完整计划下的单元测试是对时间的更高效的利用。 而调试人员的不受控和散漫的工作方式只会花费更多的时间而取得很少的好处。
使用AdaTEST和Cantata这样的支持工具可以使单元测试更加简单和有效。 但这不是必须的,单元测试即使是在没有工具支持的情况下也是一项非常有意义的活动。
3.2 它仅仅是证明这些代码做了什么
这是那些没有首先为每个单元编写一个详细的规格说明而直接跳到编码阶段的开发人员提出的一条普遍的抱怨, 当编码完成以后并且面临代码测试任务的时候,
他们就阅读这些代码并找出它实际上做了什么, 把他们的测试工作基于已经写好的代码的基础上。 当然, 他们无法证明任何事情。
所有的这些测试工作能够表明的事情就是编译器工作正常。 是的, 他们也许能够抓住(希望能够)罕见的编译器Bug, 但是他们能够做的仅仅是这些。
[1]