介绍
JUnit 4.x 是利用了 Java 5 的特性(Annotation)的优点,使得测试比起 3.x 版本更加的方便简单,JUnit 4.x 不是旧版本的简单升级,它是一个全新的框架,整个框架的包结构已经完全改变,但 4.x 版本仍然可以很好的兼容旧版本的测试用例。
使用
先来点实在的,看看代码中是怎么使用的。其他的待会再说。
下载

加入项目
- 把 junit4.8.1.jar 文件,加入到项目的 classpath 中。
对比
在代码以前,先让咱们看一下 JUnit 4 和 JUnit 3 的区别,看看 JUnit 4 到底简化了哪些东西。
演示代码
1 import static org.junit.Assert.*;
2
3 import org.junit.Ignore;
4 import org.junit.Test;
5
6
7 public class TestWordDealUtil {
8 // 测试 wordFormat4DB 正常运行的状况
9 @Test
10 public void testWordFarmat4DBNormal() {
11 String target = "employeeInfo";
12 String result = WordDealUtil.wordFormat4DB(target);
13
14 assertEquals("employee_info", result);
15 }
16
17 // 测试 null 时的处理状况
18 @Test(expected=NullPointerException.class)
19 public void testWordFormat4DBNull() {
20 String target = null;
21 String result = WordDealUtil.wordFormat4DB(target);
22
23 assertNull(result);
24 }
25
26 // 测试空字符串的处理状况
27 @Test
28 public void testWordFormat4DBEmpty() {
29 String target = "";
30 String result = WordDealUtil.wordFormat4DB(target);
31
32 assertEquals("", result);
33 }
34
35 // 测试当首字母大写时的状况
36 //@Ignore
37 @Test
38 public void testWordFormat4DBBegin() {
39 String target = "EmployeeInfo";
40 String result = WordDealUtil.wordFormat4DB(target);
41
42 assertEquals("_employee_info", result);
43 }
44
45 // 测试当尾字母大写时的状况
46 @Test
47 public void testWordFormat4DBEnd() {
48 String target = "employeeInfoA";
49 String result = WordDealUtil.wordFormat4DB(target);
50
51 assertEquals("employee_info_a", result);
52 }
53
54 // 测试多个相连字母字母大写时的状况
55 @Test
56 public void testWordFormat4DBTogether() {
57 String target = "employeeAInfo";
58 String result = WordDealUtil.wordFormat4DB(target);
59
60 assertEquals("employee_a_info", result);
61 }
62 }
从图中能够看出,TestWordDealUtil 测试类中,有6个测试方法,其中有5个测试方法都已经经过,另一个抛出了 NullPointerException (空指针)异常,须要注意的是,这里并非单元测试的失败(Failure),而是测试出现了错误(Error)。那么,这两种有什么区别呢?下面就讨论一下这二者的区别。
JUnit 将测试失败的状况分为两种:Failure 和 Error 。 Failure 通常是由单元测试使用的断言方法判断失败引发的,它表示在测试点发现了问题(程序中的 bug);而 Error 则是有代码异常引发的,这是测试目的以外的发现,它可能产生于测试代码自己的错误(也就是说,编写的测试代码有问题),也多是被测试代码中的一个隐藏 bug 。不过,通常状况下是第一种状况。
深刻
经常使用注解
初始化方法,在任何一个测试方法执行以前,必须执行的代码。对比 JUnit 3 ,和 setUp()方法具备相同的功能。在该注解的方法中,能够进行一些准备工做,好比初始化对象,打开网络链接等。
释放资源,在任何一个测试方法执行以后,须要进行的收尾工做。对比 JUnit 3 ,和 tearDown()方法具备相同的功能。
测试方法,代表这是一个测试方法。在 JUnit 中将会自动被执行。对与方法的声明也有以下要求:名字能够随便取,没有任何限制,可是返回值必须为 void ,并且不能有任何参数。若是违反这些规定,会在运行时抛出一个异常。不过,为了培养一个好的编程习惯,咱们通常在测试的方法名上加 test ,好比:testAdd()。
同时,该 Annotation(@Test) 还能够测试指望异常和超时时间,如 @Test(timeout=100),咱们给测试函数设定一个执行时间,超过这个时间(100毫秒),他们就会被系统强行终止,而且系统还会向你汇报该函数结束的缘由是由于超时,这样你就能够发现这些 bug 了。并且,它还能够测试指望的异常,例如,咱们刚刚的那个空指针异常就能够这样:@Test(expected=NullPointerException.class)。再来看一下测试结果。
忽略的测试方法,标注的含义就是“某些方法还没有完成,咱不参与这次测试”;这样的话测试结果就会提示你有几个测试被忽略,而不是失败。一旦你完成了相应的函数,只须要把 @Ignore 注解删除便可,就能够进行正常测试了。固然,这个 @Ignore 注解对于像我这样有“强迫症”的人仍是大有意义的。每当看到红色条(测试失败)的时候就会全身不舒服,感受没法忍受(除非要测试的目的就是让它失败)。固然,对代码也是同样,没法忍受那些杂乱不堪的代码。因此,建议你们都写漂亮的代码。这样人人都喜欢看你的代码。哎,有强迫症的人伤不起啊!
针对全部测试,也就是整个测试类中,在全部测试方法执行前,都会先执行由它注解的方法,并且只执行一次。固然,须要注意的是,修饰符必须是 public static void xxxx ;此 Annotation 是 JUnit 4 新增的功能。
针对全部测试,也就是整个测试类中,在全部测试方法都执行完以后,才会执行由它注解的方法,并且只执行一次。固然,须要注意的是,修饰符也必须是 public static void xxxx ;此 Annotation 也是 JUnit 4 新增的功能,与 @BeforeClass 是一对。
执行顺序
因此,在 JUnit 4 中,单元测试用例的执行顺序为:
每个测试方法的调用顺序为:编程

规范
最后,在来讲说关于测试的规范,这些规范是从编程规则,以及平常的实践中,由那些大牛们总结出来的。做为后人的咱们,在大树下乘凉的同时,更要遵照这些规则,使得大树更加茁壮成长。
- 单元测试代码应位于单独的 Source Folder 下
此 Source Folder 一般为 test ,这样能够方便的管理业务代码与测试代码。其实,在项目管理工具 Maven 上已经作了这种规范了。在咱们本身写代码时,注意一下便可。
便于进行管理,同时减小引入带测试类的麻烦。
不管是 JUnit 4 ,仍是 JUnit 3 ,单元测试方法名均需使用
test<待测试方法名称>[概要描述] ,如 public void testDivideDivisorIsZero() ,很容易知道测试方法的含义。
每项单元测试都必须独立于其余全部单元测试而运行,由于单元测试需能以任何顺序运行。
- 为暂时未实现的测试代码忽略(@Ignore)或抛出失败(fail)
在 JUnit 4 中,能够在测试方法上使用注解 @Ignore 。在 JUnit 3 中,能够在未实现的测试方法中使用 fail("测试方法未实现"); 以告知失败是由于测试方法未实现。
在使用断言方法时,请使用带有 message 参数的 API ,并在调用时给出失败时的缘由描述,如 assertNotNull("对象为空", new Object())。
结束语
请牢记:测试任何可能的错误。单元测试不是用来证实您是对的,而是为了证实您没有错。
JUnit 4 到这里就差很少了,若是文章中有什么不对的地方,还但愿各位大牛拍砖。说了这么多,能真正用上才是王道,固然,但愿以我这篇文章为契机,IT 界的精英们,以前没有用单元测试的,可以唤醒大家体内的小宇宙;以前已经在用的,也可以再体会一番,提升开发的效率,写出
漂亮 的代码。