`
yangzb
  • 浏览: 3522716 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Hamcrest指南

    博客分类:
  • QC
阅读更多

 

Hamcrest 官方网站

Hamcrest Tutorial

介绍

Hamcrest是一个书写匹配器对象时允许直接定义匹配规则的框架.有大量的匹配器是侵入式的,例如UI验证或者数据过滤,但是匹配对象在书写灵活的测试是最常用.本教程将告诉你如何使用Hamcrest进行单元测试.

我的第一个Hamcrest测试

我们将开始写一个非常简单的JUnit 3测试,但是替换使用JUnit的assertEquals方法,我们使用Hamcrest的assertThat架构和一套标准的匹配器 ,我们需要静态导入它们:

import
 static
 org.hamcrest
.MatcherAssert
.assertThat
;
import
 static
 org.hamcrest
.Matchers
.*;
 
import
 junit.framework.TestCase
;
 
public
 class
 BiscuitTest extends
 TestCase {

  public
 void
 testEquals(
)
 {

    Biscuit theBiscuit =
 new
 Biscuit(
"Ginger"
)
;
    Biscuit myBiscuit =
 new
 Biscuit(
"Ginger"
)
;
    assertThat(
theBiscuit, equalTo(
myBiscuit)
)
;
  }

}

assertThat方法是一种风格化的句子进行测试断言.在这里例子中,断言问题是第一个方法参数biscuit对象.第二个方法参数是一个 Biscuit对象的匹配器.在这是一个使用对象的equals方法检查一个对象等于另一个对象的匹配器.测试前Biscuit类定义了一个equals 方法.

如果你在你的测试中有一个以上的测试,你可以在断言中为你的测试值包含一个标识符:

assertThat(
"chocolate chips"
, theBiscuit.getChocolateChipCount
(
)
, equalTo(
10
)
)
;
assertThat(
"hazelnuts"
, theBiscuit.getHazelnutCount
(
)
, equalTo(
3
)
)
;

 

其他测试框架

Hamcrest从一开始就设计结合不同的单元测试框架.例如,Hamcrest可以使用JUnit3和4TestNG .(详细查看完整Hamcrest发布中的例子).在一个现有的测试套件中迁移到使用Hamcrest风格的断言是很容易的,因为其他断言风格可以和Hamcrest的共存.

通过使用从mock Objects框架概念匹配器到Hamcrest匹配器桥接适配器Hamcrest也可以在mock objects框架中.例如,JMock 1系统规定是Hamcrest风格.Hamcrest提供了一个JMock 1适配器来允许你在JMock 1测试中使用Hamcrest匹配器.JMock 2不需要这样一个适配器层,因为它被设计使用Hamcrest作为一个匹配库.Hamcrest还提供了EasyMock 2适配器.同样,详细查看Hamcrest例子.

常用匹配器漫游

Hamcrest带有一个有用的匹配器库.以下是一些最重要的.

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

Sugar(不明白什么意思?没有翻译)

Hamcrest努力使你的测试尽可能可读.例如,这是一个匹配器,它是一个不在基本匹配器上添加任何附加行为的包装.下面断言都是一样的:

assertThat(
theBiscuit, equalTo(
myBiscuit)
)
;
assertThat(
theBiscuit, is(
equalTo(
myBiscuit)
)
)
;
assertThat(
theBiscuit, is(
myBiscuit)
)
;

最后那种形式允许的,因为is(T value)是重载返回is(equalTo(value)).(这句话不太明白什么意思)

定制匹配器

Hamcrest捆绑了很多有用的匹配器,但你可能会发现不时您需要创建自己的来满足您的测试需求.这通常发生在你找到一个片段的代码,测试相同的 性能一遍又一遍(在不同的测试),以及您想要的片段捆绑成一个单一的断言。通过编写自己的匹配器您将去除重复代码,使您的测试更具可读性!

让我们写我们自己的匹配器测试如果一个double值有NaN值(不是一个数字),这是我们想要写的测试:

public
 void
 testSquareRootOfMinusOneIsNotANumber(
)
 {

  assertThat(
Math
.sqrt
(
-
1
)
, is(
notANumber(
)
)
)
;
}

这是实现:

package
 org.hamcrest.examples.tutorial
;
 
import
 org.hamcrest.Description
;
import
 org.hamcrest.Factory
;
import
 org.hamcrest.Matcher
;
import
 org.hamcrest.TypeSafeMatcher
;
 
public
 class
 IsNotANumber extends
 TypeSafeMatcher {

 
  @Override

  public
 boolean
 matchesSafely(
Double
 number)
 {

    return
 number.isNaN
(
)
;
  }

 
  public
 void
 describeTo(
Description description)
 {

    description.appendText
(
"not a number"
)
;
  }

 
  @Factory
  public
 static
  Matcher
 notANumber(
)
 {

    return
 new
 IsNotANumber(
)
;
  }

 
}

我们断言关于两个Double值,所以我们知道我们需要一个Matcher.对于我们的匹配器实现来说作为TypeSafeMatcher子类最方 便,它为我们转化一个Double.我们需要仅仅实现matchesSafely方法-它仅仅是检查这个Double是否是NaN,和 describedTo方法-它是用来在测试失败时产生失败消息.这是一个失败消息如何显示的列子:

assertThat(
1.0
, is(
notANumber(
)
)
)
;

失败消息

java.lang.AssertionError:
Expected: is not a number
got : <1.0>

在我们的匹配器中的第三种方法是一个方便的工厂方法.我们静态导入这种方法来在我们的测试中使用这个匹配器:

import
 static
 org.hamcrest
.MatcherAssert
.assertThat
;
import
 static
 org.hamcrest
.Matchers
.*;
 
import
 static
 org.hamcrest
.examples
.tutorial
.IsNotANumber
.notANumber
;
 
import
 junit.framework.TestCase
;
 
public
 class
 NumberTest extends
 TestCase {

 
  public
 void
 testSquareRootOfMinusOneIsNotANumber(
)
 {

    assertThat(
Math
.sqrt
(
-
1
)
, is(
notANumber(
)
)
)
;
  }

}

即使notNumber方法每次调用都创建一个新的匹配器,然而你不应该假设这对你的匹配器是仅有的使用方法.因此你应该确保你的匹配器是无状态的,所以一个单例可以在匹配之间被重用.

Sugar的生成

如果你创建了多个自定义匹配器必须分别导入它们所有,这会很麻烦.能够将它们组合起来到一个单独类将会是很好的,所以它们可以像Hamcrest匹配器库那样使用一个静态导入.

<matchers>



 
  <!-- Hamcrest library -->

  <factory
 class
="org.hamcrest.core.Is"
/>


 
  <!-- Custom extension -->

  <factory
 class
="org.hamcrest.examples.tutorial.IsNotANumber"
/>


 
</matchers>


其次,运行org.hamcrest.generator.config.XmlConfigurator命令行工具配置Hamcrest.这个工具需要XML配置文件,并生成一个单独Java类文件,它包含所有通过XML文件指定的工厂方法.

// Generated source.

package
 org.hamcrest.examples.tutorial
;
 
public
 class
 Matchers {

 
  public
 static
  org.hamcrest
.Matcher
 is(
T param1)
 {

    return
 org.hamcrest
.core
.Is
.is
(
param1)
;
  }

 
  public
 static
  org.hamcrest
.Matcher
 is(
java.lang
.Class
 param1)
 {

    return
 org.hamcrest
.core
.Is
.is
(
param1)
;
  }

 
  public
 static
  org.hamcrest
.Matcher
 is(
org.hamcrest
.Matcher
 param1)
 {

    return
 org.hamcrest
.core
.Is
.is
(
param1)
;
  }

 
  public
 static
  org.hamcrest
.Matcher
 notANumber(
)
 {

    return
 org.hamcrest
.examples
.tutorial
.IsNotANumber
.notANumber
(
)
;
  }

 
}

最后,我们可以更新我们的测试使用新的匹配器类.

import
 static
 org.hamcrest
.MatcherAssert
.assertThat
;
 
import
 static
 org.hamcrest
.examples
.tutorial
.Matchers
.*;
 
import
 junit.framework.TestCase
;
 
public
 class
 CustomSugarNumberTest extends
 TestCase {

 
  public
 void
 testSquareRootOfMinusOneIsNotANumber(
)
 {

    assertThat(
Math
.sqrt
(
-1
)
, is(
notANumber(
)
)
)
;
  }

}

请注意我们现在的使用Hamcrest库是从我们自己定制的匹配器类导入的匹配器.

分享到:
评论
2 楼 mzy0324 2014-09-30  
Sugar 语法糖么……
1 楼 liuqing9382 2010-12-12  
给初学者看很给力,但是代码排版格式差了点。

相关推荐

    hamcrest-demo-1.3-6.el7.x64-86.rpm.tar.gz

    虽然没有进一步信息显示该文件的具体内容,但根据常见的命名约定,它可能是一个文本格式的说明文档,其中包含了关于安装包的额外信息、安装指南、使用说明或者其他重要信息。在进行软件安装之前,仔细阅读该文件是一...

    bit-io-1.0.2.zip

    文档可能包含如何使用这些匹配器的指南,以及如何将它们集成到测试框架(如JUnit)中的说明。示例代码则可以帮助开发者快速上手,了解如何在实际项目中应用这些匹配器。测试用例则证明了这些匹配器的正确性和稳定性...

    Junit出现InitializationError,原因是少了两个jar包,下载下来导入即可

    确保查看这个文件以获取更多细节,特别是如果有任何特定的安装或配置指南。 在进行单元测试时,确保所有依赖都被正确地引入至关重要,因为缺少任何关键的库都可能导致测试失败或无法运行。在开发过程中,保持良好的...

    junit-4.7.jar,junit-4.11.jar

    "安装说明.txt"可能包含的是JUnit库的安装和导入到项目中的详细指南,这对于初学者尤其有用,因为正确设置JUnit环境是开始进行单元测试的第一步。 "3322软件站_www.3322.cc.url"看起来是一个网址,指向一个软件下载...

    几个junit例子

    - `read.txt`可能包含了使用这些库的说明或额外的指南。 掌握JUnit对于任何Java开发者来说都是至关重要的技能,它能确保代码的健壮性,提高开发效率,并且便于持续集成和持续交付。通过学习和实践上述知识点,你...

    kxml-2.3.0-5.el7.x64-86.rpm.tar.gz

    文件中还包括了readme.md文件,通常用于提供安装指南、软件描述或相关说明。 在具体安装过程中,该压缩包的解压指令为tar -zxvf /mnt/data/output/kxml-2.3.0-5.el7.tar.gz,这条命令的含义是使用tar命令对名为kxml...

    JUnit单元测试.zip

    文档链接`对应文档链接.txt` 提供了关于如何使用JUnit进行单元测试的详细指南。通常,这份文档会包含以下内容: 1. **安装和引入JUnit**:解释如何将JUnit库添加到项目中,包括Maven或Gradle等构建工具的配置方法。...

    Junit in Action 中文版

    此外,书中介绍了JUnit的扩展和插件,比如使用Hamcrest库增强断言表达力,以及使用TestNG等其他测试框架进行比较。这些工具和技术能帮助开发者构建更加健壮和灵活的测试框架。 在实际项目中,读者将了解到如何将...

    junit4-r4.12

    《Junit4-r4.12:核心概念与实践指南》 Junit4-r4.12 是一个广泛使用的Java编程语言的单元测试框架,它为开发者提供了强大的测试工具,帮助确保代码的质量和稳定性。本篇文章将深入探讨Junit4-r4.12的核心概念、...

    junit代码示例

    - `read.txt`通常是一份简短的阅读指南,解释了压缩包中的内容及其使用方法。 掌握这些知识点,你将能够熟练地使用JUnit4进行单元测试,确保代码的质量和可靠性。在实践中不断探索和应用,将有助于提升你的编程技能...

    Java中的异常测试框架JUnit使用上手指南

    如果你需要检查异常的详细信息,例如在不同情况下抛出相同类型但不同消息的异常,你可能需要结合其他断言库,如AssertJ或Hamcrest,或者在`catch`块中进行更复杂的逻辑判断。 总的来说,JUnit为Java开发者提供了...

    qdox-1.12.1-10.el7.x64-86.rpm.tar.gz

    压缩包子文件的文件名称列表显示了包中包含的文件,其中“readme.md”可能是一个说明文件,通常包含该软件包的基本信息、安装指南或者更新日志。“junit-4.11-8.el7.noarch.rpm”、“qdox-1.12.1-10.el7.noarch.rpm...

    junit4资料

    ### JUnit4基础知识与实践指南 #### 一、JUnit4简介 JUnit4是JUnit框架的一个重要版本,它为Java开发者提供了强大的单元测试能力。相比于早期版本,JUnit4引入了多种新特性来简化测试代码的编写过程,并提高了测试...

    junit-demo-4.11-8.el7.x64-86.rpm.tar.gz

    - hamcrest-1.3-6.el7.noarch.rpm:Hamcrest是一个提供匹配对象的期望值的库,尤其在JUnit测试中常用于断言。 - easymock2-2.5.2-12.el7.noarch.rpm:EasyMock是一个用于Java开发的模拟对象库,可简化测试中对复杂...

    RestAssured_Project

    在IT行业中,API(应用程序编程接口)已经成为现代软件开发的核心组成部分,尤其是RESTful API,它遵循...项目的结构通常包括示例代码、详细的使用指南和相关库的文档,对于初学者和有经验的开发者来说都是宝贵的资源。

    aether-test-util-1.13.1-13.el7.x64-86.rpm.tar.gz

    列表中包含了readme.md文件,它通常包含项目的说明文档和安装指南,是获取软件使用信息的重要途径。除此之外,列表中还包含了多个rpm格式的依赖包,例如junit-4.11-8.el7.noarch.rpm、qdox-1.12.1-10.el7.noarch.rpm...

    完整单元测测Jutil数据包

    “方便易用”表明这个数据包的设计考虑到了用户体验,可能包含了易于安装和配置的指南,以及清晰的文档,使得开发者可以快速地将Junit集成到他们的项目中,进行单元测试工作。 【标签】"Junit数据包"进一步明确了这...

    linux+nginx+tomcat+redis安装配置手册.docx

    本文档旨在提供一个全面的指南,用于在Linux环境下安装与配置Nginx、Tomcat以及Redis,并实现它们之间的协同工作。通过本手册,您将学习如何在Linux操作系统上搭建一套稳定且高效的Web服务环境。 #### 安装Nginx ...

    JUnit in Action

    《JUnit in Action》是一本专注于Java测试框架JUnit的权威指南,该书的PDF英文高清版在"JUnit in Action.rar"这个压缩包中。JUnit作为Java领域最常用的单元测试框架,对于软件开发人员尤其是Java开发者来说,是必备...

    junit4.8.2.zip(junit 整合包包括核心jar,文档,源代码,dep)

    压缩包中的文档可能包括用户指南、API参考文档和其他教程材料。这些文档可以帮助初学者快速理解如何使用Junit,包括如何创建测试类、编写测试方法,以及如何理解和解读测试结果。API参考通常会列出所有可用的类、...

Global site tag (gtag.js) - Google Analytics