junit4入門例子

第一步:eclipse中新建一個項目,java build path中導入junit jar包(本文例子junit-4.9b1.jar)

第二步:新建一個package,導入如下四個文件

第三步:右鍵AllCalculatorTests(或者CalculatorTest、SquareTest),run as junit test,查看執行結果。

代碼中的註釋能夠幫你理解Junit4。

 

=================================================================

package andycpp;

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;
    }
}
===============================================================

package andycpp;
/*
 * import static,這是一個靜態包含(static),是JDK5中新增添的一個功能。也就是說,assertEquals是Assert類中的一系列的靜態方法,
 * 一般的使用方式是Assert. assertEquals(),但是使用了靜態包含後,前面的類名就可以省略了,使用起來更加的方便
 * */
import static org.junit.Assert.*;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
//測試類名稱任意

public class CalculatorTest {
    //你要測試哪個類,那麼你首先就要創建一個該類的對象
    private static Calculator calculator = new Calculator();
    /*
     * @Before和@After是每個測試方法執行前後均需要執行,
     * 因此不適合累中耗資源,或者耗時過大的操作。
     * @BeforeClass 和 @AfterClass兩個Fixture來幫規避此問題。
     * 從名字上就可以看出,用這兩個Fixture標註的函數,只在測試用例
     * 初始化時執行 @BeforeClass方法,當所有測試執行完畢之後,執行
     * @AfterClass進行收尾工作。在這裏要注意一下,每個測試類只能有
     * 一個方法被標註爲 @BeforeClass 或 @AfterClass,
     * 並且該方法必須是Public和Static的
     * */
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
    }
    /*
     * 我們非常希望每一個測試都是獨立的,相互之間沒有任何耦合度。
     * 因此,我們就很有必要在執行每一個測試之前,對Calculator對象進行一個“復原”操作,
     * 以消除其他測試造成的影響。因此,“在任何一個測試執行之前必須執行的代碼”就是一個Fixture,
     * 我們用@Before來標註它     這裏不在需要@Test標註*
     * */
    @Before
    public void setUp() throws Exception {
        calculator.clear();
    }

    @After
    public void tearDown() throws Exception {
    }
   //@Test 標準的方法,返回值必須是void,而且無參數
    @Test
    public void testAdd() {
        calculator.add(2);
        calculator.add(3);
        assertEquals(5,calculator.getResult());//第一個參數填寫期待結果,第二個參數填寫實際結果
       
    }

    @Test
    public void testSubstract() {
        calculator.add(10);
        calculator.substract(2);
        assertEquals(8,calculator.getResult());
    }
    /*
     * 如果你已經把該方法的測試用例寫完,但該方法尚未完成,那麼測試的時候一定是“失敗”。
     * 這種失敗和真正的失敗是有區別的,因此JUnit提供了一種方法來區別他們,那就是在這種
     * 測試函數的前面加上@Ignore標註,這個標註的含義就是“某些方法尚未完成,暫不參與此次測試”。
     * 這樣的話測試結果就會提示你有幾個測試被忽略,而不是失敗。一旦你完成了相應函數,只需要把@Ignore標註刪去,
     * 就可以進行正常的測試。
     * */
    @Ignore
    @Test
    public void testMultiply() {
        calculator.add(2);
        calculator.multiply(3);
        assertEquals(6,calculator.getResult());
    }

    @Test
    public void testDivide() {
         calculator.add(8);
         calculator.divide(2);
         assertEquals(4, calculator.getResult());
    }
    /*
     * 對於那些邏輯很複雜,循環嵌套比較深的程序,
     * 很有可能出現死循環,因此一定要採取一些預防措 施。
     * 限時測試是一個很好的解決方案。我們給這些測試函數設定
     * 一個執行時間,超過了這個時間,他們就會被系統強行終止,
     * 並且系統還會向你彙報該函數結束的原 因是因爲超時,這樣你就可以發現這些Bug了
     * 測試例子calculator中的squareRoot是個死循環。
     * */
     @Test(timeout = 1000)//單位爲毫秒
     public void squareRoot() {
            calculator.squareRoot(4);
            assertEquals(2, calculator.getResult());
        }
     /*使用@Test標註的expected屬性,將我們要檢驗的異常傳遞給他,
      * 這樣JUnit框架就能自動幫我們檢測是否拋出了我們指定的異常
      * */
     @Test(expected = ArithmeticException.class)
      public void divideByZero() {
         calculator.divide(0);
         }
}
==============================================================

package andycpp;

import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/*
 * 對於參數測試需要重新寫一個類, 而不能與其他測試共用同一個類,此例中我們定義了一個SquareTest類。
 * 然後,你要爲這個類指定一個 Runner,而不能使用默認的Runner了,因爲特殊的功能要用特殊的Runner嘛。
 * @RunWith(Parameterized.class)
 *
 * */
@RunWith(Parameterized.class)
public class SquareTest {
    private static Calculator calculator = new Calculator();
    private int param;
    private int result;
    /*
     * 定義測試數據的集合,也就是上述的data()方法,
     * 該方法可以任意命名,但是必須使用@Parameters標註進行修飾。
     * 這個方法的框架就不予解釋了,大家只需要注意其中的數據,是一個二維數組,
     * 數據兩兩一組,每組中的這兩個數據,一個是參數,一個是你預期的結果
     * */
    @Parameters
    public static Collection date(){
        return Arrays.asList(new Object[][]{
            {2, 4},
            {0, 0},
            {-3, 9},
      });
    }
   
  //構造函數,對變量進行初始化

   
    //定義一個待測試的類,並且定義兩個變量,一個用於存放參數,一個用於存放期待的結果。
    public SquareTest(int param, int result) {
           this.param = param;
           this.result = result;
    }
   
    @Test
    public void square() {
        calculator.square(param);
        assertEquals(result, calculator.getResult());
    }
   
}
==============================================================

package andycpp;
import org.junit.runner.RunWith;

import org.junit.runners.Suite;

 
/*
 * 大家可以看到,這個功能也需要使用一個特殊的Runner,
 * 因此我們需要向@RunWith標註傳遞一個參數Suite.class。
 * 同時,我們還需要另外一個標註@Suite.SuiteClasses,
 * 來表明這個類是一個打包測試類。我們把需要打包的類作爲參數傳遞給該標註就可以了。
 * 有了這兩個標註之後,就已經完整的表達了所有的含義,因此下面的類已經無關緊要,
 * 隨便起一個類名,內容全部爲空既可
 * */
@RunWith(Suite.class)

@Suite.SuiteClasses({

        CalculatorTest.class,

        SquareTest.class

        })
public class AllCalculatorTests {

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章