单元测试是对软件基本组成单元/模块进行的测试,又称为模块测试。基本单元/模块可以是函数、类实例、方法、存储过程,也可以是任何具有明确功能、规格定义、明确接口定义、并且其规模是一般比较小的程序代码模块的组合体。
1、概述
单元测试是对软件基本组成单元/模块进行的测试,又称为模块测试。基本单元/模块可以是函数、类实例、方法、存储过程,也可以是任何具有明确功能、规格定义、明确接口定义、并且其规模是一般比较小的程序代码模块的组合体。
单元测试的重点在于发现程序设计或实现的逻辑错误,使问题及早暴露,便于问题的定位解决。
单元测试中多采用白盒测试和黑盒测试相结合的方法,既关注单元功能,也关注程序模块的逻辑结构。两者结合起来,既可以避免由于过多关注路径而导致测试工作量很大的问题,又可以避免因从外部设计测试用例而可能丢失一些路径的问题。
现今,更多观点认为单元测试应该由编码人员实施,笔者认为这种观点是有道理的。毕竟由测试人员实施单元测试比编码人员实施的工作量更大。当然,如果对于测试航空、航天、医疗等关系重大生命、财产的软件系统来说,需要投入大量的资源来保证系统质量时,则可以采用测试人员实施单元测试的策略。
单元测试的重点应该以功能测试为主,同时统计测试的覆盖率,并且测试模块的输入/输出接口是否正确,内部的数据流是否正确等。
功能测试主要测试模块是否正确实现了设计要求的功能,以及有无遗漏的功能。这里有一个功能覆盖的概念。因为被测试模块可能包括多个功能点,在做测试时,设计测试用例要覆盖这些功能点,以保证这些功能点经过测试。一般要求功能覆盖100%。
覆盖率一般要求进行语句覆盖率和分支覆盖率,同时要求测试所有的关键路径。关键路径的表达不是很明确,但是如果要求做基本路径集覆盖测试,即使是一个比较小的模块也是很难做到的。如果使用单元测试工具(如CppUnit、Junit等),则可以统计覆盖率。
单元测试结束后,如果有些分支由于各种条件无法覆盖,则需要给出原因说明。
2、单元测试的步骤
单元测试过程包括计划、设计、执行、评审等几个步骤,分别如下所述。
① 计划:确定测试需求,制订测试策略,确定测试所用资源(如人员、设备等),创建测试任务的时间表。这部分工作可以简单描述。
② 设计:设计单元测试模型,制订测试方案,制订具体的测试用例,创建可重用的测试脚本。
③ 执行:执行测试用例,对单元模块进行测试,验证测试的结果并记录测试过程中出现的缺陷。
④ 评审:对单元测试的结果进行评审。主要进行测试完备性评估。
由于单元模块往往不是一个独立的程序,在设计时,要考虑单元模块同其他模块的联系,用桩模块和驱动模块模拟所测模块相联系的其他模块。由被测试模块、驱动模块和桩模块共同构成可运行的程序。
驱动模块和桩模块的定义如下所述。
驱动模块:相当于被测试模块的主程序,用于接收数据或产生数据,把数据传递给被测试模块,再输出实测结果,或把实测结果同预期结果进行比对。
桩模块:也称为存根模块。用以代替被测试模块调用的子模块。桩模块可以用做数据处理,不需要把模块的所有功能都模拟,可以简单地返回一个值。
3、单元测试的内容
1)单元功能测试
单元功能测试的内容如下:
- 单元设计的功能点是否全部实现。
- 运算的优先级和先后执行顺序是否正确。
- 计算中精度的处理是否正确。
- 计算中的误差是否会无限放大。
2)模块接口测试
在单元测试的开始,应对所测模块的数据流进行测试。如果数据不能正确地输入和输出,就不能进行其他测试。
对模块接口可能需要进行下面的测试外包项目:
- 调用所测模块时的输入参数与模块的形式参数在个数、属性、顺序上是否匹配。
- 所测模块调用子模块时,它输入给子模块的参数与子模块的形式参数在个数、属性、顺序上是否匹配。
- 是否修改了只做输入用的形式参数。
- 输出给标准函数的参数在个数、属性、顺序上是否正确。
- 全局变量的定义在各模块中是否一致。
- 限制是否通过形式参数来传送。
- 模块对外部文件、数据库进行输入/输出时,必须对文件操作进行测试。例如,缓冲区的大小、是否在读写文件前打开文件,在结束前关闭文件等。
3)内部数据流测试
内部数据流测试包括以下几点:
- 不正确或不一致的数据类型说明。
- 使用尚未赋值或尚未初始化的变量。
- 错误的初始值或错误的默认值。
- 变量名拼写错误或书写错误。
- 不一致的数据类型。
- 全局变量对模块是否产生影响。
4)逻辑路径测试
逻辑路径测试包括以下几点:
- 是否到达重要的功能点路径。
- 逻辑判断的边界点是否正确。
- 异常/错误处理。
- 比较完善的模块设计要求能预见异常或出错的条件,并设置适当的异常处理和出错处理,以便在程序出现异常或错误时,能对出错程序重新进行安排,保证逻辑上的正确性。重点应该考虑下面几个问题:
- 异常或出错的描述是否可以理解。
- 异常处理是否合理、出错后对错误的定位是否准确。
- 提示的错误与实际的错误是否一致。
- 对错误条件的处理是否正确。
以上提到的很多内容在编码规范或代码检查单中大多已经包含,如果模块在进入单元测试之前,已经进行了桌前检查和同行评审,则模块中潜在的缺陷就可能比较少。
4、单元测试用例设计
单元测试中几乎可以运用所有测试用例设计方法。
单元测试过程如下所述。
① 单元模块运行设计第一个测试用例。第一个测试用例一般是使用最简单的方法执行被测单元。当这个用例可以执行时,就能确定测试环境和测试单元是可用的。
② 设计被测试单元测试用例。阅读相关的设计说明,每一个测试用例就是通过有针对性地测试说明书中的一项或者多项内容,用以验证设计说明书所对应的功能是否实现。
③ 设计测试功能异常处理方面的测试用例。用可能导致模块功能失效的无效数据,测试模块对无效数据的反应是否合理,以及对异常或错误的处理后模块的反应如何,验证模块有没有做不应该做的工作。
④ 设计其他的测试用例,验证设计对模块的要求。例如计算精度、性能、可恢复性、安全性等。
⑤ 加载测试用例运行程序,需要查看和记录测试结果,尤其是测试结果与预期结果不一致的情况。
⑥ 补充测试用例,执行前面测试用例运行没有覆盖到的主要分支和 语句。
⑦ 重复上面的1~6步,直到功能覆盖、主要逻辑覆盖、异常条件和边界覆盖等。
希望通过本文对单元测试的介绍,能够给你带来帮助。