1. 程式人生 > >Junit4單元測試的基本用法

Junit4單元測試的基本用法

環境搭建

這裡使用的開發工具是MyEclipse,首先新建一個Java工程,將Junit4的jar包引入,eclipse和MyEclipse都集成了Junit的jar包,詳細操作如下圖。

1、新增一個Junit的jar包,版本選擇Junit4

Junit使用

1、Junit最簡單的用法

新建一個類被測試類,裡面包含一些測試方法,新建一個測試類

package junit.util;
/**
 * 被測試類,通過Junit對此類的方法進行單元測試
 */
public class Claculate {
    public int add(int a, int b) {
    return a + b;
    }

    public int subtract(int a, int b) {
    return a - b;
    }

    public int multiply(int a, int b) {
    return a * b;
    }

    public int divide(int a, int b) {
    return a / b;
    }

}

新建一個Junit的測試類用來測試上面的測試方法,新增Junit的測試類方法如下:

package junit.util;

import static org.junit.Assert.*;
import junit.util.Claculate;

import org.junit.Test;

/**
 * junit的測試方法必須使用@Test註解
 * 測試方法必須以public void修飾,並且不包含引數
 */
public class ClaculateTest {

    @Test
    public void testAdd() {
    /**
     * assertEquals這個方法是一個斷言方法
     * 第一個引數表示預期的結果
     * 第二個引數表示程式的執行結果
     * 當預期結果與執行結果是一致的時候,則表示單元測試成功
     */
    assertEquals(4, new Claculate().add(1, 3));
    }

   
    @Test
    public void testSubtract() {
    assertEquals(4, new Claculate().subtract(9, 5));
    }
    
    @Test
    public void testMultiply() {
    assertEquals(6, new Claculate().multiply(2, 3));
    }
    
    @Test(expected=ArithmeticException.class)
    public void testDivide() {
    assertEquals(3, new Claculate().divide(9, 0));
    }
}

上面的這個測試類,分別對被測試類Claculate的四個方法進行了測試,測試是選擇使用Junit方式進行執行,如果想要執行單個測試方法,可以選擇單個方法進行執行,可以通過左側程式碼欄展開類選擇下面的方法或者直接在程式碼中選中方法名進行執行。具體操作如下圖:

 對於一個類包含的多個測試方法,可以選中這個類,滑鼠右鍵選擇new一個JUnitTest Case,可以選擇類中的所有要測試的方法,eclipse會自動幫你生成測試方法體

只需要在每個要測試的方法中新增測試程式碼即可,如下圖;

JUnit的流程

在實際專案中,進行JUnit測試時,通常會涉及到一些初始化的東西,可能有些配置項需要在測試前進行載入的,JUnit提供了一些初始化的方法用於初始化

package junit.util;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class JunitFlowTest {
    /**
     * @BeforeClass:這個註解表示這個方法會在所有測試方法執行之前執行
     * 因為是static修飾的靜態方法,所有隻會執行一次。通常用來進行一些
     * 資源的載入,如通過JUnit測試Spring相關的東西時,可以在這個方法
     * 中載入Spring的配置檔案
     */
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
    System.out.println("this is before class");
    }
    
    /**
     * @AfterClass:這個註解表示這個方法會在所有方法執行完畢之後執行,通常用來釋放資源
     */
    @AfterClass
    public static void tearDownAfterClass() throws Exception {
    System.out.println("this is after class");
    }

    /**
     * @Before:這個註解表示這個方法會在每個測試方法執行之前執行一次
     * 有多少個測試方法就會執行多少次
     */
    @Before
    public void setUp() throws Exception {
    System.out.println("this is before");
    }

    /**
     * @After:這個註解表示這個方法會在每個測試方法執行之後執行一次
     * 有多少個測試方法就會執行多少次
     */
    @After
    public void tearDown() throws Exception {
    System.out.println("this is Down");
    }

    @Test
    public void test1() {
    System.out.println("this is test1");
    }
    
    @Test
    public void test2() {
    System.out.println("this is test2");
    }

}

/* outPut:
this is before class
this is before
this is test1
this is Down
this is before
this is test2
this is Down
this is after class
*/

測試套件

如果要同時測試多個類,可以新增一個測試套件,將多個所有測試類包含進去,每次執行測試套件類的時候,就會把包含的測試類全都執行一遍,測試程式碼如下:

package junit.util;

import org.junit.Test;

public class TaskTest1 {

    @Test
    public void test() {
    System.out.println("this is TaskTest1");
    }
}



package junit.util;

import org.junit.Test;

public class TaskTest2 {

    @Test
    public void test() {
    System.out.println("this is TaskTest2");
    }
}



package junit.util;

import org.junit.Test;

public class TaskTest3 {

    @Test
    public void test() {
    System.out.println("this is TaskTest3");
    }
}



package junit.util;

import org.junit.runner.RunWith;
import org.junit.runners.Suite;

/**
 * 測試套件類
 * 測試套件是用來組織多個測試類一起執行的,使用 @RunWith註解
 * 更改測試執行器為Suite.class,將要測試的類作為陣列傳入
 * 到Suite.SuiteClasses({})中,測試套件類不能包含其他測試方法
 * 
 * 樣例如下:
 */
@RunWith(Suite.class)
@Suite.SuiteClasses({ TaskTest1.class, TaskTest2.class, TaskTest3.class })
public class SuiteTest {}

//outPut:
//this is TaskTest1
//this is TaskTest2
//this is TaskTest3

測試套件也可以包含其他的測試套件,具體用法和包含多個測試類是一樣的,程式碼如下:

package junit.util;

import org.junit.Test;

public class TaskTest4 {

    @Test
    public void test() {
    System.out.println("this is TaskTest4");
    }
}



package junit.util;

import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Suite.class)
@Suite.SuiteClasses({SuiteTest.class,TaskTest4.class})
public class SuiteTest1 {}

//outPut
//this is TaskTest1
//this is TaskTest2
//this is TaskTest3
//this is TaskTest4

引數化測試

對於一個方法需要進行多種場景進行測試時,可以通過引數化測試減少測試的工作量。用法如下:

package junit.util;

import static org.junit.Assert.assertEquals;

import java.util.Arrays;
import java.util.Collection;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class ParameterTest {

    /**
     * 1、更改測試執行器為RunWith(Parameterized.class)
     * 2、宣告變數用來存放預期值與結果值
     * 3、宣告一個返回值為Collection的公共靜態方法,並使用@Parameters進行修飾
     * 4、位測試類宣告一個帶有引數的公共構造方法,並在其中為宣告變數賦值
     */
    
    int except;  //用來儲存預期結果
    int input1;  //用來儲存第一個輸入引數
    int input2;  //用來儲存第二個輸入引數
    
    @Parameters
    public static Collection<Object[]> initTestData(){
    return Arrays.asList(
        new Object[][]{
        {3,1,2},
        {10,5,5},
        {6,4,2},
        {7,3,4}}
        );
    }
    
    public ParameterTest(int except,int input1,int input2){
    this.except = except;
    this.input1 = input1;
    this.input2 = input2;
    }
    
    
    
    
    
    @Test
    public void testAdd() {
    assertEquals(except, new Claculate().add(input1, input2));
    }

}

總結及補充:

JUnit的一些注意事項:

  • 測試方法必須使用@Test修飾
  • 測試方法必須使用public void進行修飾,不能帶引數
  • 一般使用單元測試會新建一個test目錄存放測試程式碼,在生產部署的時候只需要將test目錄下程式碼刪除即可
  • 測試程式碼的包應該和被測試程式碼包結構保持一致
  • 測試單元中的每個方法必須可以獨立測試,方法間不能有任何依賴
  • 測試類一般使用Test作為類名的字尾
  • 測試方法使一般用test作為方法名的字首

測試失敗說明:

  • Failure:一般是由於測試結果和預期結果不一致引發的,表示測試的這個點發現了問題
  • error:是由程式碼異常引起的,它可以產生於測試程式碼本身的錯誤,也可以是被測試程式碼中隱藏的bug

一些常用註解:

  • @Test:將一個普通方法修飾成一個測試方法
    • @Test(excepted=xx.class): xx.class表示異常類,表示測試的方法丟擲此異常時,認為是正常的測試通過的
    • @Test(timeout=毫秒數) :測試方法執行時間是否符合預期
  • @BeforeClass: 會在所有的方法執行前被執行,static方法
  • @AfterClass:會在所有的方法執行之後進行執行,static方法
  • @Before:會在每一個測試方法被執行前執行一次
  • @After:會在每一個測試方法執行後被執行一次
  • @Ignore:所修飾的測試方法會被測試執行器忽略
  • @RunWith:可以更改測試執行器org.junit.runner.Runner
  • Parameters:引數化註解