Java 单元测试 - Junit

这里记录一下 Java 和 Python 的测试框架:Junit 和 unittest. 两个框架的设计完全类似。

创建一个测试

假设我们有一个需要测试的 Java 类:

package me.ryan.test;

public class Calculator {
  public int evaluate(String expression) {
    int sum = 0;
    for (String summand: expression.split("\\+"))
      sum += Integer.valueOf(summand);
    return sum;
  }
}

一个最基础的 JUnit 测试类如下(需要引入 Junit 依赖):

package me.ryan.test;     // 测试类要和被测试类在同一个 package 内

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

public class CalculatorTest {  // 测试类名的约定格式 xxxTest

    // 测试方法必须被 @Test 所注解
    // 而且必须是 public void testXxx(),也就是 无参无返回值 的 public 方法
  @Test
  public void testEvaluates() {
    Calculator calculator = new Calculator();
    int sum = calculator.evaluate("1+2+3");
    assertEquals(6, sum);    // assertEqual 是最常用的一个断言方法
  }
}

运行测试

org.junit.runner.JUnitCore 是 Junit 测试的运行界面。它提供了两种方式来运行测试:

  1. 命令行:java -cp .;junit-4.XX.jar;hamcrest-core-1.3.jar org.junit.runner.JUnitCore CalculatorTest(Java需要先编译再运行哦)
  2. 静态方法:public static Result runClasses(Class<?>... classes),参数为需要运行的测试类,结果以 Result 对象形式返回。

如果使用 IDE 的话,运行测试就很方便,基本上只需要点两个按钮。

基本运行流程

除了 @Test 注解,Junit 还提供了好几个与运行顺序有关的方法注解:@BeforeClass @AfterClass @Before @After

package me.ryan.test; 

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

public class CalculateTest {

    // 类创建之前运行,因此必须是 static 方法,一般用于加载资源之类的(只运行一次)
    @BeforeClass
    public static void setUpBeforeClass() {
        System.out.println("this is BeforeClass...");
    }

    @Before      // 每个测试方法运行前都会执行一次
    public void setUp() throws Exception {
        System.out.println("\nthis is Before...");
    }

    @After        // 每个测试方法结束后都会执行一次
    public void tearDown() throws Exception {
        System.out.println("this is After...");
    }

    // 类销毁之后运行,是 static 方法,一般用于销毁资源(只运行一次)
    @AfterClass
    public static void setTearDownAfterClass() {
        System.out.println("this is AfterClass...");
    }

    @Ignore  // 忽略此测试方法
    @Test        // 测试方法
    public void testOne(){
        System.out.println("this is Test1...");
    }

    @Test    // 测试方法之间必须是相互独立的,一个方法测试一项内容
    public void testTwo(){
        System.out.println("this is Test2...");
    }
}

// 结果
/*
this is BeforeClass...
this is Before...
this is Test1...
this is After...
this is Before...
this is Test2...
this is After...
this is AfterClass...
*/

此外,注解也可添加可选的参数,可以提供额外的小功能。

套件测试

也就是一次运行多个测试类

  • @RunWith(Class):用于指定单元测试的执行类,默认是使用的 Suite.Class. 比如测试 Spring 时,会发现测试类会带有注解@RunWith(SpringJUnit4ClassRunner.class)
  • @Suite.SuiteClasses()

参数化测试

待续

Spring 测试

Spring 默认使用 Junit 做单元测试。

  1. @RunWith(SpringJUnit4ClassRunner.class):使用 Spring 提供的 SpringJUnit4ClassRunner 作为测试执行类,这个类是 Spring 针对 Junit 运行环境的自定义扩展。此注解启用了 Spring 对 Junit4 测试的支持。
  2. @ContextConfiguration:导入 Spring Context 配置。(xml文件或者Java配置类)
  3. @Transactional:表明此类需要启用事务功能,这样所有的测试运行后,都会自动 Rollback,不会污染数据库。(也可再添加 @Rollback(false) 来关闭 rollback)
  4. 测试类同样支持 Bean 的注入。

Spring Web MVC 的 mock 测试

待续

计算测试覆盖度(test coverage)

待续

参考

posted @ 2018-06-24 15:52  於清樂  阅读(486)  评论(0编辑  收藏  举报