java单元测试加载_Java单元测试-快速上手Junit(进阶)

基于Eclipse的单元测试框架Junit进阶

导言

在学习了上篇入门之后,如果你有所尝试,相信已经把持不住想要更高级的功能了,下面我们进入正题。(先把上次的简介部分放过来,因为这次会用到Before和After)

Junit简介

JUnit是一个Java语言的单元测试框架,应用它进行单元测试,能够准确、快速地保证程序基本模块的正确性。Junit通过注解的方式来识别测试方法,目前支持的主要注解有:

@BeforeClass:一次性setup,全局只执行一次,第一个运行

@AfterClass:一次性teardown,全局也只执行一次,最后一个运行

@Before:每次都在测试方法运行之前运行

@After:每次都在测试方法运行之后运行

@Test:测试方法

一个JUnit4的单元测试用例执行顺序为:

@BeforeClass -> @Before -> @Test -> @After -> @AfterClass,其中黑体部分可被多次执行。

添加Before&After

这个比较简单,只需要在新建测试程序的时候添加两个小选项就好,如图所示。

83f8534cae086e9e6799c708782f1440.png

那么,这两个方法是做什么的呢?setUp()顾名思义,就是在每次测试开始之前要做的一些初始化工作,比如,清空队列、还原执行状态等;而tearDown()呢?也很容易理解,就是在某个testcase结束之后所做的一些回收、清除或者恢复工作。总之都是为了保证测试的高效进行。

测试异常处理

有时候我们的方法会抛出异常,那么测试的时候如果遇到会发现testcase显示为error,但是我们正是想让程序在某种情况下抛出异常,该如何处理呢?很简单,只需要添加一个expected就可以解决啦!

@Test(expected = ArithmeticException.class)

public void testDivideByZero(){

cal.divide(0);

}

这样,测试起来关于异常的error就可以消失不见了。

参数化测试

在某方法的分支较多、或者该方法的参数分很多情况、或者参数有较多特殊值,但是又需要较高的测试覆盖率时,我们就需要用到这种参数化的测试了,因为不然你的代码量会急剧飙升,而且会产生很多重复代码段,对于有程序洁癖的你是否能忍受呢?

我们还是举之前的例子,比如要测试乘方,我们也许会分3类测试:正数的平方,0的平方,负数的平方。如何参数化呢?

package JunitTest;

import static org.junit.Assert.*;

import java.util.Arrays;

import java.util.Collection;

import org.junit.Before;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.junit.runners.Parameterized;

import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)

public class ParaTest {

private static Calculator Cal = new Calculator();

private double para;//parameter passed to method

private double expcted;//expected result

@Before

public void setUp() throws Exception {

Cal.clear();

}

@Parameters

public static Collection db(){

return Arrays.asList(new Object[][]{

/*{para, expected}*/

{-6, 36},

{0, 0},

{3, 9}

});

}

public ParaTest(double para, double expected) {

// TODO Auto-generated constructor stub

this.para = para;

this.expcted = expected;

}

@Test

public void testSquare() {

Cal.square(this.para);

assertEquals(this.expcted, Cal.getResult(), 0.0001);

}

}

当然,这只是一个特例,在实际应用的时候不一定仅仅只有两个参数,也不一定一个参数是结果的期望值,总之灵活使用Collection中的东西就好,但切记,参数一定要按顺序书写,把握好db()和构造方法中的参数对应关系。

那么,这段代码如何实现的呢?做如下分析:

每一个参数化测试都要有自己的专属类,不能共用

为此类指定Runner为ParameterizedRunner,通过在类的声明处添加@RunWith(Parameterized.class)修饰来实现

在专属类中确定定义要使用的变量,该例有两个变量(para、expected)

用Collection框架让测试数据组的处理标准化,用@Parameters对其修饰

构造函数(constructor)的定义,保证与方法db()中参数的对应关系

限时测试

一般情况下,在测试时间过长、或者测试出现停滞状况时,我们都能够从JUnit的布局(layout)中看出来,从而定位到出现耗时较多(一般为死循环)的方法。所以该测试方式的作用主要体现在预防层面,而并非测试层面,这里就不赘述了。该方式可通过在注解@Test之后添加timeout来实现: @Test(timeout = 1000) ,注意此处的time单位为毫秒(ms)。

以上就是我学到的JUnit应用,之后会有覆盖率统计相关的更新。

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接(http://www.cnblogs.com/Echo-41/p/6921252.html)


版权声明:本文为weixin_30959723原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。