软件测试第6章课件.ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《软件测试第6章课件.ppt》由用户(三亚风情)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 软件 测试 课件
- 资源描述:
-
1、单元测试学时:4学时 6.1 6.1 单元测试的目标及内容单元测试的目标及内容指对软件中的指对软件中的最小可测试单元最小可测试单元或或基本组成单元基本组成单元进进行检查和验证。行检查和验证。单元测试的定义:单元测试的定义:6.1 6.1 单元测试的目标及内容单元测试的目标及内容单元选取原则单元选取原则面向过程面向过程面向对象面向对象图形化软件图形化软件函数或子过程函数或子过程类类窗口或菜单窗口或菜单6.1.1 单元测试的目标(1)单元测试就是为了检测代码单元的逻辑功能,找出单元本身的所有功能逻辑错误。进一步说,就是检测对数据的各种分类是否考虑全面,处理是否正确。单元测试并不是用来代替系统测试、
2、性能测试的,它的目标很明确,就是检测代码单元的功能逻辑错误。单元测试的目的除了要发现编码中引入的错误和发现代码和周详设计不一致的地方之外,也是为了确保周详设计的质量。6.1.1 单元测试的目标(2)单元测试需要达到以下一些具体目标:信息能否正确地流入和流出单元。在单元工作过程中,其内部数据能否保持完整性,包括内部数据的形式、内容及相互关系不发生错误,也包括全局变量在单元中的处理和影响。在为限制数据加工而设置的边界处,能否正确工作。单元的运行能否做到满足特定的逻辑覆盖。单元中发生了错误,其中的出错处理措施是否有效。6.1.1 单元测试的内容(1)单元测试的内容有以下几方面:1)模块接口测试对模块
3、接口,包括参数表、调用子模块的输入参数是否正确、全程数据、此模块调用子模块时的输出参数是否正确、是否修改了只读型参数、全局变量的定义在各模块中是否一致、文件输入/输出操作都必须检查。6.1.1 单元测试的内容(2)2)局部数据结构测试设计测试用例检查数据类型说明、初始化、缺省值等方面的问题,还要查清全程数据对模块的影响。检查局部数据结构是为了保证临时存储在模块内的数据在执行过程中的完整、正确。局部数据结构往往是错误的根源,应仔细设计测试用例,力求发现以下错误:不正确或不一致的数据类型说明、使用尚未赋值或者尚未初始化的变量、错误的初始值或缺省值、变量名的拼写或书写错误、溢出或地址异常。6.1.1
4、 单元测试的内容(3)3)路径测试选择适当的测试用例,对模块中重要的执行路径进行测试。对基本执行路径和循环进行测试可以发现大量路径错误。进行路径设置时,设置测试用例是为了发现因错误计算、不正确的比较和不适当的控制流造成的错误。4)错误处理测试检查模块的错误处理功能是否包含有错误或缺陷。例如,是否拒绝不合理的输入,出错的描述是否难以理解、是否对错误定位有误、是否出错原因报告有误、是否对错误条件的处理不正确,在对错误处理之前错误条件是否已经引起系统的干预等。6.1.1 单元测试的内容(4)3)路径测试选择适当的测试用例,对模块中重要的执行路径进行测试。对基本执行路径和循环进行测试可以发现大量路径错
5、误。进行路径设置时,设置测试用例是为了发现因错误计算、不正确的比较和不适当的控制流造成的错误。4)错误处理测试检查模块的错误处理功能是否包含有错误或缺陷。例如,是否拒绝不合理的输入,出错的描述是否难以理解、是否对错误定位有误、是否出错原因报告有误、是否对错误条件的处理不正确,在对错误处理之前错误条件是否已经引起系统的干预等。6.1.1 单元测试的内容(5)5)边界测试要特别注意数据流、控制流中刚好等于、大于或小于确定的比较值时出错的可能性。对这些地方要仔细地选择测试用例,认真加以测试。边界测试是单元测试的最后,也是最重要的一项。此外,如果对模块运行时间有要求的话,还要专门进行关键路径测试,以确
6、定最坏情况下和平均意义下影响模块运行时间的因素。代码的功能逻辑越复杂,即算法密集度越高,可能出现的错误就越多,越需要全面的测试,测试效益越大。所以,如果时间紧张,应该优先测试功能逻辑复杂的代码。80-20规则在软件开发中同样存在,也就是说80%的代码错误可能存在于20%的代码中,20%的代码可能占用了80%的开发调试时间。这20%就是功能逻辑复杂的代码,即使只对这些代码进行单元测试,也能产生巨大的效益。6.1.1 单元测试的内容(6)6.1.1 单元测试的内容(7)单元测试是针对代码单元的独立测试。“独立”是指将代码从原始项目及其依赖的环境中隔离出来,针对各个单元单独进行测试,包括3方面含义:
7、形式独立、实质独立和意识独立。单元测试之所以困难,是因为技术上无法解决形式独立和实质独立,主观上没有达到意识独立。1)形式独立将测试任务从原始项目及其依赖环境中隔离出来,并能在易于测试的环境下运行。企业项目通常高耦合、可测性差、依赖于特定的软件环境或硬件环境,单元测试要首先将测试任务从依赖的代码和环境中分离出来,并解决编译、平台差异等问题,使测试任务在易于测试的环境下能够独立测试。6.1.1 单元测试的内容(8)代码的功能逻辑越复杂,即算法密集度越高,可能出现的错误就越多,越需要全面的测试,测试效益越大。所以,如果时间紧张,应该优先测试功能逻辑复杂的代码。80-20规则在软件开发中同样存在,也
8、就是说80%的代码错误可能存在于20%的代码中,20%的代码可能占用了80%的开发调试时间。这20%就是功能逻辑复杂的代码,即使只对这些代码进行单元测试,也能产生巨大的效益。6.1.1 单元测试的内容(9)2)实质独立被测试代码通常会调用各种底层函数,其功能逻辑难免受底层函数的影响,如何独立完整地进行测试?实际上,调用底层函数获得的数据,与通过参数传递的数据具有同等意义,例如,调用底层函数得到一个返回值,要测试的是被测程序对这个值的各种可能有没有做合适的判断处理,并不关心底层函数如何计算这个值,正如只关心是否对参数的各种可能做了合适处理,而不关心参数是如何传递和由谁传递一样。因此,调用底层函数
9、获得的数据可视为被测函数的一种输入,称为内部输入。如果可以模拟底层函数的各种输出,并将这些输出视为被测函数的内部输入,那么,无论底层函数属于哪种情形,都可以完整测试被测代码的功能逻辑,这就是实质独立。6.1.1 单元测试的内容(10)内部输入分为易于自然取得(调用真实的底层函数获得)、不可控(调用真实底层函数但其行为难于控制)、失真(打桩的必然后果)、难于自然取得等4种情形。易于自然取得的内部输入并不影响被测函数的独立性,而后3种则是单元测试的关键难点。静态局部变量也是麻烦的内部输入。3)意识独立意识独立是主观要素,是指在制定测试目标和执行测试时,要适应“单元测试是针对代码单元的独立测试”这一
10、基本现实,把测试任务看做是一个一个的独立单元,正确设定测试目标、正确选择测试方法及工具。6.1.1 单元测试的内容(11)单元测试有独特的优势,例如易于完整地测试代码单元的功能逻辑,这些优势来自“独立”,但凡事有其长必有其短,既然是“独立”,就难以测试与其他代码和依赖环境的相互关系。单元测试与系统测试是互补关系,不是代替关系,“独立”状态下易于发现的错误,才是单元测试的目标;集成后才易于发现的问题,应该留待系统测试完成。代码单元本身的功能逻辑错误都是单元测试的目标,而性能问题(时间性能如执行速度,空间性能如存储空间大小、内存泄漏)难以在最小单元内测试,不是单元测试目标。6.1.1 单元测试的内
11、容(12)编码规范检查与单元测试无关,无论是否实施单元测试,编码规范检查都是必不可少的工作。静态分析属于全局扫描,严格来说也不是单元测试,提高编译器的警告级别,就是最简单高效的静态分析。单元测试是意义重大且困难的工作,目标应该具体而明确,将不属于单元测试或单元测试不擅长的目标牵扯进来,其结果往往是“拣了芝麻,丢了西瓜”。6.1.1 单元测试的内容(13)6.2 单元测试的环境 模块并不是一个独立的程序,在考虑测试模块时,同时要考虑它和外界的联系,用一些辅助模块去模拟与被测模块相联系的其他模块。这些辅助模块分为两种:驱动模块和桩模块。被测模块、与它相关的驱动模块和桩模块共同构成了测试环境。6.2
12、.1 驱动模块和桩模块的定义驱动模块和桩模块是两个比较重要的概念。(1)驱动模块:相当于被测模块的主程序,它接收测试数据,把这些数据传送给被测模块,启用被测模块,最后输出实测结果。主模块作为驱动模块,与之直接相连的模块用桩模块代替。(2)桩模块:集成测试前要为被测模块编制一些模拟其下级模块功能的“替身”模块,以代替被测模块的接口,接受或传递被测模块的数据,这些专供测试用的“假”模块称为被测模块的桩模块。6.2.1 驱动模块和桩模块的定义 桩模块用来代替所测的子模块,它不能为空,也并不 需要子模块的所有功能都实现,可以只实现一部分;驱动模块用来代替主模块,用它来调用子模块。简单地说,被测模块上层
13、为驱动模块,是调用被测模块的,被测模块下层为桩模块,是被被测模块调用的(驱动模块和桩模块的举例将在6.2.3小节中具体说明)。驱动模块和桩模块为程序单元的执行构成了一个完整的环境。驱动模块用以模拟被测单元的上层模块,测试执行时由驱动模块调用被测单元使其运行,桩模块模拟被测单元执行过程中所调用的模块,测试执行时桩模块使被测单元能完整闭合地运行。6.2.1 驱动模块和桩模块的定义6.2.2 驱动模块和桩模块的使用条件 一般认为单元测试应紧接在编码之后,当源程序编制完成并通过复审和编译检查,便可开始单元测试。测试用例的设计应与复审工作相结合,根据设计信息选取测试数据,将增大发现错误的可能性。在确定测
14、试用例的同时,应给出期望结果。此时,应为测试模块开发一个驱动模块(driver)和(或)若干个桩模块(stub)。驱动模块在大多数场合称为“主程序”,它接收测试数据并将这些数据传递到被测试模块,被测试模块被调用后,“主程序”打印“进入退出”消息。实施单元测试的最佳时机是在编码阶段,若编码阶段没有进行单元测试,则也可在后期单独开发单元测试程序。驱动模块和桩模块是测试使用的软件,而不是软件产品的组成部分,但它需要一定的开发费用。若驱动和桩模块比较简单,实际开销相对低些。6.2.2 驱动模块和桩模块的使用条件 按照TDD的思想,自然是要先编写单元测试,然后再编写能够通过该单元测试的方法。在不实践TD
15、D的项目中,事后编写单元测试仍有其合理性:(1)以消极的态度来看,既然项目本身不严格要求事先编写单元测试,那么就可以在事后去做了。(2)事后编写单元测试至少也是一种检验手段,当然,肯定比不上事先编写的单元测试。因为,事后编写的单元测试很可能会“将就”已经写好的应用程序,事后编写的单元测试将是肤浅的,不会对代码进行良好的测试。6.2.2 驱动模块和桩模块的使用条件(3)可以把单元测试(其中包含事后单元测试)作为“后来者”了解、学习应用程序的手段。因为单元测试程序就是应用程序的“客户”,所以无论它是事先写的,还是事后写的,都可以很好地表现出应用程序的行为。(4)事后单元测试,也可能转化为事先单元测
16、试。在应用程序的整个生命周期中,维护阶段是最长的。在“漫长”的维护过程中,“之前”所写的“事后”单元测试将会成为“后来者”(包括原始作者本人)的“事先”单元测试。在改进程序的过程中,这些单元测试仍然能起到监督的作用。6.2.3 驱动模块和桩模块的设计驱动模块和桩模块的概念和设计我们将通过一个简单的例子来说明。现在假设一个程序由A、B、C、D、E、F六个模块组成,结构下图所示。6.2.3 驱动模块和桩模块的设计假设现在项目组把任务分给了6个人上面只有六个模块,那又如何实现每个人负责实现一个模块?,每个人负责实现一个模块。你负责的是B模块,你很优秀,第一个完成了编码工作,现在需要开展单元测试工作,
17、先分析结构图:(1)由于B模块不是最顶层模块,所以它一定不包含main函数(A模块包含main函数),也就不能独立运行。(2)B模块调用了D模块和E模块,而目前D模块和E模块都还没有开发好,因此想让B模块通过编译器的编译也是不可能的。6.2.3 驱动模块和桩模块的设计那么怎样才能测试B模块呢?方法如下:(1)写两个模块Sd和Se分别代替D模块和E模块(函数名、返回值、传递的参数相同),这样B模块就可以通过编译了。Sd模块和Se模块就是桩模块。(2)写一个模块Da用来代替A模块,里面包含main函数,可以在main函数中调用B模块,让B模块运行起来。Da模块就是驱动模块。桩模块的使命除了使得程序
18、能够编译通过之外,还需要模拟返回被代替的模块的各种可能返回值(什么时候返回什么值需要根据测试用例的情况来决定)。驱动模块的使命就是根据测试用例的设计去调用被测试模块,并且判断被测试模块的返回值是否与测试用例的预期结果相符。6.2.3 驱动模块和桩模块的设计2桩模块的设计桩模块主要完成以下内容:(1)接受测试输出。(2)将输出传给桩模块。(3)接受被测单元执行结果,并对结果进行判断。(4)将判断结果作为用例执行结果输出测试报告。6.3 单元测试的策略 单元测试是软件测试的基础,单元测试跟软件设计一样,有一些常用的策略模式。将若干个模块连接成一个可运行的系统通常有两种方式:一种是“非渐增式”,即先
19、独立地测试每一模块,然后将所有这些模块连接到一起运行;另一种是“渐增式”,即在已测试过的N个模块的基础上再增加一个模块,再对N+1个模块进行测试。左图为 X的非渐增式测试;右图为B的非渐增式测试。6.3 单元测试的策略6.3 单元测试的策略非渐增式是先分别测试6个模块A,B,C,D,E,F,然后将6个模块连接到一起再进行测试。若用这种方式,在测试某个模块X时,需要为它设计一个驱动模块和若干个桩模块,如图6-5所示。驱动模块的作用是模拟X的调用模块,桩模块的作用是模拟X的下层模块。例如测试如图6-6所示的模块B时,要为它设计一个驱动模块,其作用是将测试数据传送给模块B,并显示B产生的结果,另外,
20、由于模块B要调用模块E,所以还需设计一个名字为E的模块,它将接受B的控制并模拟E的功能。由图6-6可知,模块B要调用的是模块D,而非模块E,请修改这里。(这里不用修改了,图片画错了,文字的对的)另一种方式是渐增式,它不是分别测试每个模块,而是逐步将要测试的模块同已测试的模块连接起来。若用渐增方式,模块测试和联合测试这两步是结合起来进行的。渐增式又包含有由上而下、自下而上等。6.3.1.自上而下的测试 在自上而下的测试过程中,每个单元是通过使用它们来进行测试的,这个过程是由调用这些被测单元的其他独立的单元完成的。首先测试最高层的单元,将所有的调用单元用桩模块替换。接着用实际的调用单元替换桩模块,
展开阅读全文