Java单元测试Junit

Java单元测试Junit

什么是单元测试呢?单元测试就是针对最小的功能单元编写测试代码。Java程序最小的功能单元是方法,因此,对Java程序进行单元测试就是针对单个Java方法的测试

单元测试有什么好处呢?在学习单元测试前,我们可以先了解一下测试驱动开发。

所谓测试驱动开发,是指先编写接口,紧接着编写测试。编写完测试后,我们才开始真正编写实现代码。在编写实现代码的过程中,一边写,一边测,什么时候测试全部通过了,那就表示编写的实现完成了:

    编写接口
     │
     ▼
    编写测试
     │
     ▼
┌─> 编写实现
│    │
│ N  ▼
└── 运行测试
     │ Y
     ▼
    任务完成

这就是TDD

当然,这是一种理想情况。大部分情况是我们已经编写了实现代码,需要对已有的代码进行测试。

我们先通过一个示例来看如何编写测试。假定我们编写了一个计算阶乘的类,它只有一个静态方法来计算阶乘:

$n!=1×2×3×...×n$

首先在IDE中创建项目,这里使用Maven

pom.xml中会自动添加junit依赖

在项目中添加一个新类Factorial.java

public class Factorial {
    public static long fact(long n) {
        if(n == 0) {
            return 1;
        }

        long r = 1;
        for(long i = 1; i <=n; i++) {
            r = r * i;
        }
        return r;
    }
}

test目录中创建FactorialTest.javatest目录就是用来做测试的,IDE会帮我们自动创建好:

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

public class FactorialTest {
    @Test
    public void testFact() {
        assertEquals(1,Factorial.fact(1));
        assertEquals(2,Factorial.fact(2));
        assertEquals(6,Factorial.fact(3));
        assertEquals(362880,Factorial.fact(10));
        assertEquals(2432902008176640000L, Factorial.fact(20));
    }
}

核心测试方法testFact()加上了@Test注解,这是JUnit要求的,它会把带有@Test的方法识别为测试方法。在测试方法内部,我们用assertEquals(1, Factorial.fact(1))表示,期望Factorial.fact(1)返回1assertEquals(expected, actual)是最常用的测试方法,它在Assertion类中定义。Assertion还定义了其他断言方法,例如:

  • assertTrue(): 期待结果为true
  • assertFalse(): 期待结果为false
  • assertNotNull(): 期待结果为非null
  • assertArrayEquals(): 期待结果为数组并与期望数组每个元素的值均相等
  • ...

运行单元测试非常简单。选中testFact()方法鼠标右键点击后在弹出的菜单栏选中运行testFact即可。方法有很多种,可以自己去尝试。

在Failure Trace中,JUnit会告诉我们详细的错误结果:

那就是这行代码没通过测试assertEquals(362880,Factorial.fact(10));,此时,我们要么修正实现代码,要么修正测试代码,直到测试通过为止。

单元测试可以确保单个方法按照正确预期运行,如果修改了某个方法的代码,只需确保其对应的单元测试通过,即可认为改动正确。此外,测试代码本身就可以作为示例代码,用来演示如何调用该方法。

使用JUnit进行单元测试,我们可以使用断言(Assertion)来测试期望结果,可以方便地组织和运行测试,并方便地查看测试结果。

在编写单元测试的时候,我们要遵循一定的规范:

  1. 单元测试代码本身必须非常简单,能一下看明白,决不能再为测试代码编写测试;
  2. 每个单元测试应当互相独立,不依赖运行的顺序;
  3. 是测试时不但要覆盖常用测试用例,还要特别注意测试边界条件,例如输入为0null,空字符串""等情况。

本文来源:编写JUnit测试 - 廖雪峰的官方网站 (liaoxuefeng.com) 有删改