Eclipse全程指南
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

5.2 JUnit简介

JUnit最初是由Erich Gamm(a《设计模式》的作者)与Kent Beck(XP(Extreme Programming)的创始人)撰写,为单元测试(Unit Testing)的支持框架,用来撰写与执行重复性的测试。它是用于单元测试框架体系XUnit的一个实例。

JUnit包括了以下的特性:

(1)使用断言方法判断期望值和实际值差异,返回Boolean值。

(2)测试驱动设备使用共同的初始化变量或者实例。

(3)测试包结构便于组织和集成运行。

(4)支持图形交互模式和文本交互模式。

5.2.1 JUnit的框架组成

JUnit框架是一个典型的Composite模式:TestSuite可以容纳任何派生自Test的对象;当调用TestSuite对象的run()方法时,会遍历自己容纳的对象,逐个调用它们的run()方法。

JUnit框架主要包括:

(1)TestCase:对测试目标进行测试的方法与过程集合,可称为测试用例。

(2)TestSuite:测试用例的集合,可容纳多个测试用例(TestCase),将其称作测试包。

(3)TestResult:测试结果的描述与记录。

(4)TestListener:测试过程中的事件监听者。

(5)TestFailure:每一个测试方法所发生的与预期不一致状况的描述,称其测试失败元素。

(6)AssertionFailedError:JUnit Framework中的出错异常。

5.2.2 JUnit的安装

JUnit是开放源代码的软件,用户可以从http://www.junit.org中下载JUnit包。JUnit的当前版本是4.1版。

JUnit的安装步骤如下:

1将junit4.1.zip解压到一个物理目录中(例如C:\junit4.1),此目录为JUnit的安装目录。

2 JUnit和JDK一样,也要设置环境变量才能在集成环境中使用。设置方法和设置JDK基本上一样,在“系统变量”的“变量”列表框中选择“CLASSPATH”关键字(不区分大小写),如果该关键字不存在则添加。双击“CLASSPATH”关键字添加字符串“C:\junit4.1\junit-4.1.jar”(注意,如果已有别的字符串请在该字符串的末尾加上分号“;”),这样确定修改后JUnit就可以在集成环境中使用了。

5.2.3 JUnit中常用的接口和类

1.Test接口——运行测试和收集测试结果

Test接口的主要作用是用来运行测试和收集测试结果。Test接口使用了Composite设计模式,是单独测试用例(TestCase)、聚合测试模式(TestSuite)及测试扩展(TestDecorator)的共同接口。

它的public int countTestCases()方法用来统计这次测试有多少个TestCase。另外一个方法就是public void run(TestResult),参数TestResult作为接受测试结果的实例,run方法用于执行本次测试。

2.TestCase抽象类——定义测试中固定方法

TestCase抽象类的主要作用是用来定义测试中固定方法。TestCase是Test接口的抽象实现(不能被实例化,只能被继承),其构造函数TestCase(String name)根据输入的测试名称(name)创建一个测试实例。由于每一个TestCase在创建时都要有一个名称,若某测试失败了,便可识别出是哪个测试失败。

TestCase类中包含setUp()、tearDown()方法。setUp()方法集中初始化测试所需的所有变量和实例,并且在依次调用测试类中的每个测试方法之前再次执行setUp()方法。tearDown()方法则是在每个测试方法之后,释放测试程序方法中引用的变量和实例。

开发人员编写测试用例时,只需继承TestCase来完成run方法即可,然后JUnit获得测试用例,执行它的run方法,把测试结果记录在TestResult之中。

在编写TestCase的子类用于测试时,有以下一些事项需要注意:

(1)给测试方法起一个合适的名字。最好在原方法上加上一个test前缀,显得比较清晰,不至于由于测试程序的增多而混淆。

(2)注意测试的独立性。一次只测试一个对象,这样容易确定出错的位置。对于一个TestCase,只测试一个对象;对于一个TestMethod,只测试这个对象中的一个方法。

(3)在setUp和tearDown中的代码不应该是与测试方法相关的,而应该是全局相关的。例如,对于测试方法A和B,在setUp和tearDowm中的代码应该为A和B都需要的代码。

3.Assert静态类——一系列断言方法的集合

Assert包含了一组静态的测试方法,用于期望值和实际值比对是否正确,若测试失败,Assert类就会抛出一个AssertionFailedError异常,JUnit测试框架将这种错误加以记录,同时标志为未通过测试。如果该类方法中指定一个String类型的参数,则该参数将被作为AssertionFailedError异常的标识信息,告诉测试人员该异常的详细信息。

JUnit提供了6大类31组断言方法,包括基础断言、数字断言、字符断言、布尔断言、对象断言等。具体描述如表5-1所示。

表5-1 常用的断言方法

其中assertEquals(Object expcted,Object actual)内部逻辑判断使用equals()方法,这表明在断言两个实例的内部哈希值是否相等时,最好使用该方法对相应类实例的值进行比较。而assertSame(Object expected,Object actual)内部逻辑判断使用了Java运算符“==”,这表明该断言判断两个实例是否来自于同一个引用(Reference),最好使用该方法对不同类的实例的值进行比对。

注意

还有一个方法assertEquals(String message,String expected,String actual),该方法对两个字符串进行逻辑比对,如果不匹配则显示这两个字符串有差异的地方。ComparisonFailure类提供两个字符串的比对,不匹配则给出详细的差异。

4.TestSuite测试包类——多个测试的组合

TestSuite类负责组装多个Test Case。待测包中可能包括了对被测试类的多个测试,而TestSuite负责收集这些测试,使我们可以在一个测试中,完成对被测试类的多个测试。

TestSuite类实现了Test接口,且可以包含其他的TestSuite。它可以处理加入Test时所有抛出的异常。

TestSuite处理测试用例有6个规约(否则会被拒绝执行测试),分别是:

(1)测试用例必须是公有类(public);

(2)测试用例必须继承于TestCase类;

(3)测试用例的测试方法必须是公有的(public);

(4)测试用例的测试方法必须被声明为void;

(5)测试用例中测试方法的前置名词必须是test;

(6)测试用例中测试方法无任何传递参数。

5.TestResult结果类和其他类与接口

TestResult结果类集合了任意测试的累加结果,通过TestResult实例传递给每个测试的run()方法。TestResult在执行TestCase时如果失败会抛出异常。

TestListener接口是个事件监听规约,可供TestRunner类使用。它将相关的事件通知给listener对象,方法包括:测试开始startTest(Test test)、测试结束endTest(Test test)、增加异常addError(Test test,Throwable t)和增加失败addFailure(Test test,AssertionFailedError t)。

TestFailure类是个“失败”状况的收集类,解释每次测试执行过程中出现的异常情况。它的toString()方法返回“失败”状况的简要描述。