嘴對嘴告訴你怎麼用Junit進行測試之Junit3.8使用教程
目前的網際網路公司,尤其是小型的網際網路公司,對測試極其不重視,而如今快餐式的學習,往往也使開發者們忽略掉測試這一點。很多人都認為測試不重要,浪費時間,也有更多的人雖然知道測試的重要性,因卻為懶而不去寫測試。這些都是錯誤的認識,一個專案,我們可能花了20%的時間去寫業務程式碼,就可能會花80%的時間去寫測試程式碼去進行測試,但是如果不去測試的話,往往我們在後期在修改bug的時間不止這80%的時間,而且隨著專案需求的增多,業務邏輯會越來越複雜,可能導致修改一個bug得花費更長的時間,並且可能牽一髮而動全身(當然一個資深的程式員可能沒有頭髮),一個bug未落一個bug又起,最終與明月為伴。

閒言少敘,我們今天使用的是Junit的3.8,可能有人會說了:“現在都Junit5了啊兄dei!”,“誰還用Junit3.8,太low了吧!”,“垃圾文章,白看了!”,“PHP是世界上最好的程式語言!”等等。我們首先介紹Junit3.8主要是為了為後面學習Junit4.x, Junit5.x, 以及後面在分析Junit原始碼的文章中做鋪墊, Junit使用了大量的設計模式, 如果像學習設計模式的話, 分析Junit的原始碼無疑是一個不錯的選擇。
我使用的IDE是IntelliJ IDEA.
- 首先我們建立一個普通的maven專案 (當然我們也可以建立一個gradle專案, 也可以直接下載junit的jar包進行匯入, 後面這兩種方式我就不在此介紹), 然後在pom.xml檔案中加入Junit3.8的包:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.2</version> </dependency>
- 建立一個package, 比如 com.test.junit, 然後下package下建立一個類 Calculator.java 用於計算加減乘除:
package com.test.junit; public class Calculator { public int add(int a, int b) { return a + b; } public int minus(int a, int b) { return a - b; } public int multiply(int a, int b) { return a * b; } public int divide(int a, int b) throws Exception { if (0 == b) { throw new Exception("除數不能為0!"); } return a / b; } }
- 下面我們開始編寫測試用例, test/java 下建立包com.test.junit, 我們的測試用例的package最好與你所要測試的類的package是相同的結構, 這樣做他們編譯後的class檔案就會在同一級目錄中, 這不需要額外進行import待測試的類, 測試用例程式碼如下:
package com.test.junit; import junit.framework.Assert; import junit.framework.TestCase; public class CalculatorTest extends TestCase { private Calculator cal; @Override public void setUp() throws Exception { cal = new Calculator(); System.out.println("setUp"); } @Override public void tearDown() throws Exception { System.out.println("tearDown"); } public void testAdd() { int result = cal.add(1, 2); Assert.assertEquals(3, result); } public void testMinus() { int result = cal.minus(1, 2); Assert.assertEquals(-1, result); } public void testMultiply() { int result = cal.multiply(2, 3); Assert.assertEquals(6, result); } public void testDivide() { int result = 0; try { result = cal.divide(6, 4); } catch (Exception e) { e.printStackTrace(); Assert.fail(); } Assert.assertEquals(1, result); } public void testDivide2() { Throwable tx = null; try { cal.divide(4, 0); Assert.fail(); } catch (Exception e) { tx = e; } Assert.assertNotNull(tx); Assert.assertEquals(Exception.class, tx.getClass()); Assert.assertEquals("除數不能為0!", tx.getMessage()); } }
-
執行測試用例, 結果如下, 全綠的說明測試都通過了, 當然測試通過不代表你的程式碼沒有bug, 可能會有其他的一些情況使我們沒有想到的
這裡對測試用例簡單的進行一些說明:
- Junit3.8中我們的測試用例類必須繼承TestCase 類
- 測試方法必須是公有的(public), 無返回引數的(void), 無方法引數的方法, 並且必須以test開頭, test後面名字可以隨便取, 當然最好使用你要測試的方法名, 便於閱讀
- setUp方法會再每個測試方法前都執行一次, tearDown方法會再每個測試方法執行完後執行一次, 注意是每個測試測試方法執行前後都會執行(在Junit4中提供了可以在所有測試方法之前和之後只執行一次的註解, 我們可以用它來做一些資料庫初始化的操作, 這部分內容後面文章再進行介紹), 我們可以在setUp中進行一些初始化操作, 如上我們會再執行每個測試方法前都會生成一個Calculator的物件.
- 在測試方法中我們呼叫要測試的方法, 將結果與你期望的結果進行比較, 使用Assert.assertEquals(期望值, 實際值)
- 在測試異常情況時, 例如上面的例子的testDivide()方法, 我們期望輸入的值得到結果不會丟擲異常, 如果進入catch就說明有意外的錯誤, 需要加上Assert.fail()讓junit丟擲錯誤; 再看testDivide2(), 我們輸入的除數為0, 我們期望它丟擲異常, 所以當執行到cal.divide(4, 0)下一行的時候不是我們期望的, 我們期望的是進入catch中去, 所以我們需要在cal.divide(4, 0)後加上Assert.fail(); testDivede()如果丟擲異常了, 可能我們同樣也把它捕獲到了, 所以即使丟擲異常了, 測試也會通過, 所以我們需要在testDivide()的catch程式碼塊中加入Assert.fail()讓測試不能通過, 因為進入catch不是我們期望的; 這裡可能比較繞, 需要結合程式碼多理解理解.
Junit3相對來說比較簡單, 下篇文章將直接進入Junit4, Junit4中增加了一些新特性, 例如:
- 使用註解進行配置
- 進行引數化測試, 解決同一個方法輸入引數相同, 但是在junit3.8中需要每一種情況都需要寫一個測試方法, Junit4中可以提前預備好資料
- 可以在所有測試方法執行前進行初始化操作
- 等等
大家加油!
