软件项目中的基础测试
单元测试(UT)
什么是单元测试
• 单元测试(又称为模块测试)是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等。
单元测试流程
• 在传统软件开发过程中,单元测试是在编写完模块代码后开始进行的。基本流程是:1.模块设计;2.编写模块;3.设计测试用例;4.进行单元测试。
• 在敏捷开发中,倡导测试驱动的方法。所以在单元测试中的流程有所不同。在测试驱动中的单元测试的基本流程:1.概据模块功能需求设计测试用例;2.模块设计;3.编程模块;4.进行单元测试。
• 在1和2的顺序中可以并行来做。
单元测试的好处
• 单元测试提供了系统的一种文档记录。借助于查看单元测试提供的功能和单元测试中如何使用程序单元,开发人员取得了程序单元API的基础直观的理解。
• 通过单元测试能保证模块是可运行的,增加了程序员对自己编写的模块提交的自信。
单元测试中的覆盖率
• 单元测试中一个最重要的指标就是代码测试覆盖率。其中包括:代码语句覆盖率;程序分支覆盖率和子模块覆盖率。
• 在单元测试中覆盖率原则上是越高越好。但在项目开发过程中又有成本(包括人力,物力,时间)的限制。所以在进行在覆盖率和成本上需要有个很好的平衡点。
• 在单元测试中可以先针对被测试的模块代码进行分类。
• 1.必须测试的。
• 2.可以测试的。
• 3.测试不到的。
• 必须测试的是程序的主体结构。模块要实现的功能和流程。还要一些基本的异常处理代码。
• 这部分的的代码和分支是必须百分之百覆盖的。因为这是保证模块结构的完整性和模块功能正常实现。
• 测试不到的是指一些在当前单元测试环境中暂时无法执行到的,但程序中又必须包含的代码。这部分代码在正常情况下是很少的。可以考虑放到后面的集成测试中当环境满足时进行补充测试。
• 可以测试的是指除必须测试和测试不到的代码所剩余的部分。在考虑这部分代码的测试覆盖上就要加入成本的考虑了。在原则上这部分代码尽量测试覆盖。在这些代码和分支中会存在一些测试成本很高但测试意义并不大的代码或分支。在可控的成本范围内进行评估哪些需要覆盖,哪些可以暂时不覆盖,在后面的集成测试中去测试。
• 在单元测试中不能只追求覆盖率有多高。在针对覆盖率的问题上应该在综合各种因素后制订有灵活的幅度范围。不然大家就会为了达到高覆盖率而做覆盖工作了,这样的工作效率低且意义不大。
集成测试(IT)
什么是集成测试
• 集成测试(也叫组装测试,联合测试)是单元测试的逻辑扩展。它的最简单的形式是:两个已经测试过的单元组合成一个组件,并且测试它们之间的接口。从这一层意义上讲,组件是指多个单元的集成聚合。在现实方案中,许多单元组合成组件,而这些组件又聚合成程序的更大部分。方法是测试片段的组合,并最终扩展进程,将您的模块与其他组的模块一起测试。最后,将构成进程的所有模块一起测试。
集成的测试的作用
• 在单元测试的基础上,将所有模块按照设计要求(如根据结构图〕组装成为子系统或系统,进行集成测试。实践表明,一些模块虽然能够单独地工作,但并不能保证连接起来也能正常的工作。程序在某些局部反映不出来的问题,在全局上很可能暴露出来,影响功能的实现。
集成测试的条件
• 在集成测试之前,单元测试应该已经完成,集成测试中所使用的对象应该是已经经过单元测试的软件单元。这一点很重要,因为如果不经过单元测试,那么集成测试的效果将会受到很大影响,并且会大幅增加软件单元代码纠错的代价。
• 在很多传统的项目中,集成测试会放在项目后期才开始。这样做法让很多问题暴露的很晚。问题也会堆积如山,造成集成测试寸步难移。最后可能由于一些问题无法补救和解决造成整个项目失败。
• 在敏捷开发中,集成测试应该在项目早期开始进行。在进行概要设计时就要开始设计集成测试的框架和用例。集成测试环境在项目开始应该开始搭建。每一个模块在完成单元测试后就能马上进行组合并进入集成测试。这样能把问题尽早的暴露出来,有利于问题的解决和项目的改进。
• 集成测试中尽量要做到全自动化测试。
集成测试的问题
• 在做集成测试中能发现很多逻辑错误问题。这些逻辑问题在单元测试中无法发现。
• 在这些问题当中大部分是边界逻辑和异常处理逻辑问题。
• 为什么在集成测试中暴露出来的问题大部分是边界和异常处理逻辑问题呢?
• 1.集成测试是联合测试多个模块,每个模块的设计与编写不是一个能完成的。
每个人对同一件事物的理解都是不能完全相同的。所以人与人之间的对功能模块的理解也有所偏差,这需要通过不断的沟通与交流来不断修正。在模块间的连接点需要进行充分的沟通,严格的接口设计与接口逻辑设计
• 2.在做概要设计和一些模块设计时,程序员都会把主要精力放在正常功能的设计上,针对边界与异常处理的设计上不够充分。
• 大部分的程序开发中,大部分的代码都是处理边界与异常处理的。所以在设计时不但要把正常功能的逻辑设计周全,也要与相同的态度去设计边界逻辑和异常处理逻辑(这个工作量会比设计正常功能要多很多倍)。
• 3.必要的设计文档不健全。
• 在敏捷开发中虽然说是简洁的文档,但必须的设计文档还是非常有必要的。比如一些深度死锁问题。如果有健全的程序逻辑流程文档是比较容易发现的。特别是在多模块间的死锁问题。如果没有这类型的文档,只靠口头交流是很难发现。而且在测试中发现了这类问题要定位出来也是相当费力的。如果有健全的程序逻辑流程图可以在早期发现并解决此类问题,在后期测试中发现了这类问题,也可以通过图很容易的定位出来。如果只靠代码来定位是很难的。因为每个模块并不是同一个人设计和编写,要理解别人的代码并氢这些模块间的代码逻辑串联并定位出问题是相当耗时耗力的。
系统测试(ST)
什么是系统测试
• 系统测试是将已经确认的软件、计算机硬件、外设、网络等其他元素结合在一起,进行信息系统的各种组装测试和确认测试,其目的是通过与系统的需求相比较,发现所开发的系统与用户需求不符或矛盾的地方,从而提出更加完善的方案。
系统测试的条件与作用
• 在获取用户需求后就得开始系统测试的工作了。在需求设计和系统架构设计时应该开始设计系统测试的计划,系统设计的框架与基本的系统测试用例。在项目开发过程中需要根据用户需求和设计变更做出调整。在项目的中间有多个模块完成集成测试后即可进入系统测试。系统测试主要针对用户面,以用户的角度进行测试。看实现的功能和性能是否满足用户需求。
系统测试的要求
• 在系统测试中除了完成功能测试外,还要着重性能测试。要反复的折腾系统,保证系统在各种可能的环境中正常运行。在系统测试中,可以让最终用户参与进来,让他们亲自来进行系统测试。看用户是否对系统的体验是否满意,有哪些不符合他们的要求。而且最终用户对系统里面的实现方法并不清楚,操作测试起来更有不可以预测性,能发现更多隐蔽的缺陷。
• 参与系统测试的模块必须先经过充分单元测试和充分的集成测试。因为系统测试所发现的问题可能很难定位。原则是能在单元测试解决的问题不要留到集成测试中,能在集成测试中解决的问题不要留到系统测试中。因为越往后,问题越难定位,越难解决。