Java单元测试Junit入门

JUnit是一个Java语言的单元测试框架。它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个。 JUnit有它自己的JUnit扩展生态圈。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。
JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework)。Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How)完成功能和完成什么样(What)的功能。Junit是一套框架,继承TestCase类,就可以用Junit进行自动测试了。
From 百度百科

1、从命令行运行Junit单元测试

新建一个待测试的类,Compute.java:

/**
 * Created by chengxia on 2019/3/28.
 */
public class Compute {
    public static int add(int a, int b){
        return a+b;
    }
}

为上面的类新建一个测试类:

import org.junit.Test;

import static org.junit.Assert.assertEquals;

/**
 * Created by chengxia on 2019/4/6.
 */
public class ComputeTest {
    @Test
    public void testCompute(){
        int result = Compute.add(3,5);
        assertEquals(8,result);
    }
}

通过命令行进入上面两个源码文件所在的目录,然后编译并运行Junit测试。如下:

$ ls
Compute.java        ComputeTest.java
$ javac -cp .:/Applications/IntelliJ\ IDEA.app/Contents/lib/junit-4.12.jar ComputeTest.java 
$ ls
Compute.class       Compute.java        ComputeTest.class   ComputeTest.java
$ java -cp .:/Applications/IntelliJ\ IDEA.app/Contents/lib/junit-4.12.jar:/Applications/IntelliJ\ IDEA.app/Contents/lib/hamcrest-core-1.3.jar org.junit.runner.JUnitCore ComputeTest
JUnit version 4.12
.
Time: 0.004

OK (1 test)

$ 

上面需要注意:
(1) 由于是引入的jar包路径中有空格,所以,在命令行中需要通过反斜杠进行转义。
(2) 编译时,引入一个jar包(/Applications/IntelliJ\ IDEA.app/Contents/lib/junit-4.12.jar)就可以,在运行时必须同时引入/Applications/IntelliJ\ IDEA.app/Contents/lib/hamcrest-core-1.3.jar。否则,会报错。如下:

$ java -cp .:/Applications/IntelliJ\ IDEA.app/Contents/lib/junit-4.12.jar org.junit.runner.JUnitCore ComputeTest
JUnit version 4.12
Exception in thread "main" java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at org.junit.runner.Computer.getSuite(Computer.java:28)
    at org.junit.runner.Request.classes(Request.java:75)
    at org.junit.runner.JUnitCommandLineParseResult.createRequest(JUnitCommandLineParseResult.java:118)
    at org.junit.runner.JUnitCore.runMain(JUnitCore.java:77)
    at org.junit.runner.JUnitCore.main(JUnitCore.java:36)
Caused by: java.lang.ClassNotFoundException: org.hamcrest.SelfDescribing
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 17 more
$ 

很明显,junit-4.12.jar中用到了hamcrest-core-1.3.jar中的依赖。

从上面运行junit测试的命令java -cp .:/Applications/IntelliJ\ IDEA.app/Contents/lib/junit-4.12.jar:/Applications/IntelliJ\ IDEA.app/Contents/lib/hamcrest-core-1.3.jar org.junit.runner.JUnitCore ComputeTest可以看出,这里直接运行的实际是JUnitCore类,测试类名只是作为一个参数传递给JUnitCore类的。这里,我们可以推测,JUnitCore类中肯定有main方法。实际上,借助IDEA的自动反编译打开这个类,其中确实有main方法定义。如下:

package org.junit.runner;

import junit.framework.Test;
import junit.runner.Version;
import org.junit.internal.JUnitSystem;
import org.junit.internal.RealSystem;
import org.junit.internal.TextListener;
import org.junit.internal.runners.JUnit38ClassRunner;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;

public class JUnitCore {

    ... ...

    public static void main(String... args) {
        Result result = (new JUnitCore()).runMain(new RealSystem(), args);
        System.exit(result.wasSuccessful()?0:1);
    }

    ... ...

}

2、在IDE中创建并运行单元测试(IntelliJ IDEA为例)

上面的过程有助于我们理解单元测试的整个运行机制,实际开发中并没有这么麻烦。一般,我们都通过使用IDE来创建单元测试。这里我们,以IDEA为例说明(版本:IntelliJ IDEA 2017.1.5,自带有junit插件)。
假设,工程中有如下Compute类:

/**
 * Created by chengxia on 2019/3/28.
 */
public class Compute {
    public static int add(int a, int b){
        return a+b;
    }
}

工程的结构如下:


Java单元测试Junit入门_第1张图片
单元测试工程结构

现在,我们要为这个类创建单元测试。首先,新建一个单元测试的文件夹。在IDEA中这需要两步:
(1) 新建一个目录。


Java单元测试Junit入门_第2张图片
New Directory for Unit Test

(2) 将上面新建的目录设置为单元测试的根目录。


Java单元测试Junit入门_第3张图片
Mark as Test Root

完成之后,效果如下:


Java单元测试Junit入门_第4张图片
新建测试目录完成

接下来,创建单元测试的类。因为有插件,这里直接选中工作区中要创建单元测试的类,然后直接按快捷键command+shift+T,IDEA会自动弹出创建单元测试的指引。如下:

Java单元测试Junit入门_第5张图片
Create new test guide

点击Create New Test...,弹出如下对话框,选择junit的版本,选择要测试的方法,点OK即可。如下:

Java单元测试Junit入门_第6张图片
Configure the Test Class

注意,上图中提示junit4依赖的库找不到。点击Fix,然后,IDEA会提示,选择junit4 jar包路径,或者使用IDEA自带的junit4 jar包。我们这里选择IDEA自带的jar包。
最后,IDEA自动生成的测试类(放在刚创建的test目录中)如下。


Java单元测试Junit入门_第7张图片
Test Class Created by IDE

我们要做的就是简单地将测试逻辑补全,如下:

import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Created by chengxia on 2019/4/6.
 */
public class ComputeTest {
    @Test
    public void add() throws Exception {
        assertEquals(5,Compute.add(3,2));
    }

}

这样,我们在上面的测试类中,右键,然后选择Run 'ComputeTest',即可运行单元测试,效果如下。

Java单元测试Junit入门_第8张图片
Running Result

参考资料

  • junit百度百科
  • Java用JUnit进行单元测试

你可能感兴趣的:(Java单元测试Junit入门)