JUnit单元测试

JUnit单元测试,既然叫单元,那就是针对最小功能单元来说,也就是针对单个方法的测试,像Python里的unittest,比如OpenStack对应的Tempest都是由一个一个单元测试构成的,Java的JUnit也基本类似

常规也是通过Assert断言来书写测试代码来测试结果的正确性

在IDEA里需要安装JUnit插件,搜junit即可;当然如果配置了Maven,直接就有

简单写一个例子进行下单元测试,比如写了一个求和的方法,用了递归

package match.pattern;

/**
 * @author lihui
 * @date 2018/3/30 16:06
 */
public class Match {
    public long sum(int x) {
        if (x == 0) {
            return 0;
        } else {
            return x + sum(x - 1);
        }
    }
}

正常情况下,写完了实现代码之后,就要写一些对应的测试代码

在需要测试的当前类下鼠标右键Go To,然后选择Test,Create New Test…

到了这个窗口:

Testing library:根据你当前配置的JUnit版本一致,我这里用的是Maven里4.12版本,因此这里library选择JUnit4

Class name:基本所有单元测试都是需要携带Test关键字,区别就是大小写以及位置不同,这里需要单元测试的方法所在的类是Match,因此添加单元测试的类就是MatchTest

Superclass:这里选择你使用的junit里frameword里TestCase作为超类

Destination package:包名,和需要测试的方法所在的包一致,不需要修改,默认就行了

Generat:setUp是测试前一些初始化工作;tearDown是测试后的清理,垃圾回收工作

最下面Member里就是需要单元测试的方法,这里只有一个sum

最终配置如下:

这样对应在Maven对应的test目录下,生成了一个match.pattern包以及MatchTest类,内容如下

package match.pattern;

import junit.framework.TestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.*;

/**
 * @author lihui
 * @date 2018/3/30 17:05
 */
public class MatchTest extends TestCase {
    @Before
    public void setUp() throws Exception {
    }
    @After
    public void tearDown() throws Exception {
    }
    @Test
    public void sum() {
    }
}

装饰器@Test下的方法就是我们需要添加测试代码的方法,setUp和tearDown这里就打印一些信息

package match.pattern;

import junit.framework.TestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.*;

/**
 * @author lihui
 * @date 2018/3/30 17:05
 */
public class MatchTest extends TestCase {
    @Before
    public void setUp() throws Exception {
        System.out.println("setUp");
    }
    @After
    public void tearDown() throws Exception {
        System.out.println("tearDown");
    }
    @Test
    public void sum() {
        assertEquals(5050, new Match().sum(100));
    }
}

测试0一直加到100的和正确性,运行结果报了一个错误

测试未生效,原因是编写的测试方法sum不对,需要添加test

@Test
public void testSum() {
    assertEquals(5050, new Match().sum(100));
}

修改成testSum,执行就没问题了

再来考虑,对于测试需要验证哪些地方,比如sum方法返回值是long,那么返回值越界问题?参数x的边界值?越界?等等,都是需要测试的

比如这里以100,0,-100为例测试一下

@Test
public void testSum() {
    assertEquals(5050, new Match().sum(100));
    assertEquals(0, new Match().sum(-100));
    assertEquals(0, new Match().sum(0));
}

测试的结果,第12行出错

显然当x为-100的时候,这个递归就持续减1,没法结束了,实现时可能只考虑了从0开始算,因此这里将sum方法修改一下,当x <= 0,都返回0即可

package match.pattern;

/**
 * @author lihui
 * @date 2018/3/30 16:06
 */
public class Match {
    public long sum(int x) {
        if (x <= 0) {
            return 0;
        } else {
            return x + sum(x - 1);
        }
    }
}

这里有一个地方要注意一下,如果添加一个@Test方法

@Test
public void testSum() {
assertEquals(5050, new Match().sum(100));
assertEquals(0, new Match().sum(-100));
}
@Test
public void testZero() {
assertEquals(0, new Match().sum(0));
}

那么setUp和tearDown就执行了两次;也就是说,每一个@Test方法执行之前,都会新创建一个MatchTest实例,,在@Test的前后分别执行@Before和@After各一次

 

上面这段简单举例的代码连很简单的单元测试都没通过,属于基本的坑,这里只是举一个例子,真正系统测试当中,不光要进行正常功能验证,还要根据开发实现的代码进行单元测试,当然最终是要在看懂开发代码的基础上,考虑一些逻辑关系以及可能存在的坑的情况下,写测试代码,才算完美

发表回复