文档章节

深入探索:单元测试

灯-塔
 灯-塔
发布于 2017/09/06 15:44
字数 931
阅读 13
收藏 0

单元测试这一块我们一直都有在接触,但是对于我来说,还不够重视或深入,可以说是忽视的一块,现在公司要把测试覆盖率给推起来,此时正好可以来探究探究。 JUnit4 单元测试主要有以下的一些功能:

  • 参数测试
  • 异常测试
  • 超时测试
  • 灵活固件
  • 忽略测试
  • 对测试进行逻辑分组

注意:本版本基于JUnit4.12。

参数测试

下面我们会对这样的一个类做参数测试,我们需呀一个 参数 和 一个预期结果值

public class Fibonacci {
    public static int compute(int n) {
        int result = 0;

        if (n <= 1) {
            result = n;
        } else {
            result = compute(n - 1) + compute(n - 2);
        }

        return result;
    }
}

如何做测试?第一个方法是构造函数方式

@RunWith(Parameterized.class)
public class FibonacciTest {

    @Parameters
    public static Collection<Object[]> data() {
        /* 数组第一个 为 参数, 第二个为 期望结果 */
        return Arrays.asList(new Object[][] {{0, 0}, {1, 1}, {2, 1}, {3, 2}, {4, 3}, {5, 5}, {6, 8}});
    }

    private int fInput;

    private int fExpected;

    public FibonacciTest(int input, int expected) {
        fInput = input;
        fExpected = expected;
    }

    @Test
    public void test() {
        Assert.assertEquals(fExpected, Fibonacci.compute(fInput));
    }
}

非构造函数实现(推荐:非构造函数更加灵活,不会影响类的其他方法):

@RunWith(Parameterized.class)
public class FibonacciTest2 {
    @Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] {{0, 0}, {1, 1}, {2, 1}, {3, 2}, {4, 3}, {5, 5}, {6, 8}});
    }

    @Parameter // first data value (0) is default
    public /* NOT private */ int fInput; // 数组第一个参数为输入参数

    @Parameter(1)
    public /* NOT private */ int fExpected; // 数组第一个参数为 预期参数

    @Test
    public void test() {
        Assert.assertEquals(fExpected, Fibonacci.compute(fInput));
    }
}

参考:https://github.com/junit-team/junit4/wiki/Parameterized-tests

异常测试

在我们编写测试用例的过程中,我们往往都会有期望异常的测试方法,有异常就是对了。 举一个例子

new ArrayList<Object>().get(0);

这样的方法毫无疑问会爆出IndexOutOfBoundsException 数组越界异常,为此,我们要验证这个异常的出现是正确的,我们可以@Test(exceted=IndexOutOfBoundsException.class) 来标记期望的异常。

@Test(expected = IndexOutOfBoundsException.class) 
public void empty() { 
     new ArrayList<Object>().get(0); 
}

然而这个只是方法之一,但却不是推荐的方法,对于更长的测试,建议使用ExpectedException Rule 来实现;

对异常进行更深的测试: 上面的方式是一个非常好的示例,但是他是有限制的。例如, 不能在异常中测试消息的值, 也不能在引发异常后检测域对象的状态。在Junit3.x 是用 try/catch 来做的(这个不浪费时间叙述),但是在Junit4.x 可以使用 @Rule 来实现。使用 ExpectedException 规则。此规则允许您不仅指示所期望的异常, 而且还可以显示所期望的异常消息。 实现如下:

public class TestExyRule {
    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void shouldTestExceptionMessage() throws IndexOutOfBoundsException {
        List<Object> list = new ArrayList<Object>();
        thrown.expect(IndexOutOfBoundsException.class);
        thrown.expectMessage("Index: 0, Size: 0");
        list.get(0); // execution will never get past this line
    }
}

上面例子的expectMessage 可以使用 Matchers 来做, 这样可以更加的灵活,如:thrown.expectMessage(Matchers.containsString("Size: 0")); 当然我们也可以更加进一步的 验证异常的状态:

import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.startsWith;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

public class TestExy {
     @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void shouldThrow() {
        TestThing testThing = new TestThing();
        thrown.expect(UnsupportedOperationException.class);
        thrown.expectMessage(startsWith("some Message"));
        testThing.chuck();
    }

    private class TestThing {
        public void chuck() {
            throw new UnsupportedOperationException("some Message");
        }
    }
}

https://github.com/junit-team/junit4/wiki/Exception-testing

超时测试

https://github.com/junit-team/junit4/wiki/Timeout-for-tests 超时测试比较简单,举个例子。

@Test(timeout =1000)
public void testMethod() {
    for(;;){}
}

如上面的代码我们对时间做了限制为1s, 但是由于有死循环,是无法在规定时间内通过测试的。

灵活固件

https://github.com/junit-team/junit4/wiki/Aggregating-tests-in-suites

逻辑分组测试

https://github.com/junit-team/junit4/wiki/Categories

参考

© 著作权归作者所有

共有 人打赏支持
灯-塔
粉丝 4
博文 39
码字总数 63914
作品 0
广州
程序员
私信 提问
.NET系列文章——近一年文章分类整理,方便各位博友们查询学习

由于博主今后一段时间可能会很忙(准备出书:《.NET框架设计—模式、配置、工具》,外加换了新工作),所以博客会很少更新; 在最近一年左右时间里,博主各种.NET技术类型的文章都写过,根据...

王清培
2014/03/02
0
0
测试你的前端代码 - part1(介绍篇)

本文作者:Gil Tayar 编译:胡子大哈 翻译原文:http://huziketang.com/blog/posts/detail?postId=58d3dcb87413fc2e8240855a 英文连接:Testing Your Frontend Code : Part I (Introduction......

胡子大哈
2017/03/23
0
0
Android、JUnit深入浅出(一)——JUnit初步解析

Android、JUnit深入浅出(一)——JUnit初步解析 Android SDK 1.5已经将JUnit包含进来了,但是一直没有去深入了解,以前在使用一些C++的开源库中学习过与CPPUnit,简要分析过其主要框架,如下...

庸人谷
2012/12/26
0
0
spring-restdocs的研究

该框架通过单元测试来生成REST接口的说明文档,详见Spring REST Docs 可以对参数和返回值进行说明,还能产生url和返回用例 通过完善单元测试,和目前的mockMvc框架相结合,可以产生Asciidoct...

阿喀琉斯之盾
2016/07/22
1
0
玩转Google开源C++单元测试框架Google Test系列(gtest)(总)

前段时间学习和了解了下Google的开源C++单元测试框架Google Test,简称gtest,非常的不错。 我们原来使用的是自己实现的一套单元测试框架,在使用过程中,发现越来越多使用不便之处,而这样不...

元谷
2013/12/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

多表查询

第1章 多表关系实战 1.1 实战1:省和市  方案1:多张表,一对多  方案2:一张表,自关联一对多 1.2 实战2:用户和角色 (比如演员和扮演人物)  多对多关系 1.3 实战3:角色和权限 (比如...

stars永恒
今天
6
0
求推广,德邦快递坑人!!!!

完全没想好怎么来吐槽自己这次苦逼的德邦物流过程了,只好来记一个流水账。 从寄快递开始: 2019年1月15日从 德邦物流 微信小app上下单,截图如下: 可笑的是什么,我预约的是17号上门收件,...

o0无忧亦无怖
昨天
6
0
Mac Vim配置

1.升级 vim   我自己 MacBook Pro 的系统还是 10.11 ,其自带的 vim 版本为 7.3 ,我们将其升至最新版: 使用 homebrew : brew install vim --with-lua --with-override-system-vim 这将下...

Pasenger
昨天
8
0
vmware安装Ubuntu上不了网?上网了安装不了net-tools,无法执行ifconfig?

1.重新设置网络适配器还是不行,如下指定nat 2.还需要指定共享网络,我是在无线环境下 3.无法执行ifconfig https://packages.ubuntu.com/bionic/net-tools到这个网站下载net-tools的deb文件...

noob_chr
昨天
4
0
解决SVN:E210007无法协商认证机制

svn:E210007 svn: Cannot negotiate authentication mechanism 执行下面代码即可 sudo yum install cyrus-sasl cyrus-sasl-plain cyrus-sasl-ldap...

临江仙卜算子
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部