JUnit4 单元测试入门

Hello World

此文我们通过导入jar包的形式集成Junit4, 下载路径:链接:https://pan.baidu.com/s/1Khi-fMb_k3kfAOluufWcRQ 密码:lz0i。通过eclipse新建一个Java项目后,引入jar包。需要说明的是仅引入junit-4.12是不够的,还需要引入hamcrest-core-1.3,否则会抛出java.lang.NoClassDefFoundError异常。
PS:eclipse中已经集成了JUnit,可以通过Add Library的形式直接引入Junit,方便快捷。

引入jar包后,首先,我们新建一个Hello.class,里面包含一个add(int a, int b)方法用于计算a和b的和。
然后新建一个JUnit test case,和新建普通类一样,右击项目选择新建,进而选择新建一个JUnit test case,如下图所示:

编辑新建的JUnit test case:

public class TestHello {
    @Test
    public void testAdd() {
        assertEquals(2, new HelloWorld().add(1,1));
    }

}

直接运行TestHello, 右键TestHello, 选择 Run As –> Junit Test。运行结果如下图所示:

绿色线条代表测试通过,也即是程序运行结果与预期相符:1 + 1 = 2。

常用注解

常用的方法注解

注解名称 描述 备注
@Test 声明该方法为测试方法
@BeforeClass 在测试方法执行前会首先运行该注解所标注的方法,并且只会运行一次,一般用于测试环境的初始化 public static void
@AfterClass 在测试方法执行完毕后会运行该注解所标注的方法,并且只会运行一次,一般用于测试环境的资源释放与清理 public static void
@Before 在每个测试方法执行之前都会首先运行该注解所标注的方法 public void
@After 在每个测试方法执行之后都会运行该注解所标注的方法 public void
@Ignore 被Ignore修饰的方法会被忽略执行
@Test(timeout=毫秒) 为测试方法指定超时时间 单位:毫秒
@Test(expected=异常类) 用于指定期望抛出的异常类型,如果测试方法抛出一个预期的异常则测试通过,否则测试不通过

例:

public class TestHello {

    @BeforeClass
    public static void beforeClass(){
        System.out.println("@Before Class");
    }
    @AfterClass
    public static void afterClass(){
        System.out.println("@After Class");
    }
    @Before
    public void before(){
        System.out.println("@Before");
    }
    @Test
    public void testMethod1() {
        System.out.println("@Test");
    }
    @After
    public void after(){
        System.out.println("@After");
    }
    @Test(timeout=1000)
    public void testMethod2(){
        while(true){
        }
    }
    @Test(expected=NullPointerException.class)
    public void testMethod3(){
        assertEquals(1, 2);
    }
    @Ignore
    public void ignore(){
        System.out.println("@Ignore");
    }
}

运行结果:

@Before Class
@Before
@Test
@After
@Before
@After
@Before
@After
@After Class

常用的类注解

注解名称 描述 备注
@RunWith(xxxx.class) 用于指定测试类运行器 一般使用默认运行器就可以了
@SuiteClasses(测试类数组) 用于组合多个测试类

测试用例见下段【JUnit测试套件】

JUnit测试套件

测试套件用于组合多个测试类同时运行。

当测试类很多时,一次只能运行一个测试类无疑是效率低下的。使用测试套件可以一次运行多个测试类,显著提高测试效率。测试套件类形式如下:

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({Test1.class, Test2.class, Test3.class})
public class MainTest {

}

上述测试套件可以一次运行Test1.class, Test2.class, Test3.class三个测试类。测试套件一般为空,其内部代码不会执行。

断言方法

JUnit断言方法主要集成在Assert类中。当断言成功时程序不会执行任何动作,当断言失败时相关信息会被记录下来。
Assert类主要方法有:

方法 描述 备注
assertArrayEquals(xxxx[] expecteds, xxxx[] actuals) 断言两个数组内容相同 数组元素可以是基本数据类型或者Object对象
assertEquals(long expected, long actual) 断言两个long类型数相等
assertEquals(java.lang.String message, double expected, double actual, double delta) 断言两个double类型或float类型数相等 delta指示比较精度,message用于输出提示信息
assertFalse(boolean condition) 断言结果为false 可以额外输出提示信息
assertTrue(boolean condition) 断言结果为true 可以额外输出提示信息
assertNotNull(java.lang.Object object) 断言对象非null 可以额外输出提示信息
assertNull(java.lang.Object object) 断言对象为null 可以额外输出提示信息
assertNotSame(java.lang.Object unexpected, java.lang.Object actual) 断言不是同一个对象引用 可以额外输出提示信息
assertSame(java.lang.Object expected, java.lang.Object actual) 断言同一个对象引用 可以输出额外提示信息

JUnit参数化设置

当某个方法需要针对多组参数进行测试时该怎么办呢?当然我们可以为每一组参数写一个测试方法,但这无疑是枯燥重复的。我们可以使用JUnit参数化设置来对多组数据进行测试。

使用JUnit参数化设置步凑如下:
1 更改默认测试运行器为 Parameterized.class
2 声明变量来存储预期值和结果值
3 声明一个返回值为Collection的public static 方法,并使用@Parameters进行修饰。
4 为测试类声明一个带有参数的构造方法,并在其中为声明的变量进行赋值。

例:

@RunWith(Parameterized.class)
public class ParameterTest {

    int expected = 0;
    int input1 = 0;
    int input2 = 0;

    @Parameters
    public static Collection<Object[]> initParameters(){

        ArrayList<Object[]> parList = new ArrayList<Object[]>();
        parList.add( new Integer[]{3, 1, 2});
        parList.add(new Integer[]{5, 3, 2});
        return parList;
    }

    public ParameterTest(int expected, int input1, int input2) {
        this.expected = expected;
        this.input1 = input1;
        this.input2 = input2;
    }

    @Test
    public void testAdd(){

        assertEquals(expected, Math.addExact(input1, input2));
    }

}

以上代码会首先执行initParameters()方法生成一个参数集合,集合中的每个对象就是一组测试参数。然后执行ParameterTest()构造方法为每一组测试提供一组测试参数,最后执行testAdd()测试方法进行一组测试。initParameters()方法只会执行一次,ParameterTest()和testAdd()执行次数与参数组数相同。

个人认为,使用Junit参数化设置显得有点繁琐,在一个测试方法内声明多个断言显得更为简单。但不知道会不会有其他需要考虑的因素?

好的习惯

  1. 测试方法名一般采用【test+被测试方法名】的格式来命名。
  2. 测试类建议置于test目录下,并与被测试类采用相同的包名。
  3. 不同代码的测试应该相互独立,一个类对应一个测试类,一个函数对应一个测试函数。

参考链接:

JUnit 4 官网
慕课网-JUnit—Java单元测试必备工具

发布了36 篇原创文章 · 获赞 85 · 访问量 38万+

猜你喜欢

转载自blog.csdn.net/u012719153/article/details/79499522