Hamcrest使用
What is Hamcrest?
什么是Hamcrest?
??Hamcrest is a library of matchers, which can be combined in to create flexible expressions of intent in tests. They've also been used for other purposes.
??Hamcrest 是一個為了測試為目的,且能組合成靈活表達式的匹配器類庫。他們也被用于其他用途。?
Source
To build, please read BUILDING.txt
源碼的構建,請閱讀BUILDING.txt
Born in Java, Hamcrest now has implementations in a number of languages.
注意:因為我關注的是Java,所以我選擇的是Java Hamcrest,但是Hamcrest還有其它語言的版本。
官網截圖:
Java Hamcrest Binaries
上圖中我已經將紅框內的jar包全部下載下來了,CSDN的下載鏈接為:http://download.csdn.net/detail/fanxiaobin577328725/9658917
你也可以到上圖的鏈接下載:http://search.maven.org/#search|ga|1|g%3Aorg.hamcrest
explain
1. Introduction
??Hamcrest consists of different jars matching the different needs of applications. This document describes these distributables and the functionality contained in each of them.
??Hamcrest由不同的jar包來匹配應用程序的不同的需求。這篇文檔描述了這些包的功能和使用。
2. Overview of distributables
2.1. hamcrest-core.jar
??This is the core API to be used by third-party framework providers. This includes a foundation set of matcher implementations for common operations. This API is stable and will rarely change. You will need this library as a minimum.
??這是使用第三方框架所必須的核心API。這個Jar包中包含了一組基本的匹配器來執行一般的操作。這個API是穩定的,并且很少會改變。這是你所需要的最基本的庫。
2.2. hamcrest-library.jar
??The ever-growing library of Matcher implementations which are based on the core functionality in hamcrest-core.jar. This will grow between releases.
這是一個逐漸增加的匹配器庫,這些匹配器的實現是基于hamcrest-core.jar的核心功能。這將逐漸變化在releases版本之間。
2.3. hamcrest-generator.jar
??A tool to allow many Matcher implementations to be combined into a single class with static methods returning the different matchers so users don't have to remember many classes/packages to import. Generates code. This library is only used internally at compile time. It is not necessary for the use of any of the other hamcrest libraries at runtime.
??這是一個工具,允許實現多個匹配器組合成一個類并通過靜態方法返回不同的匹配器,因此使用者沒必要記住很多類/包的名稱來導入了。這個庫是在編譯時只在內部使用。在運行的時候沒有必要使用其他hamcrest庫。
2.4. hamcrest-integration.jar
??Provides integration between Hamcrest and other testing tools, including JUnit (3 and 4), TestNG, jMock and EasyMock. Uses hamcrest-core.jar and hamcrest-library.jar.
??在使用hamcrest-core.jar and hamcrest-library.jar這兩個包時,該包提供了它們和其他測試工具之間的集成,包括JUnit(3和4),TestNG,jMock和EasyMock。
2.5. hamcrest-all.jar
??One jar containing all classes of all the other jars.
??這一個Jar包包含了其它Jar包中的所有類。
2.6. Maven-Versions
??The description above also applies to the hamcrest Maven artifacts. The dependencies of the jars (hamcrest-integration uses hamcrest-library which uses hamcrest-core)is represented by the Maven dependency mechanism. There is no hamcrest-all library in the Maven repo. Just use hamcrest-integration which references all the other hamcrest libraries.
??上面所描述的Jar包同樣適用于Maven組件。這些Jar包的依賴性(hamcrest-integration依賴于hamcrest-library并且還依賴于hamcrest-core)可以使用Maven依賴機制。在Maven repo中沒有hamcrest-all這個庫。只使用hamcrest-integration引用其他hamcrest庫。
Source Repository
托管平臺網址:https://github.com/hamcrest/JavaHamcrest
Extensions
托管平臺網址:https://github.com/hamcrest/JavaHamcrest/wiki/Related-Projects
前言:下文是翻譯自Hamcrest官網Documentation的Getting Started,下文中藍色字體表示我還未翻譯,或者說翻譯不了的部分,如果哪位可以幫助翻譯一下,那真是萬分感謝。
The Hamcrest Tutorial(Hamcrest教程)
1. Introduction(介紹)
??Hamcrest is a framework for writing matcher objects allowing 'match' rules to be defined declaratively. There are a number of situations where matchers are invaluble, such as UI validation, or data filtering, but it is in the area of writing flexible tests that matchers are most commonly used. This tutorial shows you how to use Hamcrest for unit testing.
??本教程向您展示了如何使用hamcres進行t單元測試。
??When writing tests it is sometimes difficult to get the balance right between overspecifying the test (and making it brittle to changes), and not specifying enough (making the test less valuable since it continues to pass even when the thing being tested is broken). Having a tool that allows you to pick out precisely the aspect under test and describe the values it should have, to a controlled level of precision, helps greatly in writing tests that are "just right".Such tests fail when the behaviour of the aspect under test deviates from the expected behaviour, yet continue to pass when minor, unrelated changes to the behaviour are made.
??當編寫測試時,我們很難在編寫測試用例的時候保持很好的平衡。測試用例編寫的過于詳細會使得我們難以進行修改,測試用例編寫不詳細,會導致本不應該測試通過的情況通過了,這就導致測試失去了其價值。
2. My first Hamcrest test(第一個Hamcrest實例)
??We'll start by writing a very simple JUnit 3 test, but instead of using JUnit'sassertEquals methods,we use Hamcrest'sassertThat construct and the standard set of matchers, both of which westatically import:
??我們先寫一個簡單的JUnit3測試用例,但是我們不適用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)); }}??The assertThat method is a stylized sentence for making a testassertion. In this example, the subject of the assertion is the objectbiscuitthat is the first method parameter. The second method parameter is a matcher forBiscuitobjects, here a matcher that checks one object is equal to another using theObject equals method. The test passes since theBiscuitclass defines an equals method.
??assertThat方法是生成測試斷言的一個固定方法,在這個例子中,斷言的主體是assertThat方法的第一Biscuit對象參數,第二個參數是一個Biscuit對象的匹配器,這個匹配器(matcher)使用equals方法來檢查第一個對象是否等于另外一個對象。這個測試用例在Biscuit類定義了equals就可以通過測試。
下面是針對上面的一個自我測試:
源碼追蹤:(只截取了部分源碼)
MatcherAssert:
public class MatcherAssert { public static <T> void assertThat(T actual, Matcher<? super T> matcher) { assertThat("", actual, matcher); } public static <T> void assertThat(String reason, T actual, Matcher<? super T> matcher) { if (!(matcher.matches(actual))) { Description description = new StringDescription(); description.appendText(reason).appendText("\nExpected: ") .appendDescriptionOf(matcher).appendText("\n but: "); matcher.describeMismatch(actual, description); throw new AssertionError(description.toString()); } }.......}Matchers:
public class Matchers {....... public static <T> Matcher<T> equalTo(T operand) {?? ??? ?return IsEqual.equalTo(operand);?? ?}.......}IsEqual:
public class IsEqual<T> extends BaseMatcher<T> { private final Object expectedValue; public IsEqual(T equalArg) { this.expectedValue = equalArg; }....... public boolean matches(Object actualValue) {?? ??? ?return areEqual(actualValue, this.expectedValue);?? ?}....... private static boolean areEqual(Object actual, Object expected) {?? ??? ?if (actual == null) {?? ??? ??? ?return (expected == null);?? ??? ?} ?? ??? ?if ((expected != null) && (isArray(actual))) {?? ??? ??? ?return ((isArray(expected)) && (areArraysEqual(actual, expected)));?? ??? ?} ?? ??? ?return actual.equals(expected);?? ?}........ ?? ?public static <T> Matcher<T> equalTo(T operand) {?? ??? ?return new IsEqual(operand);?? ?}......}執行過程:myBiscuit先傳遞給equalTo(),然后又傳遞給了IsEqual.equalTo(),然后根據myBiscuit構造一個IsEqual(暫稱為M),并將M返回給assertThat(),assertThat()方法又調用M.matches(theBiscuit )來進行比較,然而M將theBiscuit傳遞給了areEqual()方法,M的areEqual()調用的就是theBiscuit的equals()方法來進行比較myBiscuit的。
饒了一大圈,總的來說就是:比較這兩個對象就是調用第一個參數的equals()方法,所以第一個參數的equals()方法的比較方式決定了這個斷言是否通過。
??If you have more than one assertion in your test you caninclude an identifier for the tested value in the assertion:
??如果你有多個斷言在你的測試中,你可以為你的每個斷言聲明一個標識符,這樣出錯也會知道是那個斷言拋出了。
3. Other test frameworks(其它測試框架)
?
??Hamcrest has been designed from the outset to integrate with different unit testing frameworks. For example, Hamcrest can be used with JUnit 3 and 4 and TestNG. (For details have a look at the examples that come with the full Hamcrest distribution.) It is easy enough to migrate to using Hamcrest-style assertions in an existing test suite, since other assertion styles can co-exist with Hamcrest's.
??Hamcrest從一開始就設計成與不同的單元測試框架的進行整合,例如Hamcrest可以與JUnit 3和4 以及TestNG進行整合。(更多細節可以參考come with the full Hamcrest distribution)這就很容易遷移到現有的使用Hamcrest格式的測試框架,只要框架的斷言可以與Hamcrest的斷言共存。
??Hamcrest can also be used with mock objects frameworks by using adaptors to bridge from the mock objects framework's concept of a matcher to a Hamcrest matcher. For example, JMock 1's constraints are Hamcrest's matchers. Hamcrest provides a JMock 1 adaptor to allow you to use Hamcrest matchers in your JMock 1 tests. JMock 2 doesn't need such an adaptor layer since it is designed to use Hamcrest as its matching library. Hamcrest also provides adaptors for EasyMock 2.Again, see the Hamcrest examples for more details.
??Hamcrest也可以通過適配器來適配mock objects(模擬對象)框架的匹配器,例如,JMock 1的約束是Hamcrest的匹配器,JMock 2就不需要這樣一個適配器層,只要其被設計為使用Hamcrest作為其匹配庫。Hamcrest也為EasyMock 2提供了適配器。
4. A tour of common matchers(常見的匹配器)
Hamcrest comes with a library of useful matchers. Here are some of the most important ones.
Hamcrest自帶了一個有用的匹配器庫。下面是主要的幾個:
Core
- anything - always matches, useful if you don't care what the object under test is
- describedAs - decorator to adding custom failure description
- is - decorator to improve readability - see "Sugar", below
?Logical
- allOf - matches if all matchers match, short circuits (like Java &&)
- anyOf - matches if any matchers match, short circuits (like Java ||)
- not - matches if the wrapped matcher doesn't match and vice versa
Object
- equalTo - test object equality using Object.equals
- hasToString - test Object.toString
- instanceOf, isCompatibleType - test type
- notNullValue, nullValue - test for null
- sameInstance - test object identity
?Beans
- hasProperty - test JavaBeans properties
?Collections
- array - test an array's elements against an array of matchers
- hasEntry, hasKey, hasValue - test a map contains an entry, key or value
- hasItem, hasItems - test a collection contains elements
- hasItemInArray - test an array contains an element
Number
- closeTo - test floating point values are close to a given value
- greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo - test ordering
Text
- equalToIgnoringCase - test string equality ignoring case
- equalToIgnoringWhiteSpace - test string equality ignoring differences in runs of whitespace
- containsString, endsWith, startsWith - test string matching
5. Sugar
??Hamcrest strives to make your tests as readable as possible. For example, theis matcher is a wrapper that doesn't add any extra behavior to the underlying matcher. The following assertions are all equivalent:
??Hamcrest致力于增強測試用例的可讀性。例如, 匹配器是一個包裝,不添加任何額外的底層匹配器。下面的斷言的作用是完全相同的:
assertThat(theBiscuit, equalTo(myBiscuit)); assertThat(theBiscuit, is(equalTo(myBiscuit))); assertThat(theBiscuit, is(myBiscuit));??The last form is allowed since is(T value) is overloaded to return is(equalTo(value)).
??最后一種方式
6. Writing custom matchers(編寫自定義的匹配器)
??Hamcrest comes bundled with lots of useful matchers, but you'll probably find that you need to create your own from time to time to fit your testing needs. This commonly occurs when you find a fragment of code that tests the same set of properties over and over again (and in different tests), and you want to bundle the fragment into a single assertion. By writing your own matcher you'll eliminate code duplication and make your tests more readable!
??Hamcrest綁定了許多有用的匹配器,但是有時候我們需要創建自己的匹配器來滿足我們測試的需要。這種情況通常發生在我們使用一段代碼片段并且反復測試相同的屬性集(在不同的測試中),我們又想把這個代碼片段打包成一個斷言。通過編寫自己的匹配器我們會減少代碼的重復性,使測試更加具有可讀性!
??Let's write our own matcher for testing if a double value has the value NaN (not a number). This is the test we want to write:
??如果double類型的之有NaN值(不是一個數字),讓我們為這種情況寫一個我們自己的匹配器,。下面使我們想寫的測試:
And here's the implementation:
下面是其實現:
?
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{ public boolean matchesSafely(Double number){ return number.isNaN(); } public void describeTo(Description description){ description.appendText("not a number"); } public static Matcher notANumber(){ return new IsNotANumber(); }}??The assertThat method is a generic method which takes aMatcher parameterized by the type of the subject of the assertion. We are asserting things about Double values, so we know that we need a Matcher<Double>. For our Matcher implementation it is most convenient to subclass TypeSafeMatcher,which does the cast to a Double for us. We need only implement thematchesSafely method - which simply checks to see if the Double is NaN - and the describeTo method - which is used to produce a failure message when a test fails. Here's an example of how the failure message looks:
??assertThat方法是一個通用的匹配方法,其需要一個匹配器類型的參數,而這個參數是一個斷言的形式。我們匹配的是一個Double類型的值,所以我們需要一個Matcher<Double>的匹配器。我們的匹配器繼承TypeSafeMatcher是最為方便的,這樣我們就可以測試Double這種情況了。我們只需要復寫matchesSafely ()方法(這個方法就是簡單檢查Double值是否是NaN),describeTo ()方法是用來產生一個測試失敗時失敗消息的。下面的例子就是演示錯誤信息的顯示地:
fails with the message(失敗的信息)
java.lang.AssertionError: Expected: is not a number got : <1.0>??The third method in our matcher is a convenience factory method. We statically import this method to use the matcher in our test:
??我們匹配器中的第三種方法就是一個方便的工廠方法。在測試中我們通過靜態導入這個方法的方式來使用我們的匹配器:
??Even though the notANumber method creates a new matcher each time it is called, you should not assume this is the only usage pattern for your matcher. Therefore you should make sure your matcher is stateless,so a single instance can be reused between matches.
??即使notANumber()方法在每次被調用的時候都會創建一個新的匹配器,你不應該認為這是唯一使用的模式匹配器。因此我們應該確保我們的匹配器是stateless,因此單獨的實例可以再多個匹配器間重復使用。
6. Sugar generation
??If you produce more than a few custom matchers it becomes annoying to have to import them all individually. It would be nice to be able to group them together in a single class, so they can be imported using a single static import much like the Hamcrest library matchers. Hamcrest helps out here by providing a way to do this by using a generator.
??如果你定義了很多自定義的匹配器,這會導致我們必須分別的單獨導入它們,這讓人很煩惱。最好是把它們組織到一個類中,這樣它們就可以像導入Hamcrest匹配器庫一樣,靜態導入這一個類就可以了。Hamcrest提供了一種方式來完成這種情況,那就是使用一個generator。
??First, create an XML configuration file listing all the Matcher classes that should be searched for factory methodsannotated with the org.hamcrest.Factory annotation. For example:
??首先,創建一個XML的配置文件來羅列出我們所有的匹配器類應該尋找的工廠方法(),如下面的例子:(官網上是空的)
??Second, run the org.hamcrest.generator.config.XmlConfigurator command-line tool that comes with Hamcrest. This tool takes the XML configuration file and generates a single Java class that includes all the factory methods specified by the XML file. Running it with no arguments will display a usage message. Here's the output for the example.
??第二步運行,在控制臺運行org.hamcrest.generator.config.XmlConfigurator。這個工具將根據XML配置文件生成一個Java類,其包含了所有的XML文件中指定的工廠方法。不帶參數的運行它,將會顯示一個使用信息,這里有一個輸出的例子:
Finally, we can update our test to use the new Matchers class.
最后,我們可以更新我們的測試用例,來使用新定義的匹配器類了。
Notice we are now using the Hamcrest library is matcher imported from our own custom Matchersclass.
請注意我們現在使用Hamcrest庫是我們自定義的匹配器類進口匹配器。
7. Where next?
See FurtherResources.
參考資料:
- JUnit4---Hamcrest匹配器常用方法總結
轉載于:https://www.cnblogs.com/jpfss/p/10955919.html
總結
以上是生活随笔為你收集整理的Hamcrest使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hadoop配置和启动
- 下一篇: [网站seo优化] 史上最全增加外链的方