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

运行结果:

 

测试集

分类测试

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