Bootstrap

JUnit编写测试用例

JUnit导入

  • JUnit是Java语言开源的单元测试框架,目前最新的版本是JUnit5

在pom.xml文件中添加junit4依赖

<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency

导入相应的包

import org.junit.Test;

JUnit编写UT示例

在com.example包下定义一个Calculate类:

public class Calculate {
    public int add(int x, int y){
        return x + y;
    }
    
    public int substract(int x, int y){
        return x + y;
    }
}

对应的测试用例类CalculateTest如下:

import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class CalculateTest {
    @Test
    public void testAdd() {
        Count count = new Count();
        assertEquals(3,count.add(1,2));
    }
    
     @Test
    public void testSubstract() {
        Count count = new Count();
        assertEquals(3,count.add(1,2));
    }
}

JUnit编写UT规范

编写单元测试建议遵循以下规范

  • 类名:命名由 被测试类+Test 组成,例如 CalculateTest

  • 方法名:命名由 test+被测方法名组成,且方法名首字母大写,或者直接使用方法名,例如 testAddadd

  • 测试类定义为public,例如 public class CalculateTest

  • 方法定义为public,且无返回值,参数列表为空,例如 public void testAdd()

JUnit4注解

注解描述
@Test标识测试方法,该方法须为 public void
@BeforeClass① 在所有测试方法之前执行,运行一次
② 添加该注解的测试方法必须定义为 public static void
③ 用法:当需要在测试几个方法前执行同一个命令时,可以使用此注解,例如建立数据库连接
@AfterClass与@BeforeClass对立,在所有测试方法执行后运行一次,用于测试后的清理工作
@Before① 每个测试用例执行之前都运行一次
② 用于测试前的准备工作,例如初始化类等
@After① 每次测试之后都运行一次
② 用于测试后的清理工作,例如释放内存等
@Ignore忽略某个测试方法或测试类
@RunWith此注解放在测试类名之前,用于指明该类所使用的的测试运行器

JUnit断言

JUnit提供了Assert类,包含一些断言方法,用来判断测试的方法是否按照预期执行。

方法描述
assertEquals(boolean expected, boolean actual)判断两个对象是否相等
assertArrayEquals(expectedArray, resultArray)判断两个数组是否相等
assertTrue(boolean condition)检查条件是否为真
assertFalse(boolean condition)检查条件是否为假
assertNull(object)检查对象是否为空
assertNotNull(object)检查对象是否非空
assertSame(expected, actual)检查两个对象的引用是否相等
assertNotSame(expected, actual)检查两个对象的引用是否不相等

JUnit套件测试

  • 套件测试(Suite Test):JUnit4可以将多个测试类组合在一起来执行测试,称为套件测试
  • 通过 @RunWith 注解来指明套件测试的运行器,即指明测试类是以什么样的方式进行测试的
  • 通过 @SuiteClasses 注解来指定多个测试类

示例:

1)假设有两个被测试类

//CalculateA.java
public class CalculateA {
    public int add(int x, int y){
        return x + y;
    }
}

//CalculateB.java
public class CalculateB {
    public int substract(int x, int y){
        return x + y;
    }
}

2)分别对应有两个测试类

//CalculateATest.java
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class CalculateATest {
    @Test
    public void testAdd() {
        Count count = new Count();
        assertEquals(3,count.add(1,2));
    }
}

//CalculateBTest
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class CalculateBTest {
     @Test
    public void testSubstract() {
        Count count = new Count();
        assertEquals(3,count.add(1,2));
    }
}

3)编写套件测试类

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

@RunWith(Suite.class)
@Suite.SuiteClasses({CountTest.class,CalculateTest.class})
public class SuiteTest {
}

JUnit参数化测试

  • 参数化测试(Parameterized Test):使用不同的参数值来进行测试的测试方法
  • 通过 @RunWith(Parameterized.class) 注解来说明对某个测试类进行参数化测试
  • 测试类中必须包含一个 public static 静态方法,并使用 @Parameters注解,且其返回类型必须为一个对象的集合

示例:

1) 被测试类,compute方法计算fibonacci数列第n个数值

public class Fibonacci {
    public static int compute(int n) {
    	int result = 0;
        if (n <= 1) { 
        	result = n; 
        } else { 
        	result = compute(n - 1) + compute(n - 2); 
        }    
        return result;
    }
}

2) 参数化测试类(第一种方式–通过构造函数为参数赋值)

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;
import static org.junit.Assert.assertEquals;

@RunWith(Parameterized.class)
public class FibonacciTest {
    //定义参数变量,输入num,返回result
    private int num;
    private int result;

    //以构造函数的方式对参数赋值
    public FibonacciTest(int num, int result) {
        this.num = input;
        this.result = result;
    }

    //定义测试参数,与构造函数输入对应
    @Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] {
                { 1, 1 },
                { 2, 1 },
                { 3, 2 },
                { 4, 3 },
                { 5, 5 },
                { 6, 8 }
        });
    }

    @Test
    public void test() {
        assertEquals(result, Fibonacci.compute(num));
    }
}

2) 参数化测试类(第二种方式–直接指定参数顺序)

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;
import static org.junit.Assert.assertEquals;

@RunWith(Parameterized.class)
public class FibonacciTest {
    //定义参数变量,输入num,返回result
    @Parameterized.Parameter(0)
    public int num;
    @Parameterized.Parameter(1)
    public int result;

    @Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] {
                { 1, 1 },
                { 2, 1 },
                { 3, 2 },
                { 4, 3 },
                { 5, 5 },
                { 6, 8 }
        });
    }

    @Test
    public void test() {
        assertEquals(result, Fibonacci.compute(num));
    }
}

JUnit超时测试

  • JUnit通过使用 timeout参数来设置测试方法的运行时间限制,以毫秒为单位,超过指定的时间,该方法测试失败
  • @Test 注解一起使用,适用于方法的测试
@Test(timeout = 1000)
public void testTimeout(){
    ...
}
;