`

探索junit4核心

阅读更多

软件测试主要分成5类,范围从小到大分别为:单元测试->集成测试->功能测试->压力测试->验收测试。此系列中我们只讨论单元测试。

>> 单元测试的3种类型:

* 逻辑单元测试:主要针对一个单独的方法来检查代码,可以通过mock object或者stub来控制某个特定的测试方法的边界。

* 集成单元测试:主要用来测试在真实环境或者真实环境的一部分中不同组件之间的相互作用。例如测试一段访问某个数据库的代码是否真正有效的调用了数据库

* 功能单元测试:已经超出了集成单元测试的边界,目的是为了确认一个刺激响应。例如如果一个网页只能登录才能看到,否则重定向到登录页面。这个时候可以变形一个功能单元测试,通过向这个网页发送一个HTTP请求,然后验证返回是否是一个重定向HTTP状态码302等。

注:严格来讲,功能单元测试并不是纯粹的单元测试,也不是纯粹的功能测试。它相对于纯粹的单元测试而言,更多的依赖外部环境,但它又不像纯粹的功能测试那样会测试一个完整的工作流。我们之所以把功能单元测试放入我们讨论范围,是因为它通常在开发环境中作为一系列测试中一部分是非常有用的。

>> Junit的几个核心对象:

* Assert:让你定义想测试的条件,条件成立时,assert方法保持沉默,但是不成立的时候就会抛出异常

* 测试:一个以@Test注解的方法定义了一个测试。为了运行这个方法,JUnit会创建一个包含该测试方法的测试类的新实例,然后再调用这个被注解的方法,也就是说一个测试方法就会new一个测试类。

* 测试类:一个测试类是@Test方法的容器

* Suite:Suite允许你将测试类归组

* Runner:Runner类用来运行测试,JUnit4向后兼容,可以运行JUnit3的测试

>> 运行参数化测试:

来看一个Runner实例,一个测试方法通过传多个参数去让它执行多次,Parameterized是JUnit多个测试运行器Runner中的一个而已:

@RunWith(Parameterized.class)
public class CalculatorParameterizedTest {
    private double expected;
    private double valueOne;
    private double valueTwo;
 
    public CalculatorParameterizedTest(
            double expected, double valueOne, double valueTwo) {
        this.expected = expected;
        this.valueOne = valueOne;
        this.valueTwo = valueTwo;
    }
 
    @Parameters
    public static Collection<Object[]> getTestParameters() {
        List<Object[]> params = Arrays.asList(new Object[][]{
                {2,1,1},
                {3,2,1},
                {4d,2d,2d}
        });
        System.out.println(params.size());
        return params;
    }
 
    @Test
    public void testSum() {
        Calculator calculator = new Calculator();
        assertThat(calculator.add(valueOne, valueTwo), is(expected));
    }
}

>> Junit最佳实践:

* 一次只能单元测试一个对象。当一个对象与其他复杂对象交互时候,可以使用可预测的测试对象将被测试对象包围起来。

* 一个单元测试等于一个@Test方法,不要试图把多个测试塞进一个方法中,这样导致的结果就是测试方法变得更加复杂,难以阅读也难以理解。

* 让测试改善你的代码,应当根据测试时候发现的问题重构代码,使其更加易于使用。极限编程提倡不要过早的添加功能。

>> 测试异常:

使用expected的注解参数测试异常示例

@Test(expected = RuntimeException.class)
public void testAddRequestDuplicateName() {
    SampleRequest request = new SampleRequest();
    SampleHandler handler = new SampleHandler();
 
    controller.addHandler(request, handler);
}

>> 超时测试:

使用timeout注解参数测试超时示例,使用@Ignore注解跳过该测试

@Test(timeout = 130)
@Ignore(value = "Skip for now")
public void testProcessMultipleRequestsTimeout() {
    Request request;
    Response response = new SampleResponse();
    RequestHandler handler = new SampleHandler();
    for (int i = 0; i < 99999; i++) {
        ...
    }
}

>> 引入Hamcrest匹配器

有时候junit的assert语句太复杂很难看懂,这个时候可以使用hamcrest框架的短语来简化assert语句。Hamcrest是一个库,包含了大量的匹配器对象(也称约束或者谓语),它可以被植入到其他几种开发语言比如java、C++、Objective-C、Python和PHP,请注意,Hamcrest本身不是一个测试框架,确切的说,它可以帮你通过声明方式指定简单的匹配规则,尤其适用于单元测试,不过也可以应用到其他领域。

@Test
public void testWithHamcrest() {
    assertThat(values, hasItem(anyOf(equalTo("one"), equalTo("two"),
            equalTo("three"))));
}

一些常用的Hamcrest匹配器:

anything 绝对匹配,更加可读性
is 仅用于改善可读性
allOf 检查是否与所有包含的匹配器匹配(相对于&&)
anyOf 检查是否与任意包含的匹配器匹配(相对于||)
not 非(相对于!)
instanceOf、isCompatibleType 对象类型
sameInstance 测试对象引用是否指向同一个对象
notNullValue、nullValue null值或非null值
hasProperty 测试JavaBean是否具有某属性
hasEntry、hasKey、hasValue 测试Map
hasItem、hasItems 测试集合

closeTo、greaterThan、greaterThanOrEqual、

lessThan、lessThanOrEqual

测试数字的大小
equalToIgnoringCase 测试字符串相同与否,忽略大小写
equalToIgnoringWhiteSpace 测试字符串相同与否,忽略空白
containsString、endsWith、startWith 测试字符串包含、结尾、开头
分享到:
评论

相关推荐

    JUnit实战(第2版)

    《JUnit实战(第2版)》从认识JUnit、不同的测试策略、JUnit与构建过程、JUnit扩展4个方面,由浅入深、由易到难地对JUnit展开了系统的讲解,包括探索JUnit的核心、软件测试原则、测试覆盖率与开发、使用stub进行粗粒度...

    Junit实战第二版 中文完整版 0分下载

    《JUnit实战(第2版)》从认识JUnit、不同的测试策略、JUnit与构建过程、JUnit扩展4个方面,由浅入深、由易到难地对JUnit展开了系统的讲解,包括探索JUnit的核心、软件测试原则、测试覆盖率与开发、使用stub进行粗粒度...

    Junit实战第二版

    《JUnit实战(第2版)》从认识JUnit、不同的测试策略、JUnit与构建过程、JUnit扩展4个方面,由浅入深、由易到难地对JUnit展开了系统的讲解,包括探索JUnit的核心、软件测试原则、测试覆盖率与开发、使用stub进行粗...

    JUnit实战 第2版 (英文版)

    《JUnit实战(第2版)》从认识JUnit、不同的测试策略、JUnit与构建过程、JUnit扩展4个方面,由浅入深、由易到难地对JUnit展开了系统的讲解,包括探索JUnit的核心、软件测试原则、测试覆盖率与开发、使用stub进行粗粒度...

    Junit实战第二版 中文完整版

    JUnit实战(第2版)本书从认识JUnit、不同的测试策略、JUnit与构建过程、JUnit扩展4个方面,由浅入深、由易到难地对JUnit展开了系统的讲解,包括探索JUnit的核心、软件测试原则、测试覆盖率与开发、使用stub进行粗粒度...

    Junit实战(第2版)

    本书从认识JUnit、不同的测试策略、JUnit与构建过程、JUnit扩展4个方面,由浅入深、由易到难地对JUnit展开了系统的讲解,包括探索JUnit的核心、软件测试原则、测试覆盖率与开发、使用stub进行粗粒度测试、使用mock...

    junit实战第二版

    it IN Action ] 第一章 JUnit起步 JUnit jumpstart 本章内容 ■ 手工编写简单测试 ■ 安装JUnit以及运行测试 ...第二章 探索JUnit Exploring JUnit 本章内容 ■ 使用核心JUnit类 ■ 理解JUnit生命周期

    immaterial:探索Android架构

    Android设计模式和应用程序设计探索 核心结构 此应用程序混合使用Java和Android模块。 Java模块允许更简单的实现和更快的构建时间,因为所有测试均以简单的Junit测试运行。 Android模块仅保留那些需要了解Android...

    myeslib:使用 Camel、Hazelcast、Guice、Gson、JDBI、Lombok 等进行的事件溯源实验

    请参阅语境这个想法是探索在 基本上,代替具有与空隙的方法,该方法将返回一个List&lt;? extends Event&gt; List&lt;? extends Event&gt; 。 这些事件和原始命令将形成一个 。 然后,这个 UnitOfWork 被持久化到一个由...

    Struts2 in action中文版

    第二部分 核心概念:动作、拦截器和类型转换 第3章 使用Struts 2动作 36 3.1 Struts 2动作简介 36 3.2 打包动作 39 3.2.1 Struts 2公文包示例应用程序 39 3.2.2 组织你的包 39 3.2.3 使用struts-default包中的组件 ...

Global site tag (gtag.js) - Google Analytics