Java知識積累——單元測試和JUnit(一)

來源:互聯網
上載者:User

    說起單元測試,剛畢業或者沒畢業的人可能大多停留在課本講述的定義階段,至於具體是怎麼定義的,估計也不會有太多人記得。我們的教育總是這樣讓人“欣慰”。那麼什麼是單元測試呢?具體科學的定義咱就不去關心了,其實每個寫代碼的人都在時刻進行著單元測試,除非你從來不驗證自己寫的代碼能否達到預期目的,而是直接寫完就完事兒了,連run一下都不進行。

    單元測試說的直白一點,就是驗證寫得一段代碼是否正確,可能是一個類,可能是一個函數,甚至可能是一個迴圈。為了測試的方便,我們一般直接就在寫好的可運行代碼中直接進行測試,看到控制台輸出了預想的結果或者拋出了異常。但是進入了公司,這樣的測試方法極不專業也不不容易複現測試環境。那麼可能需要專門寫一個測試類別,調用你想測試的代碼單元,然後進行測試。但是這樣每次都需要建立類,編寫測試案例,相當之麻煩。

    說了這麼多,福利來了。單元測試工具——JUnit。協助我們進行單元測試,提供諸多便利。下面介紹如何在Eclipse中利用JUnit進行單元測試。

 

假如,我們編寫了一個Calculator,提供一些簡單的計算機功能。代碼如下,故意留一些bug。

 1 package org.logback.test; 2  3 public class Calculator { 4      5     private static int result; 6     // 靜態變數,用於儲存運行結果 7  8     public void add(int n) { 9 10     result = result + n;11 12     }13 14     public void substract(int n) {15 16     result = result - 1; //Bug: 正確的應該是 result = result-n17 18     }19 20     public void multiply(int n) {21 22     } // 此方法尚未實現23 24     public void divide(int n) {25 26     result = result / n;27 28     }29 30     public void square(int n) {31 32     result = n * n;33 34     }35 36     public void squareRoot(int n) {37 38     for (; ;) ; //Bug : 死迴圈39 40     }41 42     public void clear() { // 將結果清零43 44     result = 0;45 46     }47 48     public int getResult() {49 50     return result;51 52     }53 }

 

那麼要對這個類在現有開發程度下進行單元測試了,方法很簡單,首先在該類所屬的工程名上右鍵進入Properties。

 

在彈出的Properties視窗,左側選擇Java Build Path,然後右側選擇Libraries標籤卡,最後選擇Add Library。

在彈出的Add Library視窗中,選擇JUnit點擊Next,然後在下拉式功能表中選擇JUnit4,點擊Finish。

這樣JUnit就被引入了項目的Libraries中,點擊OK。在要進行測試的那個類上右鍵,選擇new→JUnit Test Case。

在彈出的建立視窗中按如下設定,具體含義稍後講解

這裡可以選擇將測試類別放在專門的測試包中,並且給測試類別起一個顯而易見的名字。選擇Next,然後進入了。

此處是選擇要測試的方法,假如我們只測試加減乘除4個方法,則勾選對應的4個方法,點擊Finish。則自動產生了一個測試類別,不過我們仍需對此類進行一定的修改,將該測試類別最終修改為如下代碼

 1 package org.logback.test; 2  3 import static org.junit.Assert.*; 4  5 import org.junit.After; 6 import org.junit.AfterClass; 7 import org.junit.Before; 8 import org.junit.BeforeClass; 9 import org.junit.Ignore;10 import org.junit.Test;11 12 public class CalculatorTest {13     14     private static Calculator example = new Calculator();15 16     @Before//在每個測試方法執行前先執行的方法17     public void setUp() throws Exception {18         example.clear();19     }20     21     @After//在每個測試方法執行後立刻執行的方法22     public void setDown(){23         System.out.println("over");24     }25     26     @BeforeClass //在類載入的時候調用的方法,必須public和static的,只調用一次27     public static void start(){28         System.out.println("start class");29     }30     31     @AfterClass //在類結束的時候調用的方法,必須public和static的,只調用一次32     public static void destory(){33         System.out.println("destory class");34     }35     36     @Test37     public void testAdd() {38         example.add(2);39         example.add(3);40         assertEquals(5, example.getResult());41     }42 43     @Test44     public void testSubstract() {45         example.add(10);46         example.substract(2);47         assertEquals(8, example.getResult());48     }49 50     @Ignore//因該方法暫未實現而忽略測試51     @Test52     public void testMultiply() {53         fail("Not yet implemented");54     }55 56     @Test57     public void testDivide() {58         example.add(8);59         example.divide(2);60         assertEquals(4, example.getResult());61     }62     63     @Test(timeout = 1000)//設定時間限制,單位是毫秒,逾時即算測試失敗64     public void testsquareRoot(){65         example.squareRoot(4);66         assertEquals(2, example.getResult());67     }68 69     @Test(expected = ArithmeticException.class)//測試是否能如期拋出該異常70     public void divideByZero(){71         example.divide(0);//除數為0,如能正確拋出異常,則測試通過,否則測試失敗72     }73 }

 

每個方法都有注釋,以標明其具體用途。

為了要測試Calculator的功能,所以需要先建立一個對應的執行個體,就如14行所做的那樣。代碼中出現了很多@開頭的東西,下面簡單介紹一下。以@開頭的稱為標註,是JDK1.5引入的特性,簡介一下JUnit中常用的標註的含義:

@Test 標註的方法為測試方法,包含屬性timeout(用於設定時間限制,以毫秒為單位,超過限制時間,該測試則以失敗返回)、expected(設定此處應該拋出的異常,如果真拋出了該異常,則測試成功,否則失敗)

@Before  標註的方法會在每個測試方法執行前先執行一次

@After 標註的方法會在每個測試方法執行結束後執行一次

@BeforeClass  標註的方法會在類載入的時候執行一次,且僅此一次,該方法必須是public和static的

@AfterClass   標註的方法會在類銷毀的時候執行一次,且僅此一次,該方法必須是public和static的

@Ignore  標註的方法表示因為要測試的方法仍未實現而忽略測試

@Parameters  標註的方法用於定義測試資料集合,一般用來給一個測試方法傳遞多組測試資料

 

以上標註都是用來標註方法的,下面介紹兩個用來標註類的:

@RunWith(classname.class)  指定此測試採用什麼運行器,如果不設定,則採用預設的運行器,就像我們上一個例子中那樣。

@Suite.SuiteClasses({

   TestClassName1.class,

   TestClassName2.class,

   ...

})   打包測試,有時會遇到同一個類的測試類別有很多個,逐個運行測試太麻煩了,那就通過這種方式將所有要啟動並執行測試類別一起運行。文章後面會給出例子。

 

介紹完標註之後,再來看一下測試方法中用到的assertEquals的功能。該方法有兩個參數,第一個是預期的值,第二個是傳遞給方法的結果,用以比對方法處理後的結果與預期是否一致,因此來返回測試是否成功還是失敗。

 

用之前的代碼進行測試,步驟如下:

在類中右鍵Run As → JUnit Test

可以看到左側JUnit標籤出現如所示結果:

最上方的深紅色進度條,表示有測試方法返回失敗。然後列出了6個測試方法,藍色X表示預期與實際結果不相同,紅色X表示超過了限制條件(此處是逾時了,因為測試方法調用的方法裡面有死迴圈),綠色√表示該測試方法成功,灰色/表示該測試方法被忽略。點擊列表中對應的方法名時,下方Failure Trace會給出錯誤資訊。

 

上述例子是針對測試的方法不需要多組資料的情況。OK,今天先這麼多!改天繼續~

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.