Junit

JUnit框架用一组assert方法封装了一些常用的断言。这些assert方法可以帮我们简化单元测试的编写。这样的话,Junit就可以根据这些断言是否抛出 AssertionFailedError 错误来判断测试用例的执行结果。

Hamcrest

使用过Junit 的应该有过体验:在实际开发中,一些基本的断言,如eqaul,null,true它们的可读性并不是很好。而且很多时候我们要比较对象、集合、Map等数据结构。这样我们要么进行大段的字段获取再断言。或者干脆自己编写表达式并断言其结果。
JUnit4.4引入了Hamcrest框架,Hamcest提供了一套匹配符Matcher,这些匹配符更接近自然语言,可读性高,更加灵活。

Hamcrest 提供了大量被称为“匹配器”的方法。其中每个匹配器都设计用于执行特定的比较操作。Hamcrest的可扩展性很好,让你能够创建自定义的匹配器。最重要的是,JUnit也包含了Hamcrest的核心,提供了对Hamcrest的原生支持,可以直接使用Hamcrest。当然要使用功能齐备的Hamcrest,还是要引入对它的依赖。

看个对比例子,前者使用Junit的 断言,后者使用 Hamcrest的断言。

    @Testpublic void test_with_junit_assert() {int expected = 51;int actual = 51;assertEquals("failure - They are not same!", expected, actual);}@Testpublic void test_with_hamcrest_assertThat() {int expected = 51;int actual = 51;assertThat("failure - They are not same!", actual, equalTo(expected));}

个人感觉有两个明显的区别:
1. 参数顺序。两者的expected 和 actual 前后顺序是相反的。
2. Hamcrest 几乎总是直接使用对象。它的语法更符合函数式编程的风格。
这点很好理解了,Junit 总是获取值后再比较,因为比较的是简单的值,因此被比较的放在前面更符合习惯。
而Hamcrest 是直接对测试结果的对象进行一些更复杂的匹配。

支持语言

Hamcrest 支持以下几种语言,详情见http://hamcrest.org/
Java
Python
Ruby
Objective-C
PHP
Erlang
Swift

Hamcrest匹配器

Hamcrest 提供了很强大的一些api 供我们进行测试断言。

核心:anything - 总是匹配,如果你不关心测试下的对象是什么是有用的describedAs - 添加一个定制的失败表述装饰器is - 改进可读性装饰器 - 见下 “Sugar”
逻辑:allOf - 如果所有匹配器都匹配才匹配,像Java里的&&anyOf - 如果任何匹配器匹配就匹配,像Java里的||not - 如果包装的匹配器不匹配器时匹配,反之亦然
对象:equalTo - 测试对象相等使用Object.equals方法hasToString - 测试Object.toString方法instanceOf, isCompatibleType - 测试类型notNullValue, nullValue - 测试nullsameInstance - 测试对象实例
Beans:hasProperty - 测试JavaBeans属性
集合:array - 测试一个数组元素test an array’s elements against an array of matchershasEntry, hasKey, hasValue - 测试一个Map包含一个实体,键或者值hasItem, hasItems - 测试一个集合包含一个元素hasItemInArray - 测试一个数组包含一个元素
数字:closeTo - 测试浮点值接近给定的值greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo - 测试次序
文本:equalToIgnoringCase - 测试字符串相等忽略大小写equalToIgnoringWhiteSpace - 测试字符串忽略空白containsString, endsWith, startsWith - 测试字符串匹配

这些API 几乎覆盖了我们测试断言的所有情况。再提供良好阅读性的情况下,减少了一些取值、循环、类型判断等代码的编写。

不足

这里说的不足,只是本人使用过程中遇到的问题。如果大牛发现Hamcrest 现有的api 支持,欢迎指正。

hasProperty

先看一个复杂的层级结构。

public class MyPerson {private Address address;private String name;private String fullName;// ...
}

其中 Address 类如下:

public class Address {private String companyAddress;private String personalAddress;// ...
}

这里我们测试一个person对象,有 companyAddress 属性。

    @Testpublic void test_with_complex_property() {MyPerson p = new MyPerson();Address address = new Address();address.setCompanyAddress("");p.setAddress(address);assertThat("failure has no address property !", p, hasProperty("address"));// would failed// assertThat("failure has no address.companyAddress !", p, hasProperty("address.companyAddress"));}

这个单元测试的第二个断言出错。也就是说断言 hasProperty 时,不能跨层。这点就没有 rest-assured 的API 用着那么方便了。

这里我想了个办法如下:

assertThat("failure has no address property !", p, hasProperty("address", hasProperty("companyAddress")));

进行了一次嵌套后,就可以满足我们的需要了。

集合的泛型

这里我们要处理集合,断言每个元素都有属性:

    @Testpublic void test_with_list_generics() {List persons = new ArrayList<MyPerson>();MyPerson p = new MyPerson();p.setName("KaKa");persons.add(p);MyPerson p2 = new MyPerson();p2.setName("Hust");persons.add(p2);// compile error// assertThat("failure has no address property !", persons, everyItem(hasProperty("address")));assertThat("failure has no address property !", (List<Object>)persons, everyItem(hasProperty("address")));}

这我就没法理解了。显然,被注释的那句断言直接编译失败!然后向上转型后,反而成功。

对象自身属性比较

还用上面的例子,每个 person对象 都有 namefullName 两个属性,断言 fullName 是startwith name 属性。

    @Testpublic void test_with_list_compare_with_self() {// 加上 类型List persons = new ArrayList<MyPerson>();MyPerson p = new MyPerson();p.setName("KaKa");p.setFullName("KaKa Zhang");persons.add(p);MyPerson p2 = new MyPerson();p2.setName("Hust");p.setFullName("Hust Zhang");persons.add(p2);// 这里没法写, person对象 属性 startsWith 另一个属性assertThat((List<Object>)persons, everyItem(hasProperty("name", startsWith(""))));}

这时候只能循环来断言,某个属性startwWith 另一个属性了。

    @Testpublic void test_with_list_compare_with_self() {// 加上 类型List<MyPerson> persons = new ArrayList<MyPerson>();MyPerson p = new MyPerson();p.setName("KaKa");p.setFullName("KaKa Zhang");persons.add(p);MyPerson p2 = new MyPerson();p2.setName("Hust");p2.setFullName("Hust Zhang");persons.add(p2);// 还是用循环来做for (MyPerson person : persons) {assertThat(person.getFullName().startsWith(""), is(true));}}

上面的这几个时我遇到几个情况。如果大牛有更好的做法,欢迎指点。

Hamcrest 总结相关推荐

  1. junit集成Hamcrest测试集合中某个属性是否包含特定值

    junit已经集成Hamcrest但是还是需要引用hamcrest-library,不然只有基本方法,高级的没有 <dependency> <groupId>junit< ...

  2. junit、hamcrest、eclemma的安装与使用

    1.junit的安装与使用 1.1 安装步骤 1)从http://www.junit.org/ 下载junit相应的jar包: 2) 在CLASSPATH中加入JAR包所在的路径,如E:\Java\j ...

  3. 软件测试实验——安装并使用junit、hamcrest和eclemma进行简单测试

    一.安装junit.hamcrest和eclemma 首先,到junit官网下载junit和hamcrest. 新建java项目 完整代码已经上传至github:flyzero的coding路 实验内 ...

  4. 基于Python语言Hamcrest断言的使用

    我们通常熟悉的断言是assert()系列的断言,但有的时候也不能满足我们的需求,所以有了更强大的断言Hamcrest. 一.Hamcrest简介 Hamcrest源于Java,支持多种语言,是用于编写 ...

  5. JUnit注解与hamcrest

    2019独角兽企业重金招聘Python工程师标准>>> 黑盒测试: 黑盒测试也称功能测试,它是通过测试来检测每个功能是否都能正常使用.在测试中,把程序看作一个不能打开的黑盒子,在完全 ...

  6. JUnit和hamcrest的jar包关系

    JUnit的jar包和hamcrest的jar包关系 junit和hamcrest是两个不同的框架,不同的东西.只不过是junit使用了hamcrest框架而已. 在junit上下载的junit的包解 ...

  7. JUnit4中使用Hamcrest测试框架的assertThat断言 小实例

    ‍1.JUnit4.4引入了Hamcrest框架,Hamcest提供了一套匹配符Matcher,这些匹配符更接近自然语言,可读性高,更加灵活: 2.使用全新的断言语法:assertThat,结合Ham ...

  8. Junit Hamcrest Eclemma

    一.安装Junit 和 Hamcrest 选中项目->点击project->properties->Java Build path->libraries 点击右侧 Add Li ...

  9. hamcrest详细介绍

    使用过Junit 的应该有过体验:在实际开发中,一些基本的断言,如eqaul,null,true它们的可读性并不是很好.而且很多时候我们要比较对象.集合.Map等数据结构.这样我们要么进行大段的字段获 ...

  10. [转]Hamcrest使用方法实例

    assertThat方法需要使用hamcrest的匹配方法: 示例 assertThat( n, allOf( greaterThan(1), lessThan(15) ) ); assertThat ...

最新文章

  1. 记boost在gcc的一个库链接问题generic_category()
  2. Android Tcp操作
  3. TestNG 入门教程
  4. mybatis、ibatis 和spring集成
  5. 企业案例(二):增量恢复案例
  6. Linux如何自动获取IP地址
  7. 基于贪心算法求解TSP问题(JAVA)
  8. 我的Python之路:浏览器模拟
  9. FZU 2041 二分枚举
  10. 史上最全Plastic SCM - Unity版本控制工具使用经验分享
  11. matlab 仿真光学实验报告,基于matlab的光学实验仿真毕业论文.doc
  12. 图文介绍 Presto + Velox 整合
  13. 开源网站访问统计系统Piwik的基本使用
  14. 微信小程序.阿里巴巴矢量图标库iconfont使用
  15. Java file.encoding
  16. 密码学——变色龙哈希
  17. 一天 第二章 纤腰舞困因谁,知谁系斑骓?
  18. 0103 混蛋罗心得[装*技巧]
  19. jacob不能在Linux系统使用!
  20. 【Golang 中的 type A = XXX 与 type A XXXX的区别】

热门文章

  1. 江苏计算机一级考试知识点,江苏计算机考试一级题型(江苏省计算机一级考试题型)...
  2. excel计算机一级知识点,计算机一级考试考点:Excel电子表格
  3. SocksCap代理
  4. 豆瓣9.6分,Scala编程圣经第5版隆重来袭
  5. PowerPoint2007文件格式
  6. 接口解读:你的姓名+身份证号撑起了超11亿元市场规模,你造吗?
  7. 11年的macbook还能用吗_致我2011年买的macbook pro 15寸一封信
  8. 如何制作bt种子文件
  9. 单场淘汰制场次计算方法_怎样用单循环制进行的比赛计算场数
  10. 是德科技N9020A 频谱分析仪技术资料说明