简单的框架
JUnit是由Erich Gamma和Kent Beck开发的开源测试框架JBuilder集成了这个框架并对此做了扩展JUnit之所以流行并为广大的开发人员所推崇一是因为它实战性强功能强大二是因为它实在简单一个产品或框架要能有生命力最好都具备这样的特点
简单地讲这个框架提供了许多断言(assert)方法允许你设置测试的规则如assertEquals()assertNull()assertNotSame()assertTrue()等方法一个测试用例包括了多个断言当运行测试用例后JUnit运行器会报告哪些断言没有通过开发人员就可顺籐摸瓜搞个水落石出了而传统的测试方法需要将期望的结果用诸如Systemoutprintln()等语句将过程信息打印到控制台或日志中由开发人员观察输出信息以判断是否正确现在这种观察的工作由JUnit的那些assertXxx()方法自动完成
JUnit的测试框架类结构很简单主要由个类组成其类图关系如下图所示
图 错误!文档中没有指定样式的文字JUnit测试框架类结构
·junitframeworkTest测试接口
·junitframeworkTestCase测试用例类业务类的测试用例类只需要承继这个TestCase根据情况编写若干个public void testXxx()方法在方法中通过assertYyy()定制若干测试规则就可以了
·junitframeworkTestSuite测试套件类它可以将多个测试用例类捆绑在一起运行也可以捆绑另一个测试套件
测试固件(Fixture)
一个测试用例可以包含若干个testXxx()测试方法测试用例测试一个或多个类API接口的正确性当然在调用类API时需要事先创建这个类的对象及一些关联的对象这组对象就称为测试固件(Fixture)相当于测试用例的工作对象
我们在前面说过一个测试用例类可以包含多个testXxx()方法在运行时每个测试方法都对应一个测试用例类的实例当然你可以在具体的testXxx()方法里声明并实例化业务类的实例在测试完成后再销毁它们但是这么一来你就要在每个testXxx()方法中都重复这些代码因为TestCase实例被运行时依照以下步骤运行
.创建测试用例的实例
.调用setUp()方法执行一些初始化工作
.运行testXxx()测试方法
.调用tearDown()方法执行销毁对象的工作
如果测试用例类中有多个testXxx()方法且它们都需要使用到相同的一组对象我们可以在setUp()中实例化这组对象并在tearDown()中销毁它们要编写测试固件依照以下步骤进行
.创建TestCase类的子类
.在子类中声明若干个测试所用的对象
.覆盖setUp()方法在方法中实例化这些对象
.覆盖tearDown()方法释放这些对象的资源
如下面即是一个简单的测试固件
代码清单 错误!文档中没有指定样式的文字测试固件
public class MoneyTest extends TestCase
{
private Money fCHF;//瑞士法郎
private Money fCHF; //瑞士法郎
private Money fUSD; //美国美元
protected void setUp() {
fCHF= new Money( CHF);
fCHF= new Money( CHF);
fUSD= new Money( USD);
}
protected void tearDown(){}
}
第~行声明了个Money类对象(测试固件)在setUp()方法中实例化这个对象(第~行)由于这些对象可以被垃圾进行直接回收所以在tearDown()中不做任何操作
测试用例(TestCase)
有了测试固件就可以开始编写测试用例的测试方法了当然你也可不需要测试固件而直接编写测试用例方法下面我们在测试固件的基础上添加测试用例方法testMoneyBag()代码如下所示
代码清单 错误!文档中没有指定样式的文字测试用例方法
public class MoneyTest extends TestCase
{
private Money fCHF;//瑞士法郎
private Money fCHF; //瑞士法郎
private Money fUSD; //美国美元
protected void setUp() {
fCHF= new Money( CHF);
fCHF= new Money( CHF);
fUSD= new Money( USD);
}
public void testMoneyBag()
{
Money bag[]= { fCHF fUSD };
MoneyBag expected= new MoneyBag(bag);
assertEquals(expected fCHFadd(fUSDadd(fCHF)));
}
protected void tearDown(){}
}
测试方法都必须以test为前缀且必须是public void的运行器以此为反射查找规则找到这些测试用例方法在一个方法中可以包括多个assertYyy()方法每个assertYyy()方法都是一个测试规则像第行的assertYyy()断言方法即为测试Money的add()方法和MoneyBag类正确性的测试规则
你可以在MoneyTest中添加多个public void testXxx()方法运行器为每个方法生成一个测试用例实例分别运行
测试套件(TestSuite)
如果每次只能运行一个测试用例那么又陷入了我们前面所谈到的传统测试的窘境手工去运行一个个测试用例测试套件专门为解决这一问题而来它通过TestSuite对象将多个测试用例组装成到一个测试套件则测试套件批量运行需要特殊指出的是可以把一个测试套件整个添加到另一个测试套件中就象小筐装进大筐里变成一个箧一样
测试套件类也通过承继TestCase类实现只不过它提供了一个public static Test suite()静态方法在该方法中将多个测试用例捆绑组装在一起一个典型的测试套件代码如下所示
代码清单 错误!文档中没有指定样式的文字测试套件
public class MoneyTestSuite extends TestCase
{
public TestSuite(String s)
{
super(s);
}
public static Test suite()
{
TestSuite suite = new TestSuite();
suiteaddTestSuite(MoneyTestclass);
suiteaddTestSuite(MoneyBagclass);
return suite;
}
}
在第行中声明并实例化了一个TestSuite在第行分别加入一个测试用例你可以通过suiteaddTest(Test t)方法添加一个套件这样运行这个套件就可以自动运行所有测试用例的测试方法了
测试运行器
JUnit提供了个标准的测试运行器运行这些测试用例或测试套件这个测试运行器分别是
·junittextuiTestRunner文本测试运行器
·junitawtuiTestRunner使用AWT组件界面的测试运行器
·junitswinguiTestRunner使用Swing组件界面的测试运行器
下面是基于AWT组件的测试运行器如下图所示
图 错误!文档中没有指定样式的文字AWT测试运行器
·Test class name指定测试用例类和测试套件类
·一个进度条表示运行测试的执行进度进度条下是正确错误失败的测试统计数
·Error and Failures列出了测试错误和失败的列表点选其中的一个选项时JUnit在窗口底部列出错误跟蹤迹
提示
JBuilder提供了方便的运行测试用例和测试套件类的方法你只须点击鼠标右键就可直接调用了此外JBuilder提供了一个JBTestRunner测试运行器在功能和易用性上非JUnit提供的测试运行器所能媲美JBuilder支持JUnit所提供的两个测试运行器junittextuiTestRunner和junitswinguiTestRunner