必须说明的是,对这本《软件测试方法和技术》,我个人的评价应该是不错的,在体系结构和组织上都比较清晰,包含的内容也比较完整。缺点可能是过于中规中举了(个人看法:)),和国内的其他教科书一样,没有多少引申和深入的描述。因此,本文仅用来阐述个人对单元测试的观点,不涉及任何对该书或是作者的评价。
《软件测试方法和技术》中对单元测试的描述原文如下(P86):
“单元测试是对软件基本组成单元的测试。单元测试的对象是软件设计的最小单位——模块。很多参考书中将单元测试的概念误导为一个具体函数或一个类的方法。一个最小的单元应该有明确的功能、性能定义、接口定义而且可以清晰地与其他单元区分开来。一个菜单、一个显示界面或者能够独立完成的具体功能都可以是一个单元。某种意义上单元的概念已经扩展为组件(component)。”
其实这里的观点我大部分都同意,就是对“很多参考书中将单元测试的概念误导为一个具体函数或一个类的方法”的说法有些存疑。毫无疑问,作者的观点是,单元测试不应该是针对具体函数和类的方法的测试,接下来作者说明了他对单元的理解:“一个最小的单元应该有明确的功能、性能定义、接口定义而且可以清晰地与其他单元区分开来”,对这个单元的理解我完全同意,但困扰我的就是,我并没有从这个定义中看出来一个具体函数不能作为单元测试中“单元”的理由。这段文字中提到单元是“具有明确的功能定义、性能定义、接口定义”,那我们来看看一个具体的函数,例如,C语言中的printf函数,一样可以套用这样的定义:
printf函数
功能定义:将输入参数按照制定的格式打印输出
性能定义:(略,不同平台上应该有不同的性能标准)
接口定义:可用函数的参数作为函数对外的接口
另外,这段文字中提到的“一个菜单、一个显示界面或者能够独立完成的具体功能都可以是一个单元”,在我看来仍然有些含糊——具体什么才是“能够独立完成的具体功能”,我想这里的“功能”不可能对应到具体的用户需求中的功能,而是指设计中体现的功能,如果是这个概念,那么一个函数毫无疑问是具有功能的。
为了慎重,我特地查阅了一些经典的软件测试书和定义中的单元测试内容,以下是引用和我的理解。
swebok 2004应该算得上是软件工程领域的权威性文档了,其中对unit testing的定义如下:
“Unit testing verifies the functioning in isolation of software pieces which are separately testable. Depending on the context, these could be the individual subprograms or a larger component made of tightly related units.”
从这里可以看到,swebok 2004对unit的定义具有这些特性:一个单元是一个“software pieces”,具有“separately testable”的特性,从这个角度来说,并没有任何理由支持一个函数不能是单元测试对象的论据。而且,swebok 2004还明确说明了,在不同的上下文中,unit可以是子程序,也可以是紧密联系的一些单元组成的component。
《统一软件开发过程》中也对单元测试进行了描述(P223):
“执行单元测试的目的是为了把已实现的构件作为个体单元进行测试,主要有以下几类单元测试:
规格说明测试(specification testing)或“黑盒测试”,验证单元外观上的可观察的行为;
结构测试(structure testing)或“白盒测试”,验证单元的内部实现”
这里的关键问题在于上文中“构件”的概念,构件是RUP实现过程中的产物,在该书的P207中给出了构件的定义:“构件是模型元素(如设计模型中的设计类)的物理包”,可见,根据这样的描述,将一个类或是一段代码片断作为单元测试的目标绝对是RUP所认可的。
文章来源于领测软件测试网 https://www.ltesting.net/