單元測試工具——Junit
1.Junit簡介
JUnit是一個Java語言的單元測試框架。多數Java的開發環境都已經集成了JUnit作為單元測試的工具。Junit測試是程序員測試,即所謂白盒測試,因為程序員知道被測試的軟件如何(How)完成功能和完成什么樣(What)的功能。Junit是一套框架,繼承TestCase類,就可以用Junit進行自動測試了。
JUnit通過注解的方式來識別測試方法。目前支持的主要注解有:
@BeforeClass: 修飾的方法會在所有方法被調用前執行,且該方法時靜態的,所以當測試類被加載后就接着運行它,而且在內存中他只會存在一份實例,他比較適合加載配置文件(針對所有測試,只執行一次 )
@AfterClass: 所修飾的方法通常用來對資源管理,如關閉數據庫連接(針對所有測試,只執行一次 )
@Before和@After 會在每個測試方法前后各執行一次
@Test:測試方法,在這里可以測試期望異常和超時時間
@Ignore:忽略的測試方法
2.Junit特性
① 用於測試期望結果的斷言(Assertion)
② 用於共享共同測試數據的測試工具
③ 用於方便的組織和運行測試的測試套件
④ 圖形和文本的測試運行器
3.安裝
下載完以后解壓到你喜歡的目錄下,假設是JUNIT_HOME,然后將JUNIT_HOME下的junit.jar包加到你的系統的CLASSPATH環境變量中,對於IDE環境,對於需要用到的junit的項目增加到lib中,其設置不同的IDE有不同的設置,這里不多講。
而eclipse中自帶JUnit,我們可以直接使用。
4.測試
(1)新建一個工程,新建一個要測試的類Calculator。
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; } }
(2)工程右鍵,點擊Properties
(3)點擊下面的Classpath,之后點擊Add Library,
(4)點擊JUnit
(5)先選擇版本,然后finish
(6)點擊Apply and Close
(7)在Eclipse的Package Explorer中用右鍵點擊要測試的類,彈出菜單,選擇New →Unit Test Case。如下圖所示:
(8)選擇要測試的版本,填寫測試類名
(9)選擇測試方法
(10)然后就會發現多了一個類
(11)千萬不要去刪除@Test!!!!!然后把fail(“Not yet imolemented ”)刪除,自己的代碼敲進去就可以了。
import static org.junit.Assert.*; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; public class CalculatorTest { private static Calculator calculator = new Calculator(); @Before public void setUp() throws Exception { calculator.clear(); } @Test public void testAdd() { calculator.add(3); calculator.add(4); assertEquals(7, calculator.getResult()); } @Test public void testSubstract() { calculator.add(8); calculator.substract(3); assertEquals(5, calculator.getResult()); } @Ignore("Multiply() Not yet implemented") @Test public void testMultiply() { fail("Not yet implemented"); } @Test public void testDivide() { calculator.add(8); calculator.divide(2); assertEquals(4, calculator.getResult()); } }
(12)右鍵測試類,點擊run as → Junit Test
(12)運行結果
進度條是紅色表示發現錯誤,具體的測試結果在進度條上面有表示“共進行了4個測試,其中1個測試被忽略,一個測試失敗”。
限時測試
對於那些邏輯很復雜,循環嵌套比較深的程序,很有可能出現死循環,因此一定要采取一些預防措施。限時測試是一個很好的解決方案。我們給這些測試函數設定一個執行時間,超過了這個時間,他們就會被系統強行終止,並且系統還會向你匯報該函數結束的原因是因為超時,這樣你就可以發現這些Bug了。要實現這一功能,只需要給@Test標注加一個參數即可,代碼如下:
@Test(timeout = 1000) public void squareRoot() { calculator.squareRoot(4); assertEquals(2, calculator.getResult()); }
Timeout參數表明了你要設定的時間,單位為毫秒,因此1000就代表1秒。
5.總結
- 在軟件測試這門課中自學了JUnit的使用方法,起初我使用的時候覺得這個軟件太麻煩了!測試一段代碼竟然還需要我再去敲一段代碼……這樣太麻煩了!!后來我就去搜集了一些資料,想要了解單元測試的必要性。
- 那么單元測試為何又備受追捧呢?在How Google Tests Software中,三位谷歌的專家介紹了谷歌的軟件測試之道,總而言之就是谷歌會在開發之初設計好單元測試(其實是用代碼表達需求),在開發中不斷迭代以通過全部的測試(其實是完成全部需求),最終交付給測試人員的軟件已經經過一輪測試,如果還有集成后的Bug,就可以交給專業的測試人員發現了。這是一種典型的敏捷開發,可以看到單元測試扮演更多的是驅動開發的角色。
- 有很多公司非常准確地把單元測試叫做“開發自測”,並且非常准確地認識到了這個活動的重要性:程序員只要認真測一測自己寫的代碼,bug就能減少90%。所以說,雖然很麻煩!但是單元測試還是很有必要的!!
6.參考及特別鳴謝
趙裕(騰訊 終端工程師):你真的需要單元測試嗎?(https://zhuanlan.zhihu.com/p/35508972)