1 单元测试基础
1.单元测试:单元测试又称模块测试,属于白盒测试,是最小单位的测试。模块分为程序模块和功能模块。功能模块指实现了一个完整功能的模块(单元),一个完整的程序单元具备输入、加工和输出三个环节。而且每个程序单元都应该有正规的规格说明,使之对其输入、加工和输出的关系做出名明确的描述。
2.测试驱动:驱动被测试模块正常运行起来的实体
3.测试桩:代替被测模块调用的子模块的实体,该实体一般为桩函数。
4.测试覆盖:评测测试过程中已经执行的代码的多少。
5.覆盖率:代码的覆盖程度,一种度量方式。针对代码的测试覆盖率有许多种度量方式,定义如下:
- 语句覆盖:也称为行覆盖,段覆盖和基本块覆盖。它度量每一个可执行语句是否被执行到了。
- 判定覆盖:也被称为分支覆盖,所有边界覆盖,基本路径覆盖,判定路径覆盖。它度量是否每个BOO型的表达式取值true和false在控制结构中都被测试到了。
- 条件覆盖:它独立的度量每一个子表达式,报告每一个子表达式的结果的true或false。这个度量和判定覆盖相似,但是对控制流更敏感。不过,完全的条件覆盖并不能保证完全的判定覆盖。
- 路径覆盖:也称为断言覆盖,它度量了是否函数的每一个可能的分支都被执行了。路径覆盖的一个好处是:需要彻底的测试。但有两个缺点:一是,路径是以分支的指数级别增加的,例如:一个函数包含10个IF语句,就有1024个路径要测试。如果加入一个IF语句,路径数就达到2048;二是,许多路径不可能与执行的数据无关。
- 循环覆盖:这个度量报告你是否执行了每个循环体零次、只有一次还是多余一次(连续地)。对于do-while循环,循环覆盖报告你是否执行了每个循环体只有一次还是多余一次(连续地)。这个度量的有价值的方面是确定是否对于while循环和for循环执行了多于一次,这个信息在其它的覆盖率报告中是没有的。
2 测试的环境构成
何时进行单元测试?单元测试在编码阶段进行。在源程序代码编制完成、经过评审和验证、确认没有语法错误之后,就可以开始进行单元测试的测试用例设计。要利用软件设计文档,设计可以验证程序功能、找出程序错误的多个测试用例。
对于每一组输入,应该有预期的正确结果。在单元测试时,如果模块不是独立的程序,需要辅助测试模块,有两种辅助模块:
- 驱动模块(Driver):所测模块的主程序。它接收测试数据,把这些数据传递给所测试模块,最后再输出测试结果。当被测试模块能完成一定功能时,也可以不要驱动模块。
- 桩模块(Stub):用来代替所测模块调用的子模块。
3 测试方法和过程
3.1 测试用例设计
1.测试用例的组成(在单元测试中测试用例基本上由测试脚本组成)
用例运行前置条件
被测模块/单元所需环境(全局变量赋值或初始化实体)
启动测试驱动
设置桩
调用被测模块
设置预期输出条件判断
恢复环境(包括清除桩)
2.测试用例的设计原则
一个好的测试用例在于能够发现至今没有发现的错误;
测试用例应由测试输入数据和与之对应的预期输出结果这两部分组成;
在测试用例设计时,应当包含合理的输入条件和不合理的输入条件;
为系统运行起来而设计测试用例;
为正向测试而设计测试用例;
为逆向测试而设计测试用例;
为满足特殊需求而设计测试用例;
为代码覆盖而设计测试用例;
3.用例设计方法
-
规范(规格)导出发
-
等价类划分法
-
边界值分析法
-
状态转移测试法
-
分支测试法
-
条件测试法
-
数据定义-使用测试法(又名数据流测试法)
-
内部边界值测试法
-
错误猜测法
- 特定的用例测试设计
1)声明测试:检查模块中的所有变量是否被声明。经验表明,大量重要的错误都是由于变量没有被声明或没有被正确的声明而引起的。
2)路径测试:要求模块中所有可能的路径都被执行一遍,属逻辑覆盖测试。
基本路径测试:由于实际中,一个模块中的路径可能非常多,由于时间和资源有限,不可能一一测试到。这就需要把测试所有可能路径的目标减少到测试足够多的路径,以获得对模块的信心。要测试的最小路径集就是基本测试路径集。基本测试路径集要保证:
每个确定语句的每一个方向要测试到;
每条语句最少执行一次。
3)循环测试:重点检查循环的条件-判断部分以及边界条件。测试循环是一种特殊的路径测试,因为循环比其他语句都复杂一些。循环中错误的发生机会比其他代码构成部分多。因此,对于任何给定的循环测试应该包括测试下面每一条件的测试用例:
循环不执行;
执行一次循环;
执行两次循环;
反映执行典型的循环的执行次数;
如果有最大循环次数,最大循环次数减1;
最大循环次数;
大于最大循环次数。
对于增量和减量不是1的FOR语句,要特别注意,因为程序员习惯于增量1。
- 循环嵌套:循环嵌套使逻辑的次数呈几何级数增长,设计测试嵌套循环的测试用例应该包括的测试条件有:
把外循环设置为最小值,并运行内循环所有可能的情况;
把内循环设置为最小值,并运行外循环所有可能的情况;
把所有的循环变量都设置为最小值运行;
把所有的循环变量都设置为最大值运行;
把外循环设置为最大值,并运行内循环所有可能的情况;
把内循环设置为最大值,并运行外循环所有可能的情况;
- 边界值测试:指程序内部边界测试。检查确定代码在任何边界情况下都不会出差错。重点检查小于、等于和大于边界条件的情况。边界值测试是指专门设计用来测试当条件语句中引用的值处在边界或边界附近时系统反映的测试。被测试语句的最好的例子就是"IF-THEN...ELSE-ENDIF"部分。这样语句的例子如:
IF a <= 123 THEN
b = 1
ELSE IF a >= 123 THEN
b = 2
ELSE b = 3
END IF
上面例子中的边界值测试用例应该至少包括a的以下值:122,123,124。当a=123时,b=1还是2。(找出逻辑判断的矛盾)
6)接口测试:检查模块的数据流(输入、输出)是否正确。检查输入的参数和声明的自变量的个数,数据类型和输入顺序是否一致。检查全局变量是否被正确的定义和使用等。
7)确认测试:是否接受有效输入数据(操作),拒绝无效数据(操作)。
8)事务测试:输入->输出,错误处理。
3.2测试用例执行
一般来说,做单元测试均采用的是商用的测试工具或自行开发的测试工具,用例的编写都是在测试工具上完成,测试用例都是一些测试脚本,都以文件的方式来保存,故其用例的执行过程主要是由测试工具根据所编写的具体的测试用例脚本来完成,这样对于用例的管理和执行也非常灵活。
在特定场合,比如某种压力测试或极限测试,对于测试执行过程时间很长时(几个小时以上),一般都预先编写好用例(确保用例无误),使用空闲机或非工作时间执行测试用例,这样操作起来较节约时间。
在用例的执行过程中务必注意如下事项:
程序的执行过程―――便于构造发散用例
不要放过任何细节―――这种细节可能就是问题
3.3测试优化和策略
在测试的过程中为了提高测试效率和效果,不断的减少冗余劳动,也为后期的回归测试和测试管理带来很大的方便,不至于感到测试很混乱无序。因此我们要对测试用例和测试执行进行不断的优化,以测试策略为指导方针进行测试。
1、测试用例的优化
测试用例的优化主要是指用例的合并、修改和删除,减少冗余的无价值的测试,其优化依据来源于测试后的测试数据分析和评估,其中测试覆盖也是用例优化的主要参考。
2、测试执行的优化
测试执行的优化主要是指测试步骤的优化,减少测试人员的手工操作,因为太多的手工操作会导致测试人员很厌倦,直接影响测试效果,优化依据来源于测试总结。
3、测试策略
在测试过程中由于时间或资源的原因可能会使测试处于紧张的局面,在此情况下我们要采取一定的策略来解决此局面。策略来源于测试数据的分析,主要的方法是:为各模块制定测试优先级,其优先级的划分依据如下:
哪些是重点模块?
哪些程序是最复杂、最容易出错的?
哪些程序是相对独立,应当提前测试的?
哪些程序最容易扩散错误?
哪些程序是开发者最没有信心的?
80-20原则:80%的缺陷聚集在20%的模块中,经常出错的模块改错后还会经常出错,这种应该列入测试重点。
3.4 测试评估
单元测试完成以后,需要对单元测试的执行效果进行评估,主要从以下几方面进行:
1)测试完备性评估,主要检查测试过程中是否已经执行了所有的测试用例,对新增的测试用例是否已及时更新测试方案等。
2)代码覆盖率评估,主要是根据代码覆盖率工具提供的语句覆盖情况报告,检查是否达到方案中的要求,公司要求语句覆盖达到100%。但很多情况下,第一轮测试用例执行完后是很难达到的,这时在评估过程中要对覆盖率进行分析,主要从以下方面来考虑:
不可能的路径或条件
不可达的或冗余的代码
不充分的测试用例
- 从覆盖的角度看,测试应该覆盖:
功能覆盖
输入域覆盖
输出域覆盖
函数交互覆盖
代码执行覆盖
大多数有效的测试用例都来自于分析,而不是仅仅为了达到测试覆盖率目标而草率设计测试用例。千万不要误解测试覆盖,测试覆盖并不是我们最求的目的,它只是评价测试的一种方式,为测试提供指导和依据。
3.5测试过程
1.测试过程中各种人员的作用
系统分析设计人员
进行需求跟踪,确保系统需求的实现和更新。进行软件单元可测性分析,确定单元测试的对象、范围和方法。
软件开发人员
负责编码和单元测试过程,完成单元测试计划、方案和报告。
软件测试人员
参与单元测试计划、方案和报告的评审,对单元测试的计划、设计和执行质量进行监控。根据实际情况,可选择参与由开发人员负责的代码检视、单元测试等活动。
配置管理人员
对代码及单元测试文档进行配置管理。
质量保证(QA)人员
参与编码与单元测试评审,对编码和单元测试过程进行审计。
- 单元测试输入
《软件需求规格说明书》
《软件详细设计说明书》
《软件编码与单元测试工作任务书》
《软件集成测试计划》
《软件集成测试方案》
用户文档
3.单元测试的输出
《单元测试计划》
《单元测试方案》
《需求跟踪说明书》或需求跟踪记录
代码静态检查记录
《正规检视报告》
问题记录
问题跟踪和解决记录
软件代码开发版本
《单元测试报告》
《软件编码与单元测试任务总结报告》
3.6测试实施
- 单元测试实施步骤
-
制定测试计划和测试方案(包括测试工具的选择)
-
根据计划和方案及相关输入文档编写测试用例
-
搭建测试环境
-
执行测试
-
记录和跟踪问题
-
编写测试报告和总结报告
- 单元测试实施遵循的原则
精心制定测试计划
严格评审测试计划
严格执行测试计划
系统分析测试结果并提交报告
4 常用测试工具
常用的C语言单元测试工具介绍如下:
1.VcTester
1)简介
VcTester是与VC(注:Visual C++及Visual Studio开发套件是微软发布的产品)配套使用的新一代单元测试工具,分共享版与商用版两大系列,其主要功能包括:脚本化测试驱动(包括修改变量与调用函数)、脚本桩、支持持续集成测试、测试覆盖率统计(仅商用版本)、生成测试报告(仅商用版本)、测试消息编辑器(仅商用版本)等。
2)功能特性
脚本化测试驱动
脚本桩
在线测试
即时调测
测试工程管理
2.C++Test
1)简介
C++Test是一个功能强大的自动化C/C++单元级测试工具,可以自动测试任何C/C++函数、类,自动生成测试用例、测试驱动函数或桩函数,在自动化的环境下极其容易快速的将单元级的测试覆盖率达到100%。
2)功能特性
即时测试类/函数
支持极端编程模式下的代码测试
自动建立类/函数的测试驱动程序和桩调用
自动建立和执行类/函数的测试用例
提供快速加入和执行说明和功能性测试的框架
执行自动回归测试
执行部件测试(COM)