zoukankan      html  css  js  c++  java
  • Hamcrest匹配器框架

    其实在之前的文章中已经使用过 Hamcrest 匹配器框架,本篇文章将系统的介绍它的使用.

    为什么要用Hamcrest匹配器框架

    Hamcrest是一款软件测试框架, 可以通过现有的匹配器类检查代码中的条件.也可以通过自定义的匹配器实现.

    要在JUnit中使用Hamcrest匹配器,可以用它的assertThat语句,并且可添加一个或多个匹配器.

    Hamcrest一般被视作第三代匹配器框架.第一代使用断言(逻辑语句),但这样的测试不易读.第二代测试框架引入了特殊的断言方法,例如assertEquals().然而这种方式会导致编写过多类似的断言方法.Hamcrest采用了assertThat方法和匹配器表达式来确定测试是否成功,解决上述两个缺点.

    Hamcrest的目标是使测试尽可能的提高可读性.例如is()方法其实就是equalTo()的包装方法.

    下面的代码就是一个使用Hamcrest的案例.

    package com.lulu.androidtestdemo.hamcrest;
    import org.junit.Test;
    import static org.junit.Assert.assertEquals;
    import static org.hamcrest.MatcherAssert.assertThat;
    import static org.hamcrest.Matchers.*;
    
    /**
     * Created by lulu on 2018/3/17.
     */
    public class TestHamcrest {
        boolean a;
        boolean b;
        @Test
        public void testHamcrest() throws Exception {
            //下面语句的测试目的是一致的
            assertThat(a, equalTo(b));
            assertThat(a, is(equalTo(b)));
            assertThat(a, is(b));
        }
    }

    下面代码比较了一下pure JUnit 4和使用Hamcrest的断言语句.

    // JUnit 4 for equals check
    assertEquals(expected, actual);
    // Hamcrest for equals check
    assertThat(actual, is(equalTo(expected)));
    
    // JUnit 4 for not equals check
    assertNotEquals(expected, actual);
    // Hamcrest for not equals check
    assertThat(actual, is(not(equalTo(expected))));

    也可以通过anyOf()等方法实现匹配器的链接.

    assertThat("test", anyOf(is("testing"), containsString("est")));

    通常Hamcrest的错误信息也更容易阅读.(下图为Pure JUnit 4和Hamcrest错误log的对比)

    assertTrue(result instanceof String);
    // error message:
    java.lang.AssertionError
        at org.junit.Assert.fail(Assert.java:86)
        at org.junit.Assert.assertTrue(Assert.java:41)
        at org.junit.Assert.assertTrue(Assert.java:52)
    // ...
    
    
    assertEquals(String.class, result.getClass());
    // error message:
    java.lang.NullPointerException
        at com.vogella.hamcrest.HamcrestTest.test(HamcrestTest.java:30)
    // ....
    
    
    assertThat(result, instanceOf(String.class));
    // error message:
    java.lang.AssertionError:
    Expected: an instance of java.lang.String
         but: null
        at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
        at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
    // ...

    使用Hamcrest匹配器也具备更高的类型安全性, 因为它们都使用了泛型.

    添加Hamcrest依赖

    对于Android Studio,需要在build.gradle中添加:

    dependencies {
        // Unit testing dependencies
        testImplementation 'junit:junit:4.12'
        // Set this dependency if you want to use Hamcrest matching
        testImplementation 'org.hamcrest:hamcrest-library:1.3'
    }

    使用Hamcrest

    示例

    Hamcrest匹配器的示例如下所示

    assertThat(Long.valueOf(1), instanceOf(Integer.class));
    // shortcut for instanceOf
    assertThat(Long.valueOf(1), isA(Integer.class));

    静态导入

    使用静态导入可以使得所有匹配器都可用,更方便开发人员找到合适的匹配器.

    import static org.hamcrest.MatcherAssert.assertThat;
    import static org.hamcrest.Matchers.*;

    一些重要的Hamcrest匹配器

    下面是一些非常重要且常用的Hamcrest匹配器

    • allOf - 所有匹配条件都匹配则通过
    • anyOf - 任何一个匹配条件匹配则通过
    • not - 与匹配条件违背则通过
    • equalTo - 使用Object.equals方法测试对象相等
    • is - 与equalTo相同,仅用来提高代码可读性
    • hasToString - 测试 Object.toString方法
    • instanceOf,isCompatibleType - 测试类型
    • notNullValue,nullValue - 测试null
    • sameInstance - 测试是否是同一实例
    • hasEntry,hasKey,hasValue - 测试一个Map包含entry,key或者value
    • hasItem,hasItems - 测试一个集合包含对应元素
    • hasItemInArray - 测试一个数组包含某个元素
    • closeTo - 测试浮点值接近于给定值
    • greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo
    • equalToIgnoringCase - 测试字符串相等且忽略大小写
    • equalToIgnoringWhiteSpace - 测试字符串相等且忽略空白符
    • containsString, endsWith, startsWith - 匹配字符串

    详细请看Hamcrest API: http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html

    使用Hamcrest内置的匹配器

    集合匹配器测试集合

    测试目标

    假设存在下列代码:

    List<Integer> list = Arrays.asList(5, 2, 4);

    通过使用Hamcrest匹配器对这个list进行下列验证:

    • 大小为3
    • 包含2, 4, 5三个元素,忽略顺序
    • 每个元素都大于1

    测试代码

    @Test
    public void hasSizeOf3() {
        List<Integer> list = Arrays.asList(5, 2, 4);
    
        assertThat(list, hasSize(3));
    }
    @Test
    public void containsNumbersInAnyOrder() {
        List<Integer> list = Arrays.asList(5, 2, 4);
    
        assertThat(list, containsInAnyOrder(2, 4, 5));
    }
    @Test
    public void everyItemGreaterThan1() {
        List<Integer> list = Arrays.asList(5, 2, 4);
    
        assertThat(list, everyItem(greaterThan(1)));
    }

    集合匹配器验证数组

    测试目标

    假设存在下列代码:

    Integer[] ints = new Integer[] {7, 5, 12, 16};

    通过使用Hamcrest匹配器对这个ints数组进行下列验证:

    • 长度为4
    • 以特定的顺序含有7, 5, 12, 16元素

    测试代码

    @Test
    public void arrayHasSizeOf4() {
        Integer[] ints = new Integer[] { 7, 5, 12, 16 };
    
        assertThat(ints, arrayWithSize(4));
    }
    @Test
    public void arrayContainsNumbersInGivenOrder() {
        Integer[] ints = new Integer[] { 7, 5, 12, 16 };
    
        assertThat(ints, arrayContaining(7, 5, 12, 16));
    }

    Hamcrest beans匹配器

    测试目标

    假设存在下面的类:

    public class Todo {
        private final long id;
        private String summary;
        private String description;
        private int year;
    
        public Todo(long id, String summary, String description) {
            this.id = id;
            this.summary = summary;
            this.description = description;
        }
        //getter 和 setter
    }

    通过使用Hamcrest匹配器进行下列验证:

    • Todo类含有名叫 “summary”的属性
    • 如果Todo类被创建时给summary属性传入”Learn Hamcrest”, 则summary属性会用这个值进行初始化
    • 两个对象用相同的值创建,会有相同的属性值

    测试代码

        @Test
        public void objectHasSummaryProperty () {
            Todo todo = new Todo(1, "Learn Hamcrest", "Important");
            assertThat(todo, hasProperty("summary"));
        }<
        @Test
        public void objectHasCorrectSummaryValue () {
            Todo todo = new Todo(1, "Learn Hamcrest", "Important");
            assertThat(todo, hasProperty("summary", equalTo("Learn Hamcrest")));
        }
        @Test
        public void objectHasSameProperties () {
            Todo todo1 = new Todo(1, "Learn Hamcrest", "Important");
            Todo todo2 = new Todo(1, "Learn Hamcrest", "Important");
            assertThat(todo1, samePropertyValuesAs(todo2));
        }

    字符串匹配器

    实现下列对字符串的检查:

    • “”是一个空字符串
    • 一个给定的字符串不是空或者null
        @Test
        public void isStringEmpty() {
            String stringToTest = "";
            assertThat(stringToTest, isEmptyString());
        }
        @Test
        public void isStringEmptyOfNull() {
            String stringToTest = "";
            assertThat(stringToTest, isEmptyOrNullString());
        }

    原文地址:https://blog.csdn.net/u013144863/article/details/79940039

  • 相关阅读:
    627. Swap Salary
    176. Second Highest Salary
    596. Classes More Than 5 Students
    183. Customers Who Never Order
    181. Employees Earning More Than Their Managers
    182. Duplicate Emails
    175. Combine Two Tables
    620. Not Boring Movies
    595. Big Countries
    HDU 6034 Balala Power! (贪心+坑题)
  • 原文地址:https://www.cnblogs.com/jpfss/p/10955980.html
Copyright © 2011-2022 走看看