單元測試JUnit 4

介紹

 
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 。不過,通常狀況下是第一種狀況。
 
 

深刻

 

經常使用註解

  • @Before
初始化方法,在任何一個測試方法執行以前,必須執行的代碼。對比 JUnit 3 ,和 setUp()方法具備相同的功能。在該註解的方法中,能夠進行一些準備工做,好比初始化對象,打開網絡鏈接等。
 
  • @After
釋放資源,在任何一個測試方法執行以後,須要進行的收尾工做。對比 JUnit 3 ,和 tearDown()方法具備相同的功能。
 
  • @Test
測試方法,代表這是一個測試方法。在 JUnit 中將會自動被執行。對與方法的聲明也有以下要求:名字能夠隨便取,沒有任何限制,可是返回值必須爲 void ,並且不能有任何參數。若是違反這些規定,會在運行時拋出一個異常。不過,爲了培養一個好的編程習慣,咱們通常在測試的方法名上加 test ,好比:testAdd()。
 
同時,該 Annotation(@Test) 還能夠測試指望異常和超時時間,如 @Test(timeout=100),咱們給測試函數設定一個執行時間,超過這個時間(100毫秒),他們就會被系統強行終止,而且系統還會向你彙報該函數結束的緣由是由於超時,這樣你就能夠發現這些 bug 了。並且,它還能夠測試指望的異常,例如,咱們剛剛的那個空指針異常就能夠這樣:@Test(expected=NullPointerException.class)。再來看一下測試結果。
 

 

 

 
  • @Ignore
忽略的測試方法,標註的含義就是「某些方法還沒有完成,咱不參與這次測試」;這樣的話測試結果就會提示你有幾個測試被忽略,而不是失敗。一旦你完成了相應的函數,只須要把 @Ignore 註解刪除便可,就能夠進行正常測試了。固然,這個 @Ignore 註解對於像我這樣有「強迫症」的人仍是大有意義的。每當看到紅色條(測試失敗)的時候就會全身不舒服,感受沒法忍受(除非要測試的目的就是讓它失敗)。固然,對代碼也是同樣,沒法忍受那些雜亂不堪的代碼。因此,建議你們都寫漂亮的代碼。這樣人人都喜歡看你的代碼。哎,有強迫症的人傷不起啊!
 
  • @BeforeClass
針對全部測試,也就是整個測試類中,在全部測試方法執行前,都會先執行由它註解的方法,並且只執行一次。固然,須要注意的是,修飾符必須是 public static void xxxx ;此 Annotation 是 JUnit 4 新增的功能。
 
  • @AfterClass
針對全部測試,也就是整個測試類中,在全部測試方法都執行完以後,纔會執行由它註解的方法,並且只執行一次。固然,須要注意的是,修飾符也必須是 public static void xxxx ;此 Annotation 也是 JUnit 4 新增的功能,與 @BeforeClass 是一對。
 
 

執行順序

 
因此,在 JUnit 4 中,單元測試用例的執行順序爲:
 

 

 


每個測試方法的調用順序爲:編程

 

 

 

 
 

規範

 
最後,在來講說關於測試的規範,這些規範是從編程規則,以及平常的實踐中,由那些大牛們總結出來的。做爲後人的咱們,在大樹下乘涼的同時,更要遵照這些規則,使得大樹更加茁壯成長。
  • 單元測試代碼應位於單獨的 Source Folder 下
此 Source Folder 一般爲 test ,這樣能夠方便的管理業務代碼與測試代碼。其實,在項目管理工具 Maven 上已經作了這種規範了。在咱們本身寫代碼時,注意一下便可。
 
 
  • 測試類應該與被測試類位於同一 package 下
便於進行管理,同時減小引入帶測試類的麻煩。

 

 

 

  • 選擇有意義的測試方法名
不管是 JUnit 4 ,仍是 JUnit 3 ,單元測試方法名均需使用  test<待測試方法名稱>[概要描述] ,如 public void testDivideDivisorIsZero() ,很容易知道測試方法的含義。
 
  • 保存測試的獨立性
每項單元測試都必須獨立於其餘全部單元測試而運行,由於單元測試需能以任何順序運行。
 
  • 爲暫時未實現的測試代碼忽略(@Ignore)或拋出失敗(fail)
在 JUnit 4 中,能夠在測試方法上使用註解 @Ignore 。在 JUnit 3 中,能夠在未實現的測試方法中使用 fail("測試方法未實現"); 以告知失敗是由於測試方法未實現。
 
  • 在調用斷言(assert)方法時給出失敗的緣由
在使用斷言方法時,請使用帶有 message 參數的 API ,並在調用時給出失敗時的緣由描述,如 assertNotNull("對象爲空", new Object())。
 
 

結束語

 
請牢記:測試任何可能的錯誤。單元測試不是用來證實您是對的,而是爲了證實您沒有錯。
 
JUnit 4 到這裏就差很少了,若是文章中有什麼不對的地方,還但願各位大牛拍磚。說了這麼多,能真正用上纔是王道,固然,但願以我這篇文章爲契機,IT 界的精英們,以前沒有用單元測試的,可以喚醒大家體內的小宇宙;以前已經在用的,也可以再體會一番,提升開發的效率,寫出  漂亮 的代碼。
相關文章
相關標籤/搜索