单元测试与集成测试

软件测试分类

  • 按测试用例的设计方法,软件测试分为白盒测试黑盒测试
  • 按测试策略和过程,软件测试分为单元测试、集成测试、确认测试和系统测试
  • 按软件系统工程,测试是软件质量保证最后的一关

高质量的程序取决于以下几个方面:

  1. 高质量的设计
  2. 规范的编码
  3. 有效的测试

开发部的测试   效果不好:为什么/p>

  • 没有时间测试
  • 不知道怎样测试
  • 不好组织
  • 缺乏方法和工具    

这种情况下,往往把单元测试的任务堆积到系统测试阶段。

如果把单元测试的任务堆积到系统测试阶段,将会怎样

  • 大量的故障堆积在项目中后期:项目后10%的工作,占用了项目90%的时间。
  • 故障难以定位
  • 故障飘忽不定
  • 开发、测试人员疲于奔命 

软件缺陷的修复费用

单元测试(why)

  • 最高的成本收益比
  • 减少联调和后续测试的时间
  • BUG更容易定位
  • 更有信心去修改老代码 

单元测试(who)

  • 单元测试可以是开发者本人执行,也可以是独立的专业测试人员执行。
  • 两者各有优势。
  • 建议开发人员必须完整地做单元测试,同时测试人员针对重点模块实施独立的单元测试。

1、单元测试的目标和任务

测试的4个阶段:单元测试—–>集成测试—–>系统测试—–>验收测试

按阶段进行测试是一种基本的测试策略

定义:     单元测试是对软件基本组成单元进行的测试。

时机:     单元测试和编码是同步进行,但在TDD中,强调测试在先,编码在后。一般在代码完成后由开发人员完成,QA人员辅助。

概念:     模块, 组件, 单元

1.1 为何要进行单元测试/strong>

  • 尽早发现错误   (错误发现越早,成本越低.    发现问题比较容易    修正问题更容易 )
  • 检查代码是否符合设计和规范

为什么要进行单元测试/p>

1.单元测试是不是太浪费时间了/p>

  • 不经过单元测试,直接进入集成测试,系统正常工作的可能性非常低,大量的时间被花费在跟踪那些简单的Bug上,会导致集成为一个系统时增加额外的工期。
  • 编写完整计划的单元测试和编写实际的代码所花费的精力大致相同。但是,一旦完成了这些单元测试工作,很多Bug将被纠正,在确信他们手头拥有稳定可靠的部件的情况下,开发人员能够进行更高效的系统集成工作,这才是真正意义上的进步。
  • 调试人员的不受控和散漫的工作方式只会花费更多的时间而取得很少的好处。

2.单元测试仅仅是为了证明这些代码作了什么吗/p>

  • 这是那些没有首先为每个单元编写一个详细设计文档而直接跳到编码阶段的开发人员提出的一条普遍的抱怨。这样的测试完全基于已经写好的代码,这无法证明任何事情。
  • 单元测试基于详细设计文档,这样的测试可以找到更多的代码错误,甚至是详细设计的错误。
  • 因此,高质量的单元测试需要高质量的详细设计文档。

3.我是一个很棒的程序员,是不是可以不进行单元测试呢/p>

  • 每个都可能犯错误
  • 真正的完整的系统往往是非常复杂的,不能寄希望于没有进行广泛的测试和Bug修改过程就可以正常工作。

4.有集成测试就够了,集成测试将会抓住所有的Bug。

  • 系统规模愈来愈大,复杂度愈来愈高,没有单元测试,开发人员很可能会花费大量的时间仅仅是为了使系统能够运行。
  • 任何实际的测试方案都无法执行。
  • 在系统集成阶段,对单元功能全面测试的负载程度远远的超过独立进行的单元测试过程。
  • 最后的结果是测试将无法达到它所应该有的全面性,一些缺陷被遗漏,并且很多Bug被忽略过去。

5.单元测试的成本效率不高/p>

  • 无论什么时候做出修改都要进行完整的回归测试。
  • 生命周期中尽早的对产品进行测试将使效率和质量得到最好的保证
  • Bug修改越晚,费用就越高,单元测试是一个在早期抓住Bug的机会。
  • 相比后阶段的测试,单元测试的创建简单维护容易,并且可以更方便的进行重复。
  • 从全程的测试费用来考虑,相比复杂且旷日持久的集成测试,或是不稳定的系统,单元测试所需的费用是最低的

单元测试的重要性

  • 一个尽责的单元测试方法将会在产品开发的某个阶段发现很多的Bug,并且修改它们的成本也很低。
  • 系统开发的后期阶段,Bug的检测和修改将会变得更加困难,并要消耗大量的时间和开发费用。
  • 无论什么时候做出修改都要进行完整的回归测试,在生命周期中尽早的对产品代码进行测试将是效率和质量得到最好的保证。
  • 在提供了经过单元测试的情况下,系统集成过程将会大大的简化。开发人员可以将精力集中在单元之间的交互作用和全局的功能实现上,而不会陷入充满很多Bug的单元之中不能自拔。
  • 使测试工作的效率发挥到最大化的关键在于选择正确的测试策略,这包含了完全的单元测试的概念,以及对测试过程的良好的管理,还有适当的使用好工具来支持测试过程。

单元测试的背景

开发流程时间表与修改Bug代价的关系图

  • 编程过程中,每写1000行代码会犯几十个错误
  • 编程与编译运行结束后,每1000行代码中大约残留有2-6个Bug
  • 寻找与修改程序错误的代价占总体开发投资的30% -60%
  • Bug在整个研发流程中被发现的越早,修改的代价就越低

单元测试是什么/strong>

单元测试,对单个的软件单元或者一组相关的软件单元所进行的测试,是代码级的测试。

Unit:函数,源代码文件,类

把测试比作是清洗一台机器:

  • 系统测试就是清除机器外面的尘土。
  • 集成测试就是保证机器各个部件的接头处干净。
  • 单元测试就是清洗各个零件的内部。

单元测试原则

  • 应该尽早地进行软件单元测试。
  • 应该保证单元测试的可重复性。
  • 尽可能地采用测试自动化的手段来支持单元测试活动。

1.2 单元测试的目标和要求

目标: 单元模块被正确编码

  • 信息能否正确地流入和流出单元;
  • 在单元工作过程中,其内部数据能否保持其完整性,包括内部数据的形式、内容及相互关系不发生错误,也包括全局变量在单元中的处理和影响。
  • 在为限制数据加工而设置的边界处,能否正确工作。
  • 单元的运行能否做到满足特定的逻辑覆盖。
  • 单元中发生了错误,其中的出错处理措施是否有效。
  • 指针是否被错误引用、资源是否及时被释放。
  • 有没有安全隐患否使用了不恰当的字符串处理函数等。

单元测试的一系列活动:

  1. 建立单元测试环境,包括在集成开发环境中安装和设置单元测试工具(插件);
  2. 测试脚本(测试代码)的开发和调试;
  3. 测试执行及其结果分析。

单元测试的主要内容:

  • 目标:确保模块被正确地编码。
  • 依据:详细设计描述。
  • 过程:经过设计、脚本开发、执行、调试和分析结果等环节。
  • 执行者:由程序开发人员和测试人员共同完成。
  • 采用那些测试方法:包括代码控制流和数据流分析方法,并结合参数输入域的测试方法。
  • 测试脚本的管理:可以按照产品代码管理的方法进行类似的配置(并入代码库),包括代码评审、版本分支、变更控制等。
  • 如何进行评估:通过代码覆盖率分析工具来分析测试的代码覆盖率、分支或条件的覆盖率。

单元测试的一般准则:

  • 软件单元功能与设计需求一致。
  • 软件单元接口与设计需求一致。
  • 能够正确处理输入和运行中的错误。
  • 在单元测试中发现的错误已经得到修改并且通过了测试。
  • 达成了相关的覆盖率的要求。 完成软件单元测试 告。

任务1:模块独立执行通路测试

检查每一条独立执行路径的测试。保证每条语句被至少执行一次。

Checklist:

  • 误解或用错了算符优先级。
  • 混合类型运算。
  • 变量初始化错误、赋值错误。
  • 错误计算或精度不够。
  • 表达式符 错等。

任务2:模块局部数据结构测试

检查局部数据结构完整性

Checklist:  

  • 不适合或不相容的类型说明。  
  • 变量无初值。  
  • 变量初始化或缺省值有错。
  •  不正确的变量名或从来未被使用过。  
  • 出现上溢或下溢和地址异常。

任务3:模块接口测试

检查模块接口是否正确

checklist:  

  • 输入的实际参数与形式参数是否一致。 (个数、属性、量纲)
  • 调用其他模块的实际参数与被调模块的形参是否一致。 (个数、属性、量纲) 
  • 调用预定义函数时所用参数的个数、属性和次序是否正确  
  • 全程变量的定义在各模块是否一致。
  •  外部输入、输出   ( 文件、缓冲区、错误处理 )

任务4:模块边界条件测试

检查临界数据处理的正确性

Checklist:  

  • 普通合法数据的处理。  
  • 普通非法数据的处理。
  •  边界值内合法边界数据的处理。
  •  边界值外非法边界数据的处理。  
  • 其它

任务5:模块的各条错误处理通路测试

预见、预设的各种出错处理是否正确有效。

Checklist:  

  • 输出的出错信息难以理解。  
  • 记录的错误与实际遇到的错误不相符。
  •  在程序自定义的出错处理代码运行之前,系统已介入。  
  • 异常处理不当。  
  • 错误陈述中未提供足够的定位出错的信息。

2、 静态测试

静态测试技术:不运行被测试程序,对代码通过检查、阅读进行分析。

三步曲:  走查(Walk Through)  审查(Inspection)  评审(Review)

2.1 编码的标准和规范

  • 标准:建立起来必须遵守的规则
  • 规范:建议最佳做法,推荐更好方式

实施代码规范的原因:  可靠性  可读性和可维护性  可移植性

2.2 代码评审

  • 一次检查少于200~400行代码
  • 努力达到一个合适的检查速度:300~500LOC/hour
  • 有足够的时间、以适当的速度、仔细地检查,但不宜超过60~90分钟
  • 验证缺陷是否真正被修复

1.代码走查(Walk Through)

定义:采用讲解、讨论和模拟运行的方式进行的查找错误的活动。

注意:  

  • 引导小组成员在走查前通读设计和编码。
  •  限时,避免跑题。  
  • 发现问题适当记录,避免现场修改。
  •  检查要点是代码是否符合标准和规范,是否有逻辑错误。

2.正式会议审查(Inspection)

定义:采用讲解、提问方式进行,一般有正式的计划、流程和结果。主要方法采用缺陷检查表。

注意:

  •  以会议形式,制定会议目标、流程和规则,结束后要编写 告。  
  • 按缺陷检查表逐项检查。  
  • 发现问题适当记录,避免现场修改。  
  • 发现重大缺陷,改正后会议需要重开。  
  • 检查要点是缺陷检查表,所以该表要根据项目不同不断积累完善。

走查与审查的比较

 

走   查

审   查

准备

通读设计和编码

应准备好需求描述文档、程序设计文档、程序的源代码清单、代码编码标准和代码缺陷检查表

形式

非正式会议

正式会议

参加人员

开发人员为主

项目组成员包括测试人员

主要技术方法

缺陷检查表

注意事项

限时、不要现场修改代码

限时、不要现场修改代码

生成文档

会议记录

静态分析错误 告

目标

代码标准规范,无逻辑错误

代码标准规范,无逻辑错误

3.评审(Review)

定义:通常在审查会后进行,审查小组根据记录和 告进行评估。

注意:  

  • 充分审查了所规定的代码,并且全部编码准则被遵守。
  •  审查中发现的错误已全部修改。

3 、动态测试

动态测试需要真正将程序运行起来,需要设计系列的测试用例保证测试的完整性和有效性。  

白盒测试  黑盒(灰盒)测试

驱动程序和桩程序

运行单元程序有时需要基于被测单元的接口,开发相应的驱动模块和桩模块。

  •  驱动模块(drive):对底层 或子层模块进行测试所编写的 调用这些模块的程序。
  •  桩模块(stub):对顶层或 上层模块进行测试时所编写的 替代下层模块的程序。

单元测试设计

  • 单元测试模型的设计。
  • 测试项目的设计。

(1)单元测试模型设计

  • 构造最小运行调度系统,即驱动模块,用于模拟被测模块的上一级模块。
  • 模拟实现单元接口,即单元函数需调用的其他函数接口,即桩模块。
  • 模拟生成测试数据或状态,为单元运行准备动态环境。
  • 对测试过程的支持,对测试结果的保留,对测试覆盖率的记录等。

单元测试环境的示意图如下:

(2)测试项目设计

  • 测试项目是测试用例的一个总则,主要是根据测试需求设计测试点,不包含具体实践的用例。
  • 在测试项目的设计中,主要从功能覆盖和代码覆盖两个角度进行考虑。

               功能覆盖属黑盒的范畴,用来指出测试用例是否已经覆盖了程序应该提供的功能。逻辑覆盖率是考核单元测试质量的一个关键指标。

                代码覆盖也称逻辑覆盖,包括语句覆盖、分支覆盖、路径覆盖,是一种常用的白盒测试方法。

  • 覆盖率指标:核心代码覆盖率达到100%,共享资源库的代码覆盖率达到100%,非核心代码覆盖率达到90%。

4、调试与评估

调试与测试的对象及采用的方法有很大程度上的相似,调试还用到断点控制等排错方法,但其目的却完全不同。测试是为了找出软件中存在的缺陷,而调试是为了解决存在的缺陷。  

  • 软件单元功能与设计需求一致。  
  • 软件单元接口与设计需求一致。
  •  能够正确处理输入和运行中的错误。  
  • 在单元测试中发现的错误已经得到修改并且通过了测试。  
  • 达到了相关的覆盖率的要求。  
  • 完成软件单元测试 告

5、单元测试的管理

过程:

  • 在详细设计阶段完成单元测试计划。
  • 建立单元测试环境,完成测试设计和开发。
  • 执行单元测试用例,并且详细记录测试结果。
  • 判定测试用例是否通过。
  • 提交《单元测试 告》。

单元测试的文档

  1. 《软件需求规格说明书》、《软件详细设计说明书》 —–> 《单元测试计划》
  2. 《单元测试计划》、《软件详细设计说明书》—–> 《单元测试用例》
  3. 《单元测试用例》文档及《软件需求规格说明书》、《软件详细设计说明书》—–> 《缺陷跟踪 告》/《缺陷检查表》   
  4. 《单元测试用例》、《缺陷跟踪 告》、《缺陷检查表》—–> 《单元测试检查表》
  5.   评估—–>   单元测试 告》

7、系统集成的模式与方法

集成测试定义

定义

集成测试又称“组装测试”、“联合测试”。集成测试遵循特定的策略和步骤将已经通过单元测试的各个软件单元(或模块)逐步组合在一起进行测试,以期望通过测试发现各软件单元接口之间存在的问题。

集成测试对象

理论上凡是两个单元(如函数单元)的组合测试都可以叫做集成测试。实际操作中,通常集成测试的对象为模块级的集成和子系统间的集成,其中子系统集成测试称为组件测试。

集成测试目的与意义

考虑以下问题:

  • 在把各个模块连接起来的时候,穿越模块接口的数据是否会丢失;
  • 各个子功能组合起来,能否达到预期要求的总体功能;
  • 一个模块的功能是否会对另一个模块的功能产生不利的影响;
  • 全局数据结构是否有问题 单个模块的误差积累起来,是否会放大,从而达到不可接受的程度。  
  • 共享资源访问的测试  (   要想发现并排除在模块连接中可能发生的上述问题,就需要进行 集成测试。)

集成测试有以下不可替代的特点:

  • 单元测试具有不彻底性,对于模块间接口信息内容的正确性、相互调用关系是否符合设计无能为力。只能靠集成测试来进行保障。
  • 同系统测试相比,由于集成测试用例是从程序结构出发的,目的性、针对性更强,测试项发现问题的效率更高,定位问题的效率也较高;
  • 定位问题较快,发现问题后比较容易定位,所以能够有效地加快进度,减少隐患。

集成测试(when)

  • 在开始体系结构设计的时候开始制定测试方案;
  • 在进入详细设计之前完成集成测试方案;
  • 在进入系统测试之前结束集成测试。

集成测试(who)

  • 集成测试可以在开发部进行,也可以由独立的测试部执行。
  • 开发部尽量进行集成测试,测试部有选择地进行集成测试。

集成测试原则

  • 集成测试是产品研发中的重要工作,需要为其分配足够的资源和时间。
  • 集成测试需要经过严密的计划,并严格按计划执行。
  • 应采取增量式的分步集成方式,逐步进行软件部件的集成和测试。
  • 应重视测试自动化技术的引入与应用,不断提高集成测试效率。
  • 应该注意测试用例的积累和管理,方便进行回归并进行测试用例补充。

集成测试内容

  • 集成功能测试
  • 接口测试
  • 全局数据结构测试
  • 资源测试
  • 任务优先级冲突测试
  • 性能和稳定性测试

集成测试、单元测试与系统测试的差别

测试类型

对象

目的

测试依据

测试方法

单元测试

模块内部的程序错误

消除局部模块的逻辑和功能上的错误和缺陷

模块逻辑设计,模块外部说明

大量采用白盒测试方法

集成测试

模块间的集成和调用关系

找出与软件设计相关的程序结构,模块调用关系,模块间接口方面的问题

程序结构设计

结合使用白盒与黑和测试方法,采用较多黑盒方法构造测试用例 

系统测试

整个系统,包括系统中的硬件等

对整个系统进行一系列的整体、有效性测试

系统结构设计,目标说明书,需求说明书等

黑盒测试

由以上可以看出,整个软件系统的测试过程是:先对各个软件模块进行单元测试,然后把经过单元测试的各个模块组装起来进行集成测试,最后把经过集成测试的子系统合成软件版本,对照需求规格,在实际环境下,进行系统功能验证。 

7.1 集成测试前的准备

人员安排 、测试计划、测试内容 、集成模式、测试方法

7.2 集成测试的模式

渐增式测试模式与非渐增式测试模式:

  • 非渐增式测试模式:先分别测试每个模块,再把所有模块按设计要求放在一起结合成所要的程序,如大棒模式。
  • 渐增式测试模式:把下一个要测试的模块同已经测试好的模块结合起来进行测试,测试完以后再把下一个应该测试的模块结合进来测试。

各自的优缺点

  • 非渐增式测试模式优缺点:工作量较小;发现模块间接口错误较晚;发现错误较难诊断,可以并行测试。
  • 渐增式测试模式优缺点:要编写的软件较多,工作量较大;发现模块间接口错误较早;测试执行更彻底;需要较多的机器时间。

7.3 大棒集成方法(Big-bang Integration)

采用大棒集成方法,先是对每一个子模块进行测试(单元测试阶段),然后将所有模块一次性的全部集成起来进行集成测试 。

因为所有的模块一次集成的,所以很难确定出错的真正位置、所在的模块、错误的原因。这种方法并不推荐在任何系统中使用,适合在规模较小的应用系统中使用。  

 非增量式集成测试实例

 

评述:模块d1、d2、d3、d4、d5是对各个模块做单元测试时建立的驱动模块,s1、s2、s3、s4、s5是为单元测试而建立的桩模块。这种一次性集成方式将所测模块连接起来进行测试,但是一次试运行成功地可能性并不大。其结果发现有错误,但茫然找不到原因,差错和改错都会遇到困难。    

适应于一个维护型或被测试系统较小的项目。 

非增量式策略——优缺点:

  • 优点: ①方法简单 ②允许多测试人员同时并行工作,人力物力资源利用率较高
  • 缺点: ①必须为每个模块准备相应的驱动模块和桩模块,测试成本较高 ②一旦集成后包含多种错误,难以纠正。

7.4 自顶向下和自底向上集成方法

驱动程序/驱动模块(driver),用以模拟被测模块的上级模块。驱动模块在集成测试中接受测试数据,把相关的数据传送给被测模块,启动被测模块,并打印出相应的结果。

桩程序/桩模块(stub),也有人称为存根程序,用以模拟被测模块工作过程中所调用的模块。桩模块由被测模块调用,它们一般只进行很少的数据处理,例如打印入口和返回,以便于检验被测模块与其下级模块的接口。

1.自顶向下法(Top-down Integration) 

自顶向下法,从主控模块(主程序)开始,沿着软件的控制层次向下移动,逐渐把各个模块结合起来。

组装过程可以采用深度优先策略和宽度优先策略

  • 深度优先:从最顶层单元开始,持续向下到下一层,选择一个分支,自顶而下一个一个的集成这条分支上的所有单元,直到最底层,然后转向另一个分支,重复这样的集成操作直到所有的单元都集成进来。
  • 广度优先:从最顶层单元开始,持续向下到下一层, 一个个完成下一层上所有单元集成后,再转向下面一层,重复这样的集成操作直到所有的单元都集成进来。

 

自顶向下增量测试 

自顶向下集成测试的整个过程由3个步骤完成:  

  1. 主控模块作为测试驱动器。   
  2. 根据集成的方式(深度或广度),下层的桩模块一次一次地被替换为真正的模块。
  3. 在每个模块被集成时,都必须进行单元测试。     重复第2步,直到整个系统被测试完成。  

深度优先组装方式:

广度优先组装方式:

自顶向下法——优缺点

优点:

不需要测试驱动程序;

能够在测试阶段的早期实现并验证系统的主要功能;

能在早期发现上层模块中的接口错误。 

缺点:

需要桩程序,要使桩模块能够模拟实际子模块的功能十分困难;

底层验证被推迟; 同时涉及复杂算法,真正输入/输出的模块一般在底层,

他们是最容易出问题的模块,到测试和集成的后期才遇到这些模块,一旦发现问题导致过多的回归测试。

自顶向下增量式集成适用范围:

  • 产品控制结构比较清晰和稳定;
  • 高层接口变化较小;
  • 底层接口未定义或经常可能被修改;
  • 产口控制组件具有较大的技术风险,需要尽早被验证;
  • 希望尽早能看到产品的系统功能行为。

练习:

(1)对如下结构采用自顶向下深度优先策略进行测试

 

(2)一个按广度优先测试进行集成测试

  1. 首先,对顶层的模块A进行单元测试,这时需配以被调用子模块s1、s2、s3,以模拟被它调用的模块B、C和D。
  2. 其后,把模块B、C和D与顶层模块A连接起来,再对模块B和D配以被调用模拟子模块s4和s5以模拟对模块E和F的调用。
  3. 最后,去掉被调用模拟子模块s4和s5,把模块E和F集成后再对软件完整的结构进行测试。

2.自底向上法(Bottom-up Integration)

自底向上法,测试从原子模

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年9月4日
下一篇 2019年9月5日

相关推荐