您好,欢迎访问三七文档
当前位置:首页 > 办公文档 > 统计图表 > 软件测试第二章单体测试
第2章单元测试本章目标能够应用JUnit进行单元测试掌握JUnit+EclEmma进行覆盖率测试本章单词:unit__________________________cover_________________________emma__________________________assert________________________equals________________________same__________________________plugin________________________feature_______________________4.1单元测试简介单元测试就是测试程序员依据其所设想的方式开发出来的程序是否产生了预期的结果。单元测试是与软件开发生命周期中的编码阶段结合起来的,并且只有项目具备各个窗体、报表和屏幕之后才能开始进行测试。编码阶段的基本单元式:程序、函数、过程、窗体、或者图形用户界面。在单元测试中,需要测试以下内容:代码的控制流程、给函数传递参数值、从函数获取值是否正确。另外,单元测试不只限于检查控制流程或者程序的执行,还检查代码是否遵循编码标准。在对每个模块进行单元测试时,不能完全忽视它们和周围模块的相互关系。为模拟这一联系,在进行测试时,需设置若干辅助测试模块。辅助模块有两种,一种是驱动模块,用以模拟被测试模块的上级模块。驱动模块在单元测试中接收测试数据,把相关的数据传送给被测模块,启动被测模块,并打印出相应的结果。另一种是桩模块,用以模拟被测试模块工作过程中所调用的模块。桩模块由被测模块调用,它们一般只进行很少的数据处理,例如打印入口和返回,以便于检查被测试模块与其下级模块的接口。测试中通常使用测试驱动模块和桩模块。测试驱动程序是帮助执行软件以检查其是否工作的软件。此程序提供一个框架来设置参数、执行单元并记录结果。桩模块不是实际单元而是模型,用以取代实际单元并帮助执行测试过程。开发人员将测试作为编程的必要过程,并采用单元测试来验证它们的代码是否执行预期的功能。开放源码的单元测试框架有JUnit和Nunit。JUnit适用于Java应用程序,它是由SmallTalk的Sunit派生而来。Nunit用于测试.NET程序。PHPUnit是一个轻量级的PHP测试框架。JavaScript有JsUnit,数据库有DBUnit……4.2JUnit4.2.1JUnit简介JUnit是由ErichGamma和KentBeck编写的一个回归测试框架。JUnit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How)完成功能和完成什么样(What)的功能。JUnit是一套框架,继承TestCase类,就可以用JUnit进行自动测试了。JUnit是一个开放源代码的Java测试框架,用于编写和运行可重复的测试。它是用于单元测试框架体系xUnit的一个实例(用于java语言)。它包括以下特性:用于测试期望结果的断言(Assertion)。用于共享共同测试数据的测试工具。用于方便的组织和运行测试的测试套件。图形和文本的测试运行器。另外JUnit是在xp编程(ExtremeProgramming)和重构(refactor)中被极力推荐使用的工具,因为在实现自动单元测试的情况下可以大大的提高开发的效率,但是实际上编写测试代码也是需要耗费很多的时间和精力的,那么使用这JUnit好处到底在哪里呢?有以下几点供参考:A、对于xp编程而言要求在编写代码之前先写测试,这样可以强制你在写代码之前好好的思考代码(方法)的功能和逻辑,否则编写的代码很不稳定,那么你需要同时维护测试代码和实际代码,这个工作量就会大大增加。因此在xp编程中,基本过程是这样的:构思→编写测试代码→编写代码→测试,而且编写测试和编写代码都是增量式的,写一点测一点,在编写以后的代码中如果发现问题可以较快的追踪到问题的原因,减小回归错误的纠错难度。B、对于重构而言其好处和xp编程中是类似的,因为重构也是要求改一点测一点,减少回归错误造成的时间消耗。C、对于非以上两种情况我们在开发的时候使用JUnit写一些适当的测试也是有必要的,因为一般我们也是需要编写测试的代码的,可能原来不是使用的JUnit,如果使用JUnit,而且针对接口(方法)编写测试代码会减少以后的维护工作,例如以后对方法内部的修改(这个就是相当于重构的工作了)。另外就是因为JUnit有断言功能,如果测试结果不通过会告诉我们哪个测试不通过,是什么原因。而不是写一些测试代码看其输出结果,然后再由自己来判断结果使用正确,使用JUnit的好处就是这个结果是否正确的判断是它来完成的,我们只需要看看它告诉我们结果是否正确就可以了,在一般情况下会大大提高效率。在测试代码时,必须遵守特定的命名惯例,待测的每种方法的命名应该testXXXX()的格式。任何编写的测试代码应执行并完成以下任务:设置测试所需要的所有条件。调用待测的方法。验证待测的方法是否执行预期的功能。清除。测试代码的编写方式与程序代码相同。除了在测试代码中会用到附加库以外,其他的与程序代码相同。在执行的时候,执行测试代码而不是实际的项目代码。测试代码在一定程度上控制条件下检查项目代码。JUnit提供一些测试方法,用于判断正在测试的特定方法是否正确执行那个功能。这些方法被称为asserts(),它断言某个特定条件是否为真。断言是单元测试中的基本结构。如表4-1所示,JUnit提供了多个assert()方法,这些方法包含在junit.framework.TestCase类中。表4-1JUnit中的断言方法功能描述assertEquals判断给定两对象的值是否相等assertNull断言给定对象是否为nullassertNotNull断言给定对象是否不为nullassertSame判断给定两对象是否指同一对象assertNotSame判断给定两对象是否不是指同一对象assertTrue断言给定的布尔条件是否为真assertFalse断言给定的布尔条件是否为假fail测试失败断言失败时,将终止测试方法,并引发AssertionFailedError。4.2.2添加JUnit支持无论是Eclipse还是MyEclipse都自带有JUnit,我们只需添加JUnit支持即可,想了解更多关于JUnit请参考官方网站。下面我们介绍如何在MyEclipse中添加JUnit支持。1、在PackageExplorer中选中要添加JUnit支持的项目,点击右键。图2-1选中项目,点击右键2、选择BuildPath,然后再选择AddLiraries。图2-2AddLibraries3、选择JUnit,然后点击Next按钮。图2-3选择JUnit4、选择JUnit版本(推荐JUnit3),但后点击Finish。图2-4选择版本为JUnit35、此时项目里就已经引用了JUnit.jar。图2-5添加JUnit之后的效果上述添加支持的目的就是为了导入junit.jar,除此之外,还可以直接复制junit.jar到项目的lib目录下。4.2.3第一个JUnit程序现在有一个类JunitDemo.java文件,需要对addNum方法做测试。例4-1:JunitDemo.javapackagecom.slrj.dean.biz;publicclassJUnitDemo{publicintaddNum(intnum1,intnum2){returnnum1+num2;}}实现步骤如下:新建一个类JunitDemoTest.java。导入junit.framework.TestCase包。新建JunitDemo对象引用。新建测试addNum的方法,命名为testAddNum。利用assertEquals进行断言。例4-2:JUnitDemoTest.javapackagecom.slrj.dean.biz;importjunit.framework.TestCase;publicclassJUnitDemoTestextendsTestCase{JUnitDemodemo=newJUnitDemo();publicvoidtestAddNum(){assertEquals(demo.addNum(10,10),20);}}1、以JUnitTest方式进行运行。图2-6以JUnittest运行2、运行结果如图。图2-7运行结果在上面的JUnitDemoTest中需要大家注意的是,测试类必须继承自TestCase这个父类,每个测试方法必须以test作为前缀开头,运行测试类时需要以JUnitTest方式进行运行。4.3逻辑驱动覆盖测试逻辑驱动覆盖测试是传统的白盒测试方法。该方法利用程序内部逻辑结构设计测试用例,以期达到覆盖程序中所有的路径的目的,它包括:语句覆盖、判断覆盖、条件覆盖、判定条件覆盖、条件组合覆盖、路径覆盖。某学校自动化管理系统中有如下方法,其中细节代码已经省略,主题结构如下:例4-3:getClassInfo方法publicStringgetClassInfo(intclassId,intgradeId,intschoolId){Stringresult=;//入口……if(classId3&&schoolId10){//语句块1……}if(classId==4||gradeId5){//语句块2……}//出口……returnresult;}上面getClassInfo方法的流程图为:入口classId3&&schoolId10Yes(A)NO(B)执行语句块1classId==4||gradeId5Yes(C)NO(D)执行语句块2出口图2-8例子流程图为了说明简略,分别对各个判断的取真、取假分支编号为A、B、C、D。4.3.1语句覆盖语句覆盖就是设计若干个测试用例,运行被测试程序,使得每一条可执行语句至少执行一次。根据概念,为了对上面的函数进行语句覆盖,只要设计一个测试用例就可以把三个执行语句块中的语句覆盖。针对程序的判定语句,在入口处设计测试用例。测试用例输入为:{classId=4、gradeId=5、schoolId=5}程序执行的路径是:AC如果程序只运行上面测试用例,可以看到模块中的所有语句都被执行了,但不能检查判断逻辑是否有问题,例如在第一个判断中错误的把&&改写成||,则上面的测试用例仍可以覆盖所有的执行语句。可以说语句覆盖是最弱的逻辑覆盖准则。4.3.2判定覆盖设计若干个测试用例,运行所测程序,使程序中每个判断的取真分支和取假分支至少执行一次;根据上面的定义,对于上面的程序,如果设计两个测试用例则可以满足条件覆盖的要求。测试用例的输入为:{classId=4、gradeId=5、schoolId=5}{classId=2、gradeId=5、schoolId=5}上面的两个测试用例虽然能够满足条件覆盖的要求,但是也不能对判断条件进行检查,例如把第二个条件gradeId5错误的改写gradeId5,上面的测试用例同样满足了分支覆盖。4.3.3条件覆盖设计足够多的测试用例,运行所测试程序,使程序中每个判断的每个条件的每个可能取值至少执行一次。为了设计测试用例清楚,对例子中的所有取值加以标记。对第一个条件判断:条件classId3取真值为T1,取假为-T1条件schoolId10取真值为T2,取假为-T2对第二个条件判断:条件classId=4取真值为T3,取假值为-T3条件gradeId5取真值为T4,取假值为-T4则可以设计测试用例如下:表4-2条件覆盖测试用例覆盖分支条件取值classId=4,gradeId=5,schoolId=5ACT1、T2、T3、T4classId=2,gradeId=5,schoolId=5BD-T1、T2、-T3、-T4classId=4,gradeId=5,schoolId=15BCT1、-T2、T3、-T4上面的测试用例不但覆盖
本文标题:软件测试第二章单体测试
链接地址:https://www.777doc.com/doc-2011868 .html