370 likes | 618 Views
单元测试. 软件外包教研室. 第 5 章 单元测试 . 5.1 单元测试的基本概念 5.2 单元测试的目的 5.3 为什么要进行单元测试 5.3 单元测试过程 5.4 单元测试坚持原则 5.5JUnit 的介绍和使用. 单元测试的基本概念 . 单元测试时一种细粒度的测试。又称模块测试,属于白盒测试,是最小单位的测试。 模块分为程序模块和功能模块。. 测试的内容 . 单元测试的对象是软件设计的最小单位 —— 模块或函数,单元测试的依据是详细设计描述。 . 测试的内容. 模块接口 局部数据结构测试 路径测试 错误处理测试 边界测试 . 模块接口.
E N D
单元测试 软件外包教研室
第5章 单元测试 5.1 单元测试的基本概念 5.2单元测试的目的 5.3为什么要进行单元测试 5.3单元测试过程 5.4单元测试坚持原则 5.5JUnit的介绍和使用 wangchunxiu@ccniit.com
单元测试的基本概念 • 单元测试时一种细粒度的测试。又称模块测试,属于白盒测试,是最小单位的测试。 • 模块分为程序模块和功能模块。 wangchunxiu@ccniit.com
测试的内容 • 单元测试的对象是软件设计的最小单位——模块或函数,单元测试的依据是详细设计描述。 wangchunxiu@ccniit.com
测试的内容 • 模块接口 • 局部数据结构测试 • 路径测试 • 错误处理测试 • 边界测试 wangchunxiu@ccniit.com
模块接口 • 调用所测模块的输入参数与模块的形式参数在个数、属性、顺序上是否匹配; • 所测模块调用子模块时,它输入个子模块的参数与子模块的形式参数在个数、属性、顺序上是否匹配; • 是否修改了只做输入用的形式参数; • 输出给标准函数的参数在个数、属性、顺序上是否匹配; • 全局变量的定义在各模块中是否一致; • 限制是否通过形式参数来传送。 wangchunxiu@ccniit.com
局部数据结构测试 • 检查不正确或不一致的数据类型说明; • 使用尚未赋值或尚未初始化的变量; • 错误的初始值或错误的默认值; • 变量名拼写错误或书写错误; • 不一致的数据类型。 wangchunxiu@ccniit.com
路径测试 • 常见的不正确的计算有: • 运算的优先次序不正确或误解了运算的优先次序; • 运算的方式错误(运算的对象彼此在类型上不相容); • 算法错误; • 初始化不正确; • 运算精度不够; • 表达式的符号表示不正确等。 wangchunxiu@ccniit.com
路径测试 • 常见的比较和控制流错误有: • 不同数据类型的比较; • 不正确的逻辑运算符或优先次序; • 因浮点运算精度问题而造成的两值比较不等; • 关系表达式中不正确的变量和比较符; • “差1错”,即不正确地多循环或少循环一次; • 错误的或不可能的循环终止条件; • 当遇到发散的迭代时不能终止循环; • 不适当地修改了循环变量等。 wangchunxiu@ccniit.com
错误处理测试 • 出错的描述难以理解; • 出错的描述不足以对错误定位和确定出错的原因; • 显示的错误与实际的错误不符; • 对错误条件的处理不正确; • 在对错误进行处理之前,错误条件已经引起系统的干预; • 如果出错情况不予考虑,那么检查恢复正常后模块可否正常工作。 wangchunxiu@ccniit.com
边界测试 • 在n次循环的第0次、1次、n次是否有错误; • 运算或判断中取最大最小值时是否有错误; • 数据流、控制流中刚好等于、大于、小于确定的比较值时是否出现错误。 wangchunxiu@ccniit.com
单元测试的环境构成 • 在单元测试时,如果模块不是独立的程序,需要辅助测试模块,有两种辅助模块: • 驱动模块(Driver) • 桩模块(Stub) wangchunxiu@ccniit.com
主要单元测试方法 • 人工静态分析 • 自动静态分析 • 自动动态测试 • 人工动态测试 wangchunxiu@ccniit.com
单元测试主要目的 • 测试的目的有很多,Grenford J.Myers 认为软件测试的目的在于发现错误; • 一个好的测试用例在于发现至今未发现的错误;一个成功的测试是发现了至今未发现的错误的测试。 • 从现代软件工程的角度来看,软件的开发质量是从过程上进行保证的。 • 如果说进行编码前已经能很大程度上保证详细设计的质量,那么做单元测试时就不仅仅要检测代码的错误,而需要测试代码是否是根据详细的设计进行的。 wangchunxiu@ccniit.com
单元测试主要目的 单元测试的主要目的主要有: • 验证代码是与设计相符合的; • 跟踪需求和设计的实现; • 发现设计和需求中存在的错误; • 发现设计和需求中存在的错误; • 发现在编码过程中引入的错误。 wangchunxiu@ccniit.com
为什么要进行单元测试呢? • 对于单元测试的一些错误认识 • 单元测试的重要性 • 单元测试的优点 wangchunxiu@ccniit.com
对于单元测试的一些错误认识 • 太浪费时间了,现在要赶进度,时间上根本不允许,或者随便做做应付领导。 • 我是一个很棒的程序员,我写的代码肯定是没有问题的。 • 做单元测试太烦了,直接集成,到时有问题在集成测试时肯定能发现的,实在不行在系统测试总该能发现吧。 • 它仅仅是证明这些代码做了什么。 wangchunxiu@ccniit.com
单元测试的重要性 • 单元测试是软件测试的基础,主要目的是验证你的应用程序能够很好的工作,以及尽早的发现错误。 • 时间方面 • 测试效果 • 测试成本 • 产品质量 wangchunxiu@ccniit.com
单元测试具有的优点 • 它是一种验证行为。 • 它是一种设计行为。 • 它是一种编写文档的行为。 • 它具有回归性。 wangchunxiu@ccniit.com
单元测试过程 • 测试过程中各种人员的作用 • 单元测试输入 • 单元测试的输出 wangchunxiu@ccniit.com
测试过程中各种人员的作用 • 系统分析设计人员 • 进行需求跟踪,确保系统需求的实现和更新。进行软件单元可测性分析,确定单元测试的对象、范围和方法。 • 软件开发人员 • 负责编码和单元测试过程,完成单元测试计划、方案和报告。 • 软件测试人员 • 参与单元测试计划、方案和报告的评审,对单元测试的计划、设计和执行质量进行监控。根据实际情况,可选择参与由开发人员负责的代码检视、单元测试等活动。 • 配置管理人员 • 对代码及单元测试文档进行配置管理。 • 质量保证(QA)人员 • 参与编码与单元测试评审,对编码和单元测试过程进行审计。 wangchunxiu@ccniit.com
单元测试输入 • 《软件需求规格说明书》 • 《软件详细设计说明书》 • 《软件编码与单元测试工作任务书》 • 《软件集成测试计划》 • 《软件集成测试方案》 • 用户文档 wangchunxiu@ccniit.com
单元测试的输出 • 《单元测试计划》 • 《单元测试方案》 • 《需求跟踪说明书》或需求跟踪记录 • 代码静态检查记录 • 《正规检视报告》 • 问题记录 • 问题跟踪和解决记录 • 软件代码开发版本 • 《单元测试报告》 • 《软件编码与单元测试任务总结报告》 wangchunxiu@ccniit.com
单元测试坚持的原则(一) • 对于全新的代码和修改过的代码进行单元测试; • 被测试的对象为实现一组相关功能的代码(一个或者一组函数); • 单元测试根据单元测试计划和方案进行,排除测试的随意性; • 项目管理者保证测试用例经过审核; wangchunxiu@ccniit.com
单元测试坚持原则(二) • 当测试用例的测试结果与预期的结果不一致时,单元测试的执行人员需要如实记录实际的测试结果; • 当测试计划中的结束标准达标时,单元测试结束; • 对被测试单元需要达到的一定的代码覆盖率要求; • 当程序进行了修改,则测试执行人员执行回归测试以保证对发现错误的修改没有引入新的错误。 wangchunxiu@ccniit.com
JUnit的介绍和使用 JUnit是一个开源的java单元测试框架。在1997年,由 Erich Gamma 和 Kent Beck 开发完成。JUnit设计的非常小巧,但是功能却非常强大。 wangchunxiu@ccniit.com
下面是JUnit一些特性的总结: • 提供的API可以让你写出测试结果明确的可重用单元测试用例 • 提供了三种方式来显示你的测试结果,而且还可以扩展 • 提供了单元测试用例成批运行的功能 • 超轻量级而且使用简单,没有商业性的欺骗和无用的向导 • 整个框架设计良好,易扩展 wangchunxiu@ccniit.com
JUnit简单使用 • 在这里,我们从一个简单例子入手。这是一个只会做两数加减的超级简单的计算器。代码如下: public class SampleCalculator { public int add(int augend , int addend) { return augend + addend ; } public int subtration(int minuend , int subtrahend) { return minuend - subtrahend ; } } wangchunxiu@ccniit.com
下面就是为上面程序写的一个单元测试用例: import junit.framework.TestCase; public class TestSample extends TestCase { public void testAdd() { SampleCalculator calculator = new SampleCalculator(); int result = calculator.add(50 , 20); assertEquals(70 , result); } } wangchunxiu@ccniit.com
在DOS命令行里面输入javac TestSample.java 将测试类编译通过。然后再输入 java junit.swingui.TestRunner TestSample 运行测试类,你会看到如下的窗口。 wangchunxiu@ccniit.com
绿色说明单元测试通过,没有错误产生;如果是红色的,则就是说测试失败了。这样一个简单的单元测试就完成了. wangchunxiu@ccniit.com
按照框架规定:编写的所有测试类,必须继承自junit.framework.TestCase类;里面的测试方法,命名应该以Test开头,必须public void 而且不能有参数;而且为了测试查错方便,尽量一个TestXXX方法对一个功能单一的方法进行测试;使用assertEquals等junit.framework.TestCase中的断言方法来判断测试结果正确与否。 wangchunxiu@ccniit.com
本章小结 • 单元测试不但保证局部代码的质量,同时使开发过程自然而然地变得"敏捷"。单元测试对项目或产品的整个生命周期都具有积极的影响: • 对需求分析、设计的影响:自动回归测试可以发现代码修改所引入的错误,使开发过程可以适应频繁变化的需求,减轻需求分析和架构设计的压力,轻松实现螺旋式的开发过程。 • 对后期测试的影响:由于代码错误已很少,大幅减少集成测试和系统测试的成本,自动回归测试也使修正错误的成本大量降低。对维护、升级的影响:高质量的产品大量降低维护费用,另一方面,升级相当于需求的增加或变化,自动回归测试也会产生重要的作用。实施或改进单元测试,是低投入、高效益的技术进步,将极大地提升软件企业和软件产品的竞争力。 wangchunxiu@ccniit.com