jUnit4 概述
jUnit4 是 JUnit 框架有史以来的最大改进,其主要目标便是利用 Java5 的 Annotation(注解功
能)特性简化测试用例的编写。
先简单解释一下什么是 Annotation,这个单词一般是翻译成元数据。元数据是什么?元数据
就是描述数据的数据。也就是说,这个东西在 Java 里面可以用来和 public、static 等关键字
一样来修饰类名、方法名、变量名。修饰的作用描述这个数据是做什么用的,差不多和 public
描述这个数据是公有的一样。想具体了解可以看 Core
Java2。废话不多说了,直接进入
正题。
我们先看一下在 JUnit 3 中我们是怎样写一个单元测试的。比如下面一个类:
public class AddOperation {
public int add(int x,int y){
return x+y;
}
}
我们要测试 add 这个方法,我们写单元测试得这么写:
import junit.framework.TestCase;
import static org.junit.Assert.*;
public class AddOperationTest extends TestCase{
public void setUp() throws Exception {
}
public void tearDown() throws Exception {
}
public void testAdd() {
System.out.println(\"add\");
int x = 0;
int y = 0;
AddOperation instance = new AddOperation();
int expResult = 0;
int result = instance.add(x, y);
assertEquals(expResult, result);
}
}
可以看到上面的类使用了 JDK5 中的静态导入,这个相对来说就很简单,只要在 import 关键
字后面加上 static 关键字,就可以把后面的类的 static 的变量和方法导入到这个类中,调用
的时候和调用自己的方法没有任何区别。
我们可以看到上面那个单元测试有一些比较霸道的地方,表现在:
1.单元测试类必须继承自 TestCase。
2.要测试的方法必须以 test 开头。
如果上面那个单元测试在 JUnit 4 中写就不会这么复杂。代码如下:
import junit.framework.TestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author bean
*/
public class AddOperationTest extends TestCase{
public AddOperationTest() {
}
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void add() {
System.out.println(\"add\");
int x = 0;
int y = 0;
AddOperation instance = new AddOperation();
int expResult = 0;
int result = instance.add(x, y);
assertEquals(expResult, result);
}
}
我们可以看到,采用 Annotation 的 JUnit 已经不会霸道的要求你必须继承自 TestCase 了,而
且测试方法也不必以 test 开头了,只要以@Test 元数据来描述即可。
从上面的例子可以看到在 JUnit 4 中还引入了一些其他的元数据,下面一一介绍:
@Before:
使用了该元数据的方法在每个测试方法执行之前都要执行一次。
@After:
使用了该元数据的方法在每个测试方法执行之后要执行一次。
注意:@Before 和@After 标示的方法只能各有一个。这个相当于取代了 JUnit 以前版本中的
setUp 和 tearDown 方法,当然你还可以继续叫这个名字,不过 JUnit 不会霸道的要求你这么
做了。
@Test(expected=*.class)
在 JUnit4.0 之前,对错误的测试,我们只能通过 fail 来产生一个错误,并在 try 块里面 assertTrue
(true)来测试。现在,通过@Test 元数据中的 expected 属性。expected 属性的值是一个异
常的类型
@Test(timeout=xxx):
该元数据传入了一个时间(毫秒)给测试方法,
如果测试方法在制定的时间之内没有运行完,则测试也失败。
@ignore:
该元数据标记的测试方法在测试中会被忽略。当测试的方法还没有实现,或者测试的方法已
经过时,或者在某种条件下才能测试该方法(比如需要一个数据库联接,而在本地测试的时
候,数据库并没有连接),那么使用该标签来标示这个方法。同时,你可以为该标签传递一
个 String 的参数,来表明为什么会忽略这个测试方法。比如:@lgnore(“该方法还没有实现”),
在执行的时候,仅会报告该方法没有实现,而不会运行测试方法。
在 Eclipse 中使用 JUnit4 进行单元测试(初级篇)
我们在编写大型程序的时候,需要写成千上万个方法或函数,这些函数的功能可能很强大,
但我们在程序中只用到该函数的一小部分功能,并且经过调试可以确定,这一小部分功能是
正确的。但是,我们同时应该确保每一个函数都完全正确,因为如果我们今后如果对程序进
行扩展,用到了某个函数的其他功能,而这个功能有 bug 的话,那绝对是一件非常郁闷的事
情。所以说,每编写完一个函数之后,都应该对这个函数的方方面面进行测试,这样的测试
我们称之为单元测试。传统的编程方式,进行单元测试是一件很麻烦的事情,你要重新写另
外一个程序,在该程序中调用你需要测试的方法,并且仔细观察运行结果,看看是否有错。
正因为如此麻烦,所以程序员们编写单元测试的热情不是很高。于是有一个牛人推出了单元
测试包,大大简化了进行单元测试所要做的工作,这就是 JUnit4。本文简要介绍一下在
Eclipse3.2 中使用 JUnit4 进行单元测试的方法。
首先,我们来一个傻瓜式速成教程,不要问为什么,Follow Me,先来体验一下单元测试的
快感!
首先新建一个项目叫 JUnit_Test,我们编写一个 Calculator 类,这是一个能够简单实现加减
乘除、平方、开方的计算器类,然后对这些功能进行单元测试。这个类并不是很完美,我们
故意保留了一些 Bug 用于演示,这些 Bug 在注释中都有说明。该类代码如下:
package andycpp;
public class Calculator ...{
private static int result; // 静态变量,用于存储运行结果
public void add(int n) ...{
result = result + n;
}
public void substract(int n) ...{
result = result - 1;
//Bug: 正确的应该是 result =result-n
}
public void multiply(int n) ...{
}
public void divide(int n) ...{
// 此方法尚未写好
result = result / n;
}
public void square(int n) ...{
result = n * n;
}
public void squareRoot(int n) ...{
for (; ;) ;
//Bug : 死循环
}
public void clear() ...{
result = 0;
}
// 将结果清零
public int getResult() ...{
return result;
}
}
第二步,将 JUnit4 单元测试包引入这个项目:在该项目上点右键,点“属性”,如图:
在弹出的属性窗口中,首先在左边选择“Java Build Path”,然后到右上选择“Libraries”标签,
之后在最右边点击“Add Library…”按钮,如下图所示:
然后在新弹出的对话框中选择 JUnit4 并点击确定,如上图所示,JUnit4 软件包就被包含进
我们这个项目了。
第三步,生成 JUnit 测试框架:在 Eclipse 的 Package Explorer 中用右键点击该类弹出菜
单,选择“New à JUnit Test Case”。如下图所示:
在弹出的对话框中,进行相应的选择,如下图所示:
点击“下一步”后,系统会自动列出你这个类中包含的方法,选择你要进行测试的方法。
此例中,我们仅对“加、减、乘、除”四个方法进行测试。如下图所示: