天天看点

JUnit:求求你了,别再用 main 方法测试了,好吗?(1)

01、前世今生

你好呀,我是 JUnit,一个开源的 Java 单元测试框架。在了解我之前,先来了解一下什么是单元测试。单元测试,就是针对最小的功能单元编写测试代码。在 Java 中,最小的功能单元就是方法,因此,对 Java 程序员进行单元测试实际上就是对 Java 方法的测试。

为什么要进行单元测试呢?因为单元测试可以确保你编写的代码是符合软件需求和遵循开发规范的。单元测试是所有测试中最底层的一类测试,是第一个环节,也是最重要的一个环节,是唯一一次能够达到代码覆盖率 100% 的测试,是整个软件测试过程的基础和前提。可以这么说,单元测试的性价比是最好的。

微软公司之前有这样一个统计:bug 在单元测试阶段被发现的平均耗时是 3.25 小时,如果遗漏到系统测试则需要 11.5 个小时。

JUnit:求求你了,别再用 main 方法测试了,好吗?(1)

经我这么一说,你应该已经很清楚单元测试的重要性了。那在你最初编写测试代码的时候,是不是经常这么做?就像下面这样。

public class Factorial {
    public static long fact(long n) {
        long r = 1;
        for (long i = 1; i <= n; i++) {
            r = r * i;
        }
        return r;
    }
    public static void main(String[] args) {
        if (fact(3) == 6) {
            System.out.println("通过");
        } else {
            System.out.println("失败");
        }
    }
}      

要测试 fact() 方法正确性,你在 main() 方法中编写了一段测试代码。如果你这么做过的话,我只能说你也曾经青涩天真过啊!使用 main() 方法来测试有很多坏处,比如说:

1)测试代码没有和源代码分开。

2)不够灵活,很难编写一组通用的测试代码。

3)无法自动打印出预期和实际的结果,没办法比对。

但如果学会使用我——JUnit 的话,就不会再有这种困扰了。我可以非常简单地组织测试代码,并随时运行它们,还能给出准确的测试报告,让你在最短的时间内发现自己编写的代码到底哪里出了问题。

02、上手指南

好了,既然知道了我这么优秀,那还等什么,直接上手吧!我最新的版本是 JUnit 5,Intellij IDEA 中已经集成了,所以你可以直接在 IDEA 中编写并运行我的测试用例。

第一步,直接在当前的代码编辑器窗口中按下 Command+N 键(Mac 版),在弹出的菜单中选择「Test…」。

JUnit:求求你了,别再用 main 方法测试了,好吗?(1)

勾选上要编写测试用例的方法 fact(),然后点击「OK」。

此时,IDEA 会自动在当前类所在的包下生成一个类名带 Test(惯例)的测试类。如下图所示。

JUnit:求求你了,别再用 main 方法测试了,好吗?(1)

如果你是第一次使用我的话,IDEA 会提示你导入我的依赖包。建议你选择最新的 JUnit 5.4。

JUnit:求求你了,别再用 main 方法测试了,好吗?(1)

导入完毕后,你可以打开 pom.xml 文件确认一下,里面多了对我的依赖。

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>RELEASE</version>
    <scope>compile</scope>
</dependency>      

第二步,在测试方法中添加一组断言,如下所示。

@Test
void fact() {
    assertEquals(1, Factorial.fact(1));
    assertEquals(2, Factorial.fact(2));
    assertEquals(6, Factorial.fact(3));
    assertEquals(100, Factorial.fact(5));
}      

@Test 注解是我要求的,我会把带有 @Test 的方法识别为测试方法。在测试方法内部,你可以使用 assertEquals() 对期望的值和实际的值进行比对。

第三步,你可以在邮件菜单中选择「Run FactorialTest」来运行测试用例,结果如下所示。

JUnit:求求你了,别再用 main 方法测试了,好吗?(1)

测试失败了,因为第 20 行的预期结果和实际不符,预期是 100,实际是 120。此时,你要么修正实现代码,要么修正测试代码,直到测试通过为止。

JUnit:求求你了,别再用 main 方法测试了,好吗?(1)

不难吧?单元测试可以确保单个方法按照正确的预期运行,如果你修改了某个方法的代码,只需确保其对应的单元测试通过,即可认为改动是没有问题的。