This article is a complete guide to using Hamcrest matchers. You will also learn how to use Hamcrest matchers effectively in software testing.
Let’s dive in
Introduction
It turns out that the word “Hamcrest” is an anagram of the word “Matchers”! That means that we cannot define Hamcrest without first introducing matchers.
A matcher is an object that allows “match” rules to be defined declaratively. You can think of a matcher as a way to make assertions in a program.
Therefore, Hamcrest is a framework for writing matcher objects. We use the assertThat method to make test assertions.
Hamcrest vs TestNG
You are probably wondering if Hamcrest can be a substitute for TestNG or whether one is better than the other. It turns out that although both do similar things, one cannot substitute the other entirely.

TestNG is a testing framework; as noted above, Hamcrest is a matcher framework. Both frameworks allow us to make assertions; it is here where Hamcrest does a better job than TestNG.
Hamcrest is very useful for UI validation and data filtering. Most importantly, Hamcrest allows your tests to be self-documenting since it focuses on what your code should do instead of what it is doing. Let’s look at some examples.
Code readability
Here, we have an array of strings.
String[] primaryColors = {"red", "green", "blue"};
In order to verify that this array has a certain value, we would write a TestNG assertion similar to this:
Assert.assertTrue(Arrays.asList(primaryColors).contains("blue"));
Meanwhile, using Hamcrest, we would write something like this:
assertThat(primaryColors, hasItemInArray("blue"));
Notice that Hamcrest allows us to focus on the ‘what’ rather than the ‘how’. This results in code that is easier to write and understand.
Self-documenting code
Hamcrest allows us tremendous flexibility to write code that essentially needs no documentation. Remember that your documentation is only good until the next code change!
Take, for example, the following statements.
String pageTitle = "Home";
assertThat(pageTitle, equalTo("Home"));
assertThat(pageTitle, is("Home"));
assertThat(pageTitle, is(equalTo("Home")));
All of the above will result in a passing test. In the case of is(“Home”), it passes because it is an overloaded method that returns is(equalTo(“Home”)).
Making assertions in this way requires no explanation of what your code is doing since it speaks for itself.
Better error messages
Perhaps the most compelling feature of using Hamcrest matchers is the type of error messages that it provides out of the box.
Let us assume that we have the following list.
List<Integer> fibonacci = Arrays.asList(0,1,1,2,3,5,8);
If we perform the following assertion,
assertThat(fibonacci, hasSize(5));
we get the following error.
java.lang.AssertionError:
Expected: a collection with size <5>
but: collection size was <7>
Compare that to using the following TestNG assertion.
Assert.assertEquals(fibonacci.size(), 5);
The error message that is displayed is as follows.
java.lang.AssertionError: expected [5] but found [7]
Expected :5
Actual :7
This error message is not very helpful when trying to debug our code.
You might say, that’s fine, but TestNG allows me to provide my error message as in the following example.
Assert.assertEquals(fibonacci.size(), 5, "the list size did not equal 5");
This results in this error message.
java.lang.AssertionError: the list size did not equal 5 expected [5] but found [7]
Expected :5
Actual :7
The point is that with Hamcrest we do not need to provide our error message if we do not want to; any errors that may occur will still provide handy information.
So, how do we provide our error message using Hamcrest? Easy, we use the describeAs method.
assertThat(fibonacci, describedAs("the list size to be equal to 5", hasSize(5)));
The error message looks like this.
java.lang.AssertionError:
Expected: the list size to be equal to 5
but: collection size was <7>
Better enforcement of type safety
Another nice thing about using Hamcrest matchers is its better handling of type safely. If we were to write the following code using a framework such as TestNG,
Assert.assertEquals("abc", 123);
the code will compile, but it will fail at runtime. Meanwhile, if we write a similar code using Hamcrest,
assertThat(123, is("abc"));
the code will not compile since it knows that we are trying to compare an int type to a String type object.
Custom Hamcrest matchers
Hamcrest has another powerful feature that allows us to write our custom matchers. Doing so permits the creation of our very own DSL (Domain Specific Language) if we so choose.
We have written another article that covers Hamcrest custom matchers in more detail.
Common Hamcrest matchers
Here is a list of some of the most common Hamcrest matchers.
allOf – this functions as the logical ‘&&’ operator in Java, which matches if all the matchers match.
String email = "info@automatenow.io";
assertThat(email, allOf(startsWith("info"), containsString("@"), endsWith(".io")));
anyOf – this functions as the logical ‘||’ operator in Java, which matches if any of the matchers match.
assertThat(email, anyOf( endsWith(".io"), endsWith(".dev"), endsWith(".com")));
equalTo – used to test object equality using Object.equals
assertThat(“Home page”, equalTo(“Home page”));
hasToString – used to test Object.toString
assertThat(true, hasToString(equalTo("true")));
hasKey, hasValue – checks to see if a map contains a given key or value
HashMap<Integer, String> binary = new HashMap<Integer, String>();
binary.put(1, "on");
assertThat(binary, hasKey(1));
assertThat(binary, hasValue("on"));
Getting started with Hamcrest
Now that we have seen how convenient Hamcrest matchers are, you may be wondering how to start using them in your automation project.
Hamcrest’s original design was for testing Java applications, but it has since been ported over to other programming languages. For instance, there is PyHamcrest for Python, NHamcrest for .NET, OCHamcrest for Objective-C, etc.

If you happen to be using a Java Maven project, you can add the following Maven dependency.
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>enter_version_here</version>
<scope>test</scope>
</dependency>
Click here to see the latest version.
You can find the source code for all the examples listed in this post by visiting the automateNow GitHub page.
References
Follow our blog
Be the first to know when we publish new content.
How we can know that our hamcrest ran successfully.
Thanks for your question, Chetan.
You will know that your Hamcrest assertions passed when you see that your tests containing the assertions pass. On the other hand, if a Hamcrest assertion fails, you will see an AssertionError and the test containing the assertion will fail.