IDEA下使用Junit4進行單元測試(待更新)

該內容爲“中國大學MOOC”,華中科技大學《軟件測試與質量》第8周單元測試部分的筆記。

 

IDEA工具可進官網下載,這裏使用的2019.3.2版本。

BMI計算程序

 

新建工程,命名爲“HealthIndex”:

在src目錄下新建package,“sample.ut”:

在建好的包下新建class,“BMI”:

BMI.java中包含的內容有:

1. 定義屬性

private double weight; // 體重
private double height; // 身高

2. getter&setter

在空白處右鍵,選擇“Gennerate”,然後選擇“Getter and Setter”:

 

會自動生成下述方法:

public double getWeight() {
    return weight;
}

public void setWeight(double weight) {
    this.weight = weight;
}

public double getHeight() {
    return height;
}

public void setHeight(double height) {
    this.height = height;
}

3. 同時設定所有屬性

public void setParams(double w, double h){
    this.weight = w;
    this.height = h;
}

4. 定義構造方法

public BMI(double w, double h){
    this.weight = w;
    this.height = h;
}

5. 定義功能方法

public String getBMIType(){
    // 1. 初始化
    String result = "";
    double bmi = 0.0;

    if(weight>0 && height>0){
        // 2. 計算BMI
        bmi = weight / (height*height);

        // 3. 判斷所屬分類
        if(bmi<20.5){
            result = "偏瘦";
        }else if(bmi<24){
            result = "正常";
        }else if(bmi<28){
            result = "偏胖";
        }else{
            result = "肥胖";
        }
    }else{
        result = "數據有誤";
    }
    
    // 4. 返回分類結果
    return result;
}

 

使用Junit4創建簡單測試方法

創建一個新的文件夾“test”,跟src同層:

右鍵test文件夾,把它標記爲Test Sources Root:

在test文件夾下也建立同名的包“sample.ut”:

回到BMI.java文件中,在空白處右鍵,選擇“Go To” --> “Test”:

創建新的Test:

選擇“JUnit4”,勾選下圖所示部分:

如果提示沒有JUnit4包,點擊右邊的“Fix”:

在彈出的框中直接點OK即可:

如果導入失敗,在導入過程中檢查該路徑:

發現路徑下沒有jar包:

可以到IDEA的下載路徑的lib文件夾下找到,並copy過來:

創建成功後,在BMITest.java中定義被測對象,並補充測試方法:

BMI testObj;

@Test
public void getBMIType() {
    // 創建被測對象
    testObj = new BMI(45.0, 1.6);
    // 調用測試方法
    String actual = testObj.getBMIType();
    // 校驗測試結果
    String except = "偏瘦";
    assertTrue(actual==except);
}

完整的BMITest.java內容爲:

package sample.ut;

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

import static org.junit.Assert.*;

public class BMITest {
    BMI testObj;

    @Before
    public void setUp() throws Exception {

    }

    @After
    public void tearDown() throws Exception {
    }

    @Test
    public void getBMIType() {
        // 創建被測對象
        testObj = new BMI(45.0, 1.6);
        // 調用測試方法
        String actual = testObj.getBMIType();
        // 校驗測試結果
        String except = "偏瘦";
        assertTrue(actual==except);
        // 銷燬測試對象
        testObj = null;
    }

}

點擊方法前的運行:

 

測試通過:

修改expect,使其失敗,再次運行:

運行失敗,可通過控制檯查看出錯原因。

 

一次性執行多個測試方法

在上述BMITest.java中,可定義多個測試方法@Test進行測試:

    @Test
    public void getBMIType1() {
        testObj = new BMI(45.0, 1.6);
        String actual = testObj.getBMIType();
        String except = "偏瘦";
        assertTrue(actual==except);
        testObj = null;
    }

    @Test
    public void getBMIType2() {
        testObj = new BMI(55.0, 1.6);
        String actual = testObj.getBMIType();
        String except = "正常";
        assertTrue(actual==except);
        testObj = null;
    }

需要注意的是,執行測試的順序和定義測試的順序不一定相同,且這樣寫測試方法會造成冗餘。

Junit4提供了以下幾種基本註解:

它們的執行順序如下:

因此,可以在BMITest.java中,在@Before中創建被測對象,在@After中銷燬被測對象,減少冗餘:

    @Before
    public void setUp() throws Exception {
        testObj = new BMI();
        System.out.println("Run @Before method");
    }

    @After
    public void tearDown() throws Exception {
        testObj = null;
        System.out.println("Run @After method");
    }

在BMI.java中添加無參的構造方法:

修改測試方法寫法:

    @Test
    public void getBMIType1() {
        testObj.setParams(45.0, 1.6);
        // 調用測試方法
        String actual = testObj.getBMIType();
        // 校驗測試結果
        String except = "偏瘦";
        assertTrue(actual==except);
    }

修改後的完整 BMITest.java:

package sample.ut;
// 使用junit4的測試
import org.junit.*;

import static org.junit.Assert.*;

public class BMITest {
    BMI testObj;

    @Before
    public void setUp() throws Exception {
        testObj = new BMI();
        System.out.println("Run @Before method");
    }

    @After
    public void tearDown() throws Exception {
        testObj = null;
        System.out.println("Run @After method");
    }

    @BeforeClass
    public static void prepareEnvironment(){
        System.out.println("Run @BeforeClass method");
    }

    @AfterClass
    public static void RestoreEnvironment(){
        System.out.println("Run @AfterClass method");
    }

    @Test
    public void getBMIType1() {
        System.out.println("Run getBMIType1 method");
        testObj.setParams(45.0, 1.6);
        // 調用測試方法
        String actual = testObj.getBMIType();
        // 校驗測試結果
        String except = "偏瘦";
        assertTrue(actual==except);
    }

    @Test
    public void getBMIType2() {
        System.out.println("Run getBMIType2 method");
        testObj.setParams(55.0, 1.6);
        // 調用測試方法
        String actual = testObj.getBMIType();
        // 校驗測試結果
        String except = "正常";
        assertTrue(actual==except);
    }
}

執行結果:

可以清楚的明白註解的執行順序。

 

測試參數化

爲了使運行多個測試用例的代碼簡潔,可以使用參數化運行器來進行測試。

org.junit.runners.Parameterized

測試步驟:

  1. 指定參數化運行器 @RunWith(Parameterized.class)
  2. 準備測試數據(構造注入or屬性注入)
  3. 添加Test方法,執行測試

構造注入

創建新的測試類BMITestParam.java,創建方法同BMITest.java。

用帶參數的構造函數獲取數據集,分爲以下幾個步驟:

1. 定義參數:定義私有變量,用以保存輸入和與預期輸出。

    private double weight;      // 體重
    private double height;      // 身高
    private String expected;    // 預期分類

2. 引入參數:定義帶參數的構造方法。

    public BMITestParam(double w, double h, String exp){
        this.weight = w;
        this.height = h;
        this.expected = exp;
    }

3. 準備測試數據:定義一個特殊方法。

    @Parameterized.Parameters
    public static Collection testDataset(){
        return Arrays.asList(
                new Object[][]{
                    {45.0, 1.6, "偏瘦"},
                    {55.0, 1.6, "正常"},
                    {68.0, 1.6, "偏胖"},
                    {80.0, 1.6, "肥胖"}
                }
        );
    }

爲了使測試結果有更好的可讀性,可對Patameters添加內部屬性:

在該例中,可改爲:

@Parameterized.Parameters(name="{index}:getBMIType[{0},{1}]=[{2}]")

完整的測試代碼:

package sample.ut;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

import static org.junit.Assert.*;

// 指定參數化運行器
@RunWith(Parameterized.class)
public class BMITestParam {
    BMI testObj;                 // 定義被測類對象

    // 1. 定義參數
    private double weight;      // 體重
    private double height;      // 身高
    private String expected;    // 預期分類

    // 2. 引入參數(定義構造方法)
    public BMITestParam(double w, double h, String exp){
        this.weight = w;
        this.height = h;
        this.expected = exp;
    }

    // 3. 準備測試數據
    @Parameterized.Parameters(name="{index}:getBMIType[{0},{1}]=[{2}]")
    public static Collection testDataset(){
        return Arrays.asList(
                new Object[][]{
                    {45.0, 1.6, "偏瘦"},
                    {55.0, 1.6, "正常"},
                    {68.0, 1.6, "偏胖"},
                    {80.0, 1.6, "肥胖"}
                }
        );
    }

    @Before
    public void setUp() throws Exception {
        testObj = new BMI(weight, height);
    }

    @After
    public void tearDown() throws Exception {
        testObj = null;
    }

    @Test
    public void getBMIType() {
        assertTrue(testObj.getBMIType()==expected);
    }
}

運行結果:

 

屬性注入

創建新的測試類BMITestParam2.java,創建方法同BMITest.java。

用屬性指定獲取數據集,分爲以下幾個步驟:

1. 定義參數:定義共有變量,用以保存輸入和預期輸出,並指定每個屬性爲參數:

    @Parameterized.Parameter(0)
    public double weight;      // 體重

    @Parameterized.Parameter(1)
    public double height;      // 身高

    @Parameterized.Parameter(2)
    public String expected;    // 預期分類

2. 準備測試數據:定義一個特殊方法(同構造注入)。

完整測試代碼:

package sample.ut;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

import static org.junit.Assert.*;

// 指定參數化運行器
@RunWith(Parameterized.class)
public class BMITestParam2 {
    BMI testObj;                 // 定義被測類對象

    // 1. 定義參數
    @Parameterized.Parameter(0)
    public double weight;      // 體重

    @Parameterized.Parameter(1)
    public double height;      // 身高

    @Parameterized.Parameter(2)
    public String expected;    // 預期分類

    // 2. 準備測試數據
    @Parameterized.Parameters(name="{index}:getBMIType[{0},{1}]=[{2}]")
    public static Collection testDataset(){
        return Arrays.asList(
                new Object[][]{
                        {45.0, 1.6, "偏瘦"},
                        {55.0, 1.6, "正常"},
                        {68.0, 1.6, "偏胖"},
                        {80.0, 1.6, "肥胖"}
                }
        );
    }

    @Before
    public void setUp() throws Exception {
        testObj = new BMI(weight, height);
    }

    @After
    public void tearDown() throws Exception {
        testObj = null;
    }

    @Test
    public void getBMIType() {
        assertTrue(testObj.getBMIType()==expected);
    }
}

運行結果:

 

測試集

分類測試

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