软件测试方法和技术第5章单元测试与集成测试第五章单元测试与集成测试5.1单元测试的目标和任务5.2单元的静态测试5.3驱动程序和桩程序5.4单元测试工具5.5集成测试为何要进行单元测试?尽早发现错误错误发现越早,成本越低.发现问题比较容易修正问题更容易检查代码是否符合设计和规范,有利于将来代码的维护5.1单元测试的目标和任务5.1单元测试的目标和任务定义单元测试是对软件基本的组成单元进行独立的测试。时机单元测试和编码是同步进行,但在TDD中,强调测试在先,编码在后。单元测试一般由开发人员完成,QA人员辅助。单元一个最小的单元应该有明确的功能、接口定义而且可以清析地与其他单元区分开。单元测试关注的主要内容目标:确保单元模块被正确编码。依据:详细设计描述,可以是详细设计说明书、源程序、单元测试计划;过程:见右图执行者:开发人员和测试人员共同完成测试方法:白盒为主,黑盒为辅通过单元测试的一般准则:P97单元测试的误区6单元测试一种浪费时间的工作;我是很棒的程序员,是不是可以不进行单元测试;集成测试能找到所有的BUG;任务1:单元独立执行路径的测试对每一条独立执行路径进行测试,并保证每条语句被至少执行一次。检查的问题:误解或用错了算符优先级混合类型运算变量初值错精度不够表达式符号错其它任务2:单元局部数据结构的测试检查局部数据结构在程序执行过程中是否正确、完整。检查的问题:不适合或不相容的类型说明变量无初值变量初始化或默认值有错不正确的变量名或从来未被使用过出现上溢或下溢和地址异常其它任务3:单元接口测试检查单元接口是否正确检查的问题:输入的实际参数与形式参数是否一致(个数、属性、量纲)调用其他模块的实际参数与被调模块的形参个数、属性、量纲是否一致。全程变量的定义在各模块是否一致。外部输入、输出文件、缓冲区、错误处理其它任务4:单元边界条件的测试检查边界数据处理的正确性检查的问题:普通合法数据的处理。普通非法数据的处理。边界值内合法边界数据的处理。边界值外非法边界数据的处理。其它任务5:单元容错性测试预设的各种出错条件的处理是否正确有效。检查的问题:输出的出错信息难以理解记录的错误与实际不相符异常处理不当未提供足够的定位出错的信息其它5.2静态测试技术的运用静态测试技术是单元测试中最重要的手段之一,适用于新开发的和重用的代码。通常在代码完成并无错误地通过编译或汇编后进行,采用工具扫描分析、代码评审等方法。5.2静态测试技术的运用静态测试是指不实际运行被测软件,而只是静态地检查程序代码、界面或文档中可能存在的错误的过程。(1)代码测试:主要测试代码是否符合相应的标准和规范(2)界面测试:主要测试软件的实际界面与需求中的说明是否相符(3)文档测试:主要测试用户手册和需求说明是否真正符合用户的需求这里着重介绍代码测试。5.2.1编码的标准和规范标准:建立起来必须遵守的规则规范:建议最佳做法,推荐更好方式实施代码规范的原因:可靠性可读性和可维护性可移植性C语言编码规范规范编号规范内容是否通过1一行代码只做一件事情2代码行的最大长度宜控制在70-80个字3函数与函数之间,说明语句和执行语句之间最好加空行4在程序开头加注释,说明基本信息;在重要函数处加注释,说明其功能5不要漏掉函数的参数和返回值,如果没有,用void表示例:C语言程序的静态测试(1)#includestdio.h(2)max(floatx,floaty)(3){floatz;(4)z=xy?x:y(5)return(z);(6)}(7)main()(8){floata,b;(9)intc;(10)scanf(“%f,%f”,&a,&b);(11)c=max(a,b)(12)printf(“maxis%d\n”,c);(13)}阅读Java编程规范:P100-102方法——三步曲:互查(PeerReview)走查(WalkThrough)审查(Inspection)5.2.2代码评审一次检查少于200~400行代码努力达到一个合适的检查速度:300~500LOC/hour有足够的时间、以适当的速度、仔细地检查,但不宜超过60~90分钟在复审前,代码作者应该对代码进行注释使用检查表(checklist)肯定能改进双方(作者和复审者)的结果验证缺陷是否真正被修复……互查示例走查(WalkThrough)定义:采用讲解、讨论和模拟运行的方式进行的查找错误的活动。注意:引导小组成员在走查前通读设计和编码。限时,避免跑题发现问题适当记录,避免现场修改检查要点是代码是否符合标准和规范,是否有逻辑错误审查(Inspection)以会议形式,制定目标、流程和规则按缺陷检查表(不断完善)逐项检查发现问题适当记录,避免现场修改发现重大缺陷,改正后会议需要重开。走查与审查的比较走查审查准备通读设计和编码事先准备Spec、程序设计文档、源代码清单、代码缺陷检查表等形式非正式会议正式会议参加人员开发人员为主项目组成员包括测试人员主要技术方法无缺陷检查表生成文档会议记录静态分析错误报告目标代码标准规范无逻辑错误代码标准规范无逻辑错误缺陷检查表缺陷检查表:主要包括一些容易出错的地方和在以往工作中遇到的典型错误,形成表格形式,目的是防止人为的疏漏。例:P1045.3动态测试动态测试需要真正将程序运行起来,需要设计系列的测试用例保证测试的完整性和有效性。白盒测试黑盒测试灰盒测试驱动程序和桩程序驱动程序(drive):所测模块的主程序。它接收测试数据,把这些数据传递给所测试模块,最后再输出测试结果。当被测试模块能完成一定功能时,也可以不要驱动模块。桩程序(stub):对顶层或上层模块进行测试时所编写的替代下层模块的程序。运行单元程序有时需要基于被测单元的接口,开发相应的驱动程序和桩程序。#includestdio.hvoidmain(void){inta=1,b=2,c;c=fun1(a,b);}intfun1(intx,inty){returnx+y;}例1例2DriverStubFunctionundertest为下面的函数构造一个驱动模块,并至少设计5条测试用例。/*计算2个整数的除法运算将结果转换为单精度输出*/floatdivide(inta,intb){floatc;if(b==0){printf(“除数不能为0!”);return0;}c=(float)a/b;returnc;}习题第一步:构造驱动模块如下:voidmain(void){intx;inty;floatz;scanf(“%d%d”,&x,&y);z=divide(x,y);printf(“%f”,z);}习题解答第二步:编写5条测试用例,如下表所示:习题解答1.空指针保护案例分析5.4代码评审案例分析2.格式化数字错误案例分析5.4代码评审案例分析3.字符串或数组越界案例分析5.4代码评审案例分析4.其它案例没有合理的关闭资源导致系统性能下降或最终崩溃P.111(5.4.4)不当使用synchronized导致系统性能下降或最终崩溃P.113(5.4.5)5.4代码评审案例分析5.5单元测试的结束程序调试与测试的区别:调试与测试的对象及采用的方法有很大程度上的相似,调试还用到断点控制等排错方法,但其目的却完全不同。测试是为了找出软件中存在的缺陷,而调试是为了解决存在的缺陷。单元测试的停止准则:(1)软件单元功能与设计需求一致;(2)软件单元接口与设计需求一致;(3)能够正确处理输入和运行中的错误;(4)在单元测试中发现的错误已经修改并通过了测试;(5)达到了相关的覆盖率的要求;(6)完成软件单元测试报告;单元测试检查表(1)单元测试检查表单元名称___________系统_______________构造______________任务编号____________________初次测试日期_________________关键测试项是否已纠正1.有无任何输入参数没有使用?有无任何输出参数没有产生?2.有无任何数据类型不正确或不一致?3.有无任何算法与PDL或功能需求中的描述不一致?4.有无任何局部变量使用前没有初始化?5.有无任何外部接口编码错误?即调用语句、文件存取、数据库错误。6.有无任何逻辑路径错误?7.该单元是否有多个入口或多个正常的出口?借助单元测试检查表进行评估。案例:单元测试检查表(2)额外测试项8.该单元中有任何地方与PDL与PROLOG中的描述不一致?9.代码中有无任何偏离本项目标准的地方?10.代码中有无任何对于用户来说不清楚的错误提示信息?11.如果该单元是设计为可重用的,代码中是有可能妨碍重用的地方?采取的动作和说明(请用单独的一页或多页。每一项动作必须指出所引用的问题。)审查结果1.如果上述11个问题的答案均为否,那么测试通过,请在此标记并且在最后签名。2.如果代码存在严重的问题,例如多个关键问题的答案为是,那么程序编制者纠正这些错误,并且必须重新安排一次单元测试。下一次单元测试的日期:_________________________3.如果代码存在小的缺陷,那么程序编制者纠正这些错误,并且仲裁者必须安排一次跟踪会议。跟踪会议的日期:_________________________测试人签名:__________________日期:_________________单元测试的过程单元测试的过程有5个步骤:(1)在详细设计阶段完成单元测试计划;(2)建立单元测试环境,完成测试设计和开发;(3)执行单元测试用例,并详细记录测试结果;(4)判定测试用例是否通过;(5)提交《单元测试报告》。单元测试的过程与文档管理时间依据任务成果计划阶段详细设计阶段后《软件需求规格说明书》《详细设计说明书》制定测试计划单元测试计划设计阶段《单元测试计划》提交后《单元测试计划》《软件详细设计说明书》测试用例的编写驱动模块、桩模块的设计单元测试用例执行阶段编码完成后《单元测试用例》《软件需求规格说明书》《详细设计说明书》执行测试用例记录缺陷《缺陷跟踪报告》评估阶段《单元测试用例》《缺陷跟踪报告》《缺陷检查表》完备性评估代码覆盖率评估《单元测试报告》5.6单元测试常用工具简介1.JUnit介绍2.在Eclipse中JUnit应用举例3.Junit+Ant构建自动的单元测试4.CheckStyle/PMD与FindBug的使用5.SourceMonitor检测代码复杂度6.开源的单元测试工具7.商业的单元测试工具单元测试工具种类代码规则/风格检查工具内存资源泄漏检查工具代码覆盖率检查工具代码性能检查工具单元测试工具列表5.6.1JUnitJunit()是一款功能强大的开源的Java单元测试工具,由ErichGamma和KentBeck两个人共同开发完成。准确地说,JUnit是一个测试框架,是单元测试框架体系xUnit的一个实例。可以和Java的开发环境进行很好的集成,比如Eclipse中就自动集成了JUnit框架。JUnit相对独立于所编写的代码,测试代码的编写可以先于实现代码的编写,TDD的实现有了现成的手段:用JUnit编写测试代码、编写实现代码、运行测试、测试失败、修改实现代码、在运行测试、直到测试成功。Junit的特性1.用断言来判断期望值和实际值的差异2.测试驱动设备使用共同的初始化变量和实例3.测试包结构便于组织和运行测试4.支持图形交互模式和文本交互模式其他:书P119JUnit结构7个包,核心是:junit.framework:负责整个测试的框架。junit.runner:负责测试驱动。4个重要的类:TestSuite:负责包装和运行所有的TestCase。TestCase:客户测试类所要继承的类。TestResult:负责收集TestCase所执行的结果。TestRunner:负责整个测试流