Recently, we have released JUnit 4.11 which now uses the latest version of Hamcrest (1.3). Being finally able to (easily) use the power of a recent version of the matchers that come with hamcrest-core and hamcrest-library along with JUnit, I have been looking for a decent-looking printable quick reference of available matchers. Since I wasn’t able to find any, I have decided to create my own.
A little more than a month ago I spoke at the Entwicklertag in Karlsruhe about Software Craftsmanship. More precisely, I gave my very first Pecha Kucha on my understanding of the principles and ethics behind it. Along with several others, my talk was recorded and is now available on YouTube.
Since the slides are a little hard to see in the video, I have uploaded them to SpeakerDeck.
A couple of weeks ago I had the pleasure to participate in Uncle Bob’s Clean Code course in Karlsruhe. Afterwards, I interviewed him together with Susann Mathis on Software Craftsmanship and professionalism in software development.
In the previous post we have seen how to use DbUnit to write a simple database test. By using DbUnit for this purpose, we were able to insert a complete dataset into the database without writing SQL. However, we had to use XML to specify the dataset:
1 2 3 4 5
Now, you can think about XML what you want but I (and hopefully most people) would rather not want to write such files but instead create the dataset directly in the code of the test class. As it turns out, this is very hard using plain DbUnit.
DataSetBuilder to the rescue
So, I thought, wouldn’t it be nice to have a builder for datasets with an easy-to-use API? Thus, I sat down and wrote DataSetBuilder for DbUnit.
Inspired by a recent blog post and presentation by Jens Schauder, this blog posts starts a series of posts about using DbUnit for database and integration tests. In addition, I will talk about Database Tests with DbUnit at ObjektForum Karlsruhe in April. This first post introduces DbUnit and demonstrates how it can be used to write database tests.
Marc Philipp, andrena objects ag
Stefan Birkner, Immobilien Scout GmbH
Erschienen in Java aktuell, 1/2012, dem Magazin der iJUG.
Automatisierte Tests sind aus der heutigen Softwareentwicklung nicht mehr wegzudenken. JUnit ist das älteste und bekannteste Testing-Framework für Java. Doch selbst ein so etabliertes und einfach zu benutzendes Framework wird kontinuierlich weiterentwickelt. Eine der Neuerungen sind JUnit Rules, die Entwicklern eine neue mächtige Möglichkeit bieten, Tests zu formulieren und besser zu strukturieren.
The Hamcrest project provides a large number of matchers, i.e. declaratively defined predicates. Prominent uses of these matchers include testing and mocking libraries like JUnit and jMock, respectively.
How to use them?
1 2 3 4
While the above example is simple, it demonstrates one of the benefits of using
assertThat() and Hamcrest matchers: assertions become very readable. Unfortunately, you often have to rely on a questionable Java mechanism: auto boxing/unboxing.
Auto boxing and unboxing have been introduced in Java 5 to ease the use of primitive types and their counterparts: real objects (a.k.a. reference types). However, especially unboxing can lead to hidden NullPointerExceptions and thus is discouraged by many developers. For details see Autoboxing is Evil by Nicole Rauch and Andreas Leidig.
For this reason, the Eclipse Java compiler optionally shows warnings whenever boxing or unboxing occurs. While it is certainly a good idea to enable this warning, it also puts markers on code that is perfectly sane, like the test case above. To prevent un-/boxing and use matchers at the same time, one can go back to pre-Java 5 times and convert the primitive literals explicitly:
1 2 3 4
However, this is not readable anymore!
Why do we need boxing in the first place?
assertThat() we need boxing for two reasons. First, there is no definition of
assertThat() for primitive types, only for reference types:
Well, why don’t we overload
assertThat() with separate method definitions for each primitive type, you might say.
Java’s generics do not allow primitive types like
int as type arguments, only reference types are allowed.
Hmm, anything we can do?
Yes! So how about
1 2 3
Without using auto boxing, we can now write:
1 2 3 4
That solves half of our problem: We got rid of the first boxing by overloading
assertEquals(). However, we still need to explicity convert our
Integer when calling the matcher factory method. Thus, we also need to overload the
1 2 3
Problem solved! Really? Obviously, it requires a lot of work do define extra matcher factory methods for every combination of primitive type and matcher.
Solution: generate it!
Hamcrest already allows to generate matcher libraries, i.e. classes that collect all static factory methods for easy access at a single entry point. So, we could simply generate extra methods for every matcher. To stay with the example from above, if we have an
Matcher<T>, we would generate the following eight overloading methods:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
A matcher declaration which uses the object representation of a primitive type, e.g.
Matcher<Integer>, is a special case that is even more simple. We would only need to generate a single extra method, such as
1 2 3
Summing up, it would be great if Hamcrest provided built-in support for primitive types.
My proposal was rejected by the Hamcrest maintainers.
In a recent commit to JUnit Kent Beck and David Saff have added an “alpha-ready implementation of
SuiteBuilder”. As Kent Beck previously described in a blog post, the idea behind the
SuiteBuilder runner is to use annotations on fields instead of annotations on classes.
Limitations of regular test suites
While an annotation can take parameters the arguments must be literals, e.g. constant String values or class literals. For example, the classic
Suite runner is configured using the
@SuiteClasses annotation that takes an array of class literals, i.e. the test classes to be run:
1 2 3 4 5 6
Literals have a severe limitation: they must be know at compile-time! Thus, when using the
Suite runner, there was no way of determining the classes to run by any other means such as scanning the current classpath.
ClasspathSuite to the rescue
For this original purpose, Johannes Link created the
ClasspathSuite runner. Its basic usage is very simple: just specify it using the
@RunWith annotation. In addition, you can also include test classes in JAR files, filter by class names or types, and so on:
1 2 3 4 5
ClasspathSuite does not support JUnit’s categories as mentioned in an earlier blog post. While it could certainly be extended to support the Category-related annotations
SuiteBuilder offers a more flexible alternative.
SuiteBuilder runner is similar to the
Suite runner, but reads the test classes it is supposed to run from a field of the suite class annotated with
@Classes. The field can be freely initialized to hold an implementation of the
SuiteBuilder.Classes.Value interface which simply wraps a collection of classes. E.g., the first example can be rewritten using the
1 2 3 4 5 6
In addition, you can filter the resulting test runners by annotating a field of type
@RunnerFilter. For example, the latest commit included a
CategoryFilter that filters tests by category:
1 2 3 4 5 6 7 8 9
Putting the pieces together
So what? Well, instead of specifying the classes explicitly you could employ the capabilities of the
ClasspathSuite to determine the test classes dynamically. For this purpose, I have written a small wrapper around Johannes Links’
ClasspathSuite. The above example can thus be rewritten without explicitly specifying the test classes:
1 2 3 4 5 6 7 8
The wrapper offers the same flexibility as the
1 2 3 4 5 6 7 8 9 10
While I will look into how this can be integrated into JUnit or ClasspathSuite feel free to contact me if you are interested in the source code of the
I am currently working on integrating ClasspathSuite and InClasspath into core JUnit… In the meantime, you can take a look at the code on GitHub.
Long awaited, JUnit 4.8 introduced support for categorizing test cases.
A category marker is simply a class or interface, e.g.
Tests can be marked using the
1 2 3 4 5 6 7 8
The annotation works both on methods and classes:
1 2 3 4 5
Test suites that include or exclude the
SlowTests category are defined by specifying the
Categories runner and using the
@IncludeCategory annotation, respectively:
1 2 3 4 5 6 7 8 9
In this example,
AllFastTests would execute only
AllSlowTests would ignore
A.a but run
However, there is a major issue in the above suite declarations: they violate the DRY principle. Both test suites list all test classes in the
@SuiteClasses annotation. While it seems feasible to maintain the list of test classes at two locations for a small number of classes, it certainly is not a viable option in a real-world setting, especially when there are multiple categories.
Fortunately, there is a simple solution: use inheritance. You can define the list of test classes once in a normal test suite …
1 2 3
… and declare subclasses that filter the list of classes by category:
1 2 3 4 5 6 7
Using Hamcrest matchers in combination with
assertThat allows for more fluid specification of JUnit assertions.
Recently, while working on the backend of Project Usus, we needed a simple matcher, that would test whether a given set is empty. At the time, we reused a set matcher we had already written a few minutes earlier.
Today, I had another look at the pre-defined matchers that come with Hamcrest and found the
empty() matcher in
org.hamcrest.Matchers. Since I’m not concerned with the actual implementation (at least for now), I’ll just give you the factory method:
1 2 3 4
Great, I thought. So I readily changed our tests to use the pre-defined matcher…
However, this yielded a compile error because the compiler could not infer the type parameter of the method. It did work when stating the type parameter of the static method explicitly:
But that looked horrible. My first shot was to define an own factory method…
1 2 3 4
…that can be used like this:
I was still not very pleased with the solution. Even more since it does not matter at all what kind of objects are inside the collection to determine whether it is empty. After playing around for a little while I came up with this solution:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
In conclusion, I think it is not trivial to write usable generic matchers. Therefore, avoid generics when you don’t need them!