菜鳥學Java(二十一)——如何更好的進行單元測試——JUnit

測試在軟件生命週期中的重要性,不用我多說想必你們也都很是清楚。軟件測試有不少分類,從測試的方法上可分爲:黑盒測試、白盒測試、靜態測試、動態測試等;從軟件開發的過程分爲:單元測試、集成測試、確認測試、驗收、迴歸等。java


在衆多的分類中,與開發人員關係最緊密的莫過於單元測試了。像其餘種類的測試基本上都是由專門的測試人員來完成,只有單元測試是徹底由開發人員來完成的。那麼今天咱們就來講說什麼是單元測試,爲何要進行單元測試,以及如更好的何進行單元測試。 小程序


什麼是單元測試? less

單元測試(unit testing),是指對軟件中的最小可測試單元進行檢查和驗證。好比咱們能夠測試一個類,或者一個類中的一個方法。
ide


爲何要進行單元測試? 函數

爲何要進行單元測試?說白了就是單元測試有什麼好處,其實測試的好處無非就是減小bug、提升代碼質量、使代碼易於維護等。單元測試有什麼好處請看一下百度百科中概括的四條: 工具


一、它是一種驗證行爲。
程序中的每一項功能都是測試來驗證它的正確性。它爲之後的開發提供支援。就算是開發後期,咱們也能夠輕鬆的增長功能或更改程序結構,而不用擔憂這個過程當中會破壞重要的東西。並且它爲代碼的重構提供了保障。這樣,咱們就能夠更自由的對程序進行改進。
單元測試


二、它是一種設計行爲。
編寫單元測試將使咱們從調用者觀察、思考。特別是先寫測試(test-first),迫使咱們把程序設計成易於調用和可測試的,即迫使咱們解除軟件中的耦合。
測試


三、它是一種編寫文檔的行爲。
單元測試是一種無價的文檔,它是展現函數或類如何使用的最佳文檔。這份文檔是可編譯、可運行的,而且它保持最新,永遠與代碼同步。
spa


四、它具備迴歸性。
自動化的單元測試避免了代碼出現迴歸,編寫完成以後,能夠隨時隨地的快速運行測試。
設計


如何更好的進行單元測試?


在討論如何更好的進行單元測試以前,先來看看咱們之前是怎麼測試代碼的。

之前是這樣測試程序的:

 

    public int add(int x,int y) {
        return x + y;
    }
        
    public static void main(String args[]) {
        int z = new Junit().add(2, 3);
        System.out.println(z);
    }

 

 

如上面所示,在測試咱們寫好的一個方法時,一般是用一個main方法調用一下咱們要測試的方法,而後將結果打印一下。如今看來這種方式已經很是out了,因此出現了不少單元測試的工具,如:JUnit、TestNG等。藉助它們可讓咱們的單元測試變得很是方便、高效。今天就說說如何利用JUnit進行單元測試。


咱們新建一個Java Project以便進行演示,至於Java Project怎麼建立我就不在此贅述了,若是連怎麼建Java Project,那你還不適合看這篇文章。建好之後在該項目的「src」目錄上右擊,選擇new——》JUnit Test Case,而後按下圖填寫必要信息:



填寫好包名和類名(選擇New JUnit 4 Test),點擊最下面的那個「Browse」按鈕來選擇須要測試的類:



手動輸入咱們要測試的類,選擇該類,點擊「OK」,回到第一張圖的界面,而後點擊「Next」,來到下圖:



勾選要測試的方法,點擊「Finish」,這樣咱們的JUnit測試實例就建好了。而後就能夠寫具體的測試了:

 

 
package com.tgb.junit.test;

//靜態引入
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;

import org.junit.Test;

import com.tgb.junit.Junit;

public class JUnitTest {

    @Test
    public void testAdd() {
        int z = new  Junit().add(2, 3);
        assertThat(z , is(5));
    }

    @Test
    public void testDivide() {
        int z = new Junit().divide(4, 2);        
        assertThat(z, is(2));
    }
}
 

 

 


寫好之後,右擊該類選擇「Run As」——》「JUnit Test」,出現下圖表明測試經過:

 



到這裏,可能有人會有疑問,JUnit跟用main方法測試有什麼區別呢?

首先,JUnit的結果更加直觀,直接根據狀態條的顏色便可判斷測試是否經過,而用main方法你須要去檢查他的輸出結果,而後跟本身的指望結果進行對比,才能知道是否測試經過。有一句話可以很直觀的說明這一點——keeps the bar green to keeps the code clean。意思就是說,只要狀態條是綠色的,那麼你的代碼就是正確的。

第二點,JUnit讓咱們同時運行多個測試變得很是方便,下面就演示一下如何進行多實例測試:

首先咱們要再建一個待測試類,而後再建一個對應的JUnit測試實例,步驟略。而後在咱們測試實例的包上右擊選擇「Run As」——》「Run Configurations」,以下圖;



選擇第二項「Run all tests in the selected project, package or source folder」,而後點擊「Run」效果以下:



能夠看到,咱們本次測試了兩個類,共三個方法,這種方便的效果在測試實例越多的狀況下,體現的越明顯。至於main方法運行多個測試,想一想就以爲很是麻煩,這裏就不演示了。


JUnit除了能夠測試這些簡單的小程序,還能夠測試Struts、JDBC等等,這裏只是用這個小程序作過簡單的介紹。本實例使用的是hamcrest斷言,而沒有使用老的斷言,由於hamcrest斷言更加接近天然語言的表達方式,更易於理解。


本實例須要引入如下三個jar包:

hamcrest-core-1.3.jar
hamcrest-library-1.3.jar
junit-4.10.jar


最後附上經常使用hamcrest斷言的使用說明:

數值類型
//n大於1而且小於15,則測試經過
assertThat( n, allOf( greaterThan(1), lessThan(15) ) );
//n大於16或小於8,則測試經過
assertThat( n, anyOf( greaterThan(16), lessThan(8) ) );
//n爲任何值,都測試經過
assertThat( n, anything() );
//d與3.0的差在±0.3之間,則測試經過
assertThat( d, closeTo( 3.0, 0.3 ) );
//d大於等於5.0,則測試經過
assertThat( d, greaterThanOrEqualTo (5.0) );
//d小於等於16.0,則測試經過
assertThat( d, lessThanOrEqualTo (16.0) );

字符類型
//str的值爲「tgb」,則測試經過
assertThat( str, is( "tgb" ) );
//str的值不是「tgb」,則測試經過
assertThat( str, not( "tgb" ) );
//str的值包含「tgb」,則測試經過
assertThat( str, containsString( "tgb" ) );
//str以「tgb」結尾,則測試經過
assertThat( str, endsWith("tgb" ) ); 
//str以「tgb」開頭,則測試經過
assertThat( str, startsWith( "tgb" ) ); 
//str忽略大小寫後,值爲「tgb」,則測試經過
assertThat( str, equalToIgnoringCase( "tgb" ) ); 
//str忽略空格後,值爲「tgb」,則測試經過
assertThat( str, equalToIgnoringWhiteSpace( "tgb" ) );
//n與nExpected相等,則測試經過(對象之間)
assertThat( n, equalTo( nExpected ) ); 

collection類型
//map中包含key和value爲「tgb」的鍵值對,則測試經過
assertThat( map, hasEntry( "tgb", "tgb" ) );
//list中包含「tgb」元素,則測試經過
assertThat( iterable, hasItem ( "tgb" ) );
//map中包含key爲「tgb」的元素,則測試經過
assertThat( map, hasKey ( "tgb" ) );
//map中包含value爲「tgb」的元素,則測試經過
assertThat( map, hasValue ( "tgb" ) );
相關文章
相關標籤/搜索