这里有一些例子奉献给你,利用JUnit来编写和组织你自己的测试。
简单的测试案例
你怎样编写测试代码?
最简单的方法是在调试器中写一条代码了,然后修改调试器而不用重新编译。最后还得判断所看到的最终运行的是哪个对象。
同时,你也可以把测试代码作为完整的语句打印到标准输出流,例如:
public class Car{
public int getWheels() {
return 4;
}
}
//执行测试的类
public class testCar {
public static void main(String[] args) {
testCar myTest = new testCar();
myTest.testGetWheels();
}
public testGetWheels () {
int expectedWheels = 4;
Car myCar = Car();
if (expectedWheels==myCar.getWheels())
System.out.println("test [Car]: getWheels works perfected!");
else
System.out.println("test [Car]: getWheels DOESNT work!");
}
}
但是,两种测试风格都有局限性,因为他们需要程序员对结果进行判断与分析。同样,有时我只需要了解一条调试代码的结果,但有时在一个程序中却有太多的输出流,从而导致恐怖的"卷轴乱跳"。
JUnit测试就不需要程序员来解释,并且也能在同一时间方便地执行许多的测试。当你需要测试时,请按照以下方法:
1.构造一个TestCase类的实例;
2.创建一个构造器接收String参数来访问超类;
3.覆盖runTest()方法;
4.当你需要检测值时,调用带有boolean返回类型的方法assertTrue(),来判断是否测试成功。
例如,要测试两个Money对象的总和是否和预测的值相同时,就这样写:
public void testSimpleAdd() {
Money m12CHF= new Money(12, "CHF");
Money m14CHF= new Money(14, "CHF");
Money expected= new Money(26, "CHF");
Money result= m12CHF.add(m14CHF);
assertTrue(expected.equals(result));
}
如果你需要一个类似已存在的测试时,只需写一个Fixture来代替。当你需要一次运行很多测试时,创建一个Suite即可。
Fixture
如果你有两个以上对同一组对象基于相似或相同的测试时,该怎么办?
测试将创建一组(待测)对象为条件(如:Money f12CHF,Money m14CHF)。这组对象就叫做测试Fixture。当你在写测试的时候经常会发现,花费许多时间写Fixture会比你进行实际测试更有价值。
某种程度上,创建Fixture代码会比在构造器上小心翼翼更简单。另一方面,一个更大的优势来自于能够复用这些Fixture代码,你能经常地在各种测试代码中使用同样的Fixture。每个案例对信息和参数做细微地调整再送给Fixture,就可以测试不同地结果了。
按照这样,你就可以有一个公有的fixture了:
1.创建一个TestCase的子类;
2.创建一个可接收String类型参数的构造器,再传递给超类;
3.为每一Fixture部分增加一个实例变量;
4.覆盖setUp()方法来初始化变量,初始化所有测试的Fixture,甚至可以在setUp中建立网络连接。
5.tearDown()释放你在setUp()中分配的永久性资源,如数据库连接。
例如,给12瑞士法郎、14瑞士法郎、28美元的不同组合写测试方案,首先就要创建一个Fixture:
public class MoneyTest extends TestCase {
private Money f12CHF;
private Money f14CHF;
private Money f28USD;
protected void setUp() {
f12CHF= new Money(12, "CHF");
f14CHF= new Money(14, "CHF");
f28USD= new Money(28, "USD");
}
}
只需适当的编写Fixture,就可以随心所欲地进行测试了。
Test Case
在有了Fixture后怎样编写和调用单独的测试呢?
test case来简单代替Fixture,创建TestCase类的匿名子类并覆盖runTest()方法。为单独的测试建立匿名子类。你会注意到有少数这样的测试会占用很多行代码来实现。
JUnit提供更加简明的方法,你需要这样:
1.在fixture类中在创建test case方法,需要声明为Public,否则将不能通过映射调用。
2.创建一个TestCase类的实例,并传递test case方法的名字给构造器。
例如,对Money和MoneyBag进行加法运算:
public void testMoneyMoneyBag() {
// [12 CHF] + [14 CHF] + [28 USD] == {[26 CHF][28 USD]}
Money bag[]= { f26CHF, f28USD };
MoneyBag expected= new MoneyBag(bag);
assertEquals(expected, f12CHF.add(f28USD.add(f14CHF)));
}
创建MoneyTest的实例,并像这样运行test case:
new MoneyTest("testMoneyMoneyBag")
当测试运行时,各种测试方法将会被自动检测、运行。
一旦需要进行几个测试时,需要把他们组织在Suite中。
Suite
怎样一次性执行多个测试呢?
当你手头有多个测试时,第一反应就会想把他们放在一起测试,这样会更简单。在此之前,你会一个个地单独测试,直到感到厌倦。那么现在JUnit提供一个对象——TestSuite,它可以把许多测试放在一起。
例如,进行单一测试,就像这样:
TestResult result= (new MoneyTest("testMoneyMoneyBag")).run();
进行两个案例的集成测试,就像这样:
TestSuite suite= new TestSuite();
suite.addTest(new MoneyTest("testMoneyEquals"));
suite.addTest(new MoneyTest("testSimpleAdd"));
TestResult result= suite.run();
另一种方法就是让JUnit从TestCase中抽取suite。这样就可以把TestCase类传递给TestSuit构造器。
TestSuite suite= new TestSuite(MoneyTest.class);
TestResult result= suite.run();
用手工方法把多个测试案例的子集包含进suite,suite会自动的选择最佳方案。它能避免新增测试案例引起的重复更新suite代码。
TestSuite不仅包含TestCase,也包含满足Test接口的其他对象。例如,在你的代码中可以创建一个TestSuite,在我的代码中也可以,通过创建TestSuite,都可以把他们包含进来:
TestSuite suite= new TestSuite();
suite.addTest(Kent.suite());
suite.addTest(Erich.suite());
TestResult result= suite.run();
TestRunner
怎样既可以测试又可以收集它们的结果呢?
之前你可以创建一个test suite,并执行。JUnit提供众多的工具来定义suite并执行并显示结果。可以把集成测试和TestRunner工具通过静态方法suite()很好的结合,并返回test suite。
public static Test suite() {
TestSuite suite= new TestSuite();
suite.addTest(new MoneyTest("testMoneyEquals"));
suite.addTest(new MoneyTest("testSimpleAdd"));
return suite;
}
如果一个TestCase类不能定义suite()方法,TestRunner将会提取suite并填充以“test”开始的方法。
JUnit也为TestRunner提供图像和文字两种界面,输入java junit.awtui.TestRunner或者junit.swingui.TestRunner,图形用户界面就会呈现:
1.在输入框中选择适当的项目,
2.点击Run按钮开始测试,
3.下面的指示器有红绿两种,红代表失败,
4.在列表中查看失败的测试。
失败的情况下JUnit会在下面进行错误列表,JUnit会加以区别是failures还是errors。失败是指结果和断言(assertion)不一致,错误是指像ArrayIndexOutOfBoundsException这样的异常。如下图:
在动态编程环境中类似JAVA的VisualAge所支持”hot code update“,就可以始终使用JUnit的窗口。其他不支持这种特征的环境中进行不同测试时,也可以把JUnit的窗口关闭再打开,但这是很单调和浪费时间的。一种择中选择是用JUnit的AWT和Swing界面junit.runner.LoadingTestCollector。LoadingTestCollector会在不同测试时重新装载待测类。如果使用这个功能,”Reload classes every run“这个按钮将置为不可选。
JUnit有一系列接口,在命令提示符下运行java junit.textui.TestRunner,在后面加上带有suite方法的类。那么将会以文字界面输出,择中办法是在TestCase类中调用定义好的main方法。
例如,在TestRunner中运行MoneyTest:
public static void main(String args[]) {
junit.textui.TestRunner.run(suite());
}
通过定义main方法,只需在命令提示符中输入java MoneyTest即可。
当然,不管使用图形界面或文字界面,都必须确认junit.jar文件在你的CLASSPATH中。
本文地址:http://com.8s8s.com/it/it16625.htm