Java单元测试框架(一)——JUnit4

时间:2022-07-24
本文章向大家介绍Java单元测试框架(一)——JUnit4,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1.基础架构

被测代码:Calculator.java

package JUnit.com.jerry;


public class Calculator {
    private static int result; // 静态变量,用于存储运行结果
    public void add(int n) {
        result = result + n;
    }
    public void substract(int n) {
        result = result - n;  
    }
    public void multiply(int n) {
      result = result * 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;
}
}

基本的测试代码:CalculatorTest.java

package JUnit.com.jerry;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
public class CalculatorTest {
    private static Calculator calculator = new Calculator();
    @Before
    public void setUp() throws Exception {
        calculator.clear();
    }
    @Test
    public void testAdd() {
        calculator.add(2);
        calculator.add(3);
        assertEquals(5, calculator.getResult());
    }
    @Test
    public void testSubstract() {
        calculator.add(5);
        calculator.substract(3);
        assertEquals(2, calculator.getResult());
    }
    @Test
    public void testMultiply() {
        calculator.add(3);
        calculator.multiply(2);
        assertEquals(6, calculator.getResult());
    }
@Test
    public void testDivide() {
        calculator.add(9);
        calculator.divide(3);
        assertEquals(3, calculator.getResult());
    }

2. JUnit4的修饰符

修饰符

含义

@Before

每个用例前执行

@Test

下面是一个测试用例

@After

每个用例后执行

@BeforeClass

类中所有用例前执行

@AfterClass

类中所有用例后执行

@Ignore

测试类或测试方法不执行

@Categories

表示单元测试类别

3. JUnit4的断言

断言方法

断言描述

assertEquals([String message],expected,actual)

expected==actual,测试通过(用于整型数字)

assertEquals([String message],expected,actual,tolerance)

expected==actual,测试通过,tolerance为浮点数的精度

assertTrue ([String message],Boolean condition)

condition条件成立,测试通过

assertFalse([String message],Boolean condition)

condition条件不成立,测试通过

assertNull([String message],Object object)

object为空,测试通过

assertNotNull([String message],Object object)

Object不为空,测试通过

assertSame ([String message],expected,actual)

expected与actual相同,测试通过

assertNotSame ([String message],expected,actual)

expected与actual相同,测试通过

fail([String message])

直接直接失败

4. 延迟测试

@Test(timeout=1000 ) //1000毫秒
    Public void squareRoot()  {
        calculator.squareRoot(4);
        assertEquals(2 , calculator.getResult());
     }

由于squareRoot方法是一个死循环,为了保证测试用例不至于无限制等待,在@Test后使用(timeout=1000),意思是等待1000毫秒,如果1000毫秒内没有出结果,默认测试失败

5. 参数化测试

package JUnit.com.jerry;


import  static  org.junit.Assert.assertEquals;
import  org.junit.Test;
import  org.junit.runner.RunWith;
import  org.junit.runners.Parameterized;
import  org.junit.runners.Parameterized.Parameters;


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


@RunWith(Parameterized.class )
public   class SquareTest {
private static final Object[] String = null;
private  static  Calculator calculator  =   new  Calculator();
private   int  param;
private   int  result;
@Parameters
public static Collection data()  {
    return  Arrays.asList( new  Object[][] {
            { 2 ,  4 } ,
            { 0 ,  0 } ,
            {-3 ,  9 } ,
            {-15 ,  225 } ,
    } );
}
// 构造函数,对变量进行初始化 
public SquareTest( int param, int result)  {
      this.param=param;
      this.result =result;
} 
@Test
public  void  square()  {
     calculator.square(param);
     assertEquals(result, calculator.getResult());
  } 
}

参数化测试必须使用Parameterized.class运行器,参数化方法使用

@Parameters装饰器。

6. @BeforeClass和@AfterClass

public class CalculatorTest {
@BeforeClass
public void setUp() throws Exception {
    db.connect();
}
@Before
…
@test
…
@After
…
@AfterClass
public void tearDown() throws Exception {
    db.disconnect();
}

由于所有的测试用例开始都要连接数据库,结束后都要断开数据库,这个时候如果使用@Before和@After装饰符势必会测试执行的速度,JUnit4提供了@BeforeClass和@AfterClass,可以帮助解决这种情况。

7. 批量运行

import org.JUnit.runner.RunWith;
import org.JUnit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
CalculatorTest.class,
SquareTest.class 
} )
public class  AllCalculatorTests{
}

使用Suite.class运行器,可以依次运行Suite.SuiteClasses定义类中的所有测试用例。