crafting code.

Marc Philipp

Fork me on GitHub

Hamcrest Quick Reference

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.

Pecha Kucha: Software Craftsmanship

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.

Interview with Uncle Bob

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 meantime, the interview has been published in print in the VKSI Magazine (PDF, German) and as a video on YouTube.

Using DbUnit Without XML

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:

dataset.xml
1
2
3
4
5
<dataset>
  <PERSON NAME="Bob" LAST_NAME="Doe" AGE="18"/>
  <PERSON NAME="Alice" LAST_NAME="Foo" AGE="23"/>
  <PERSON NAME="Charlie" LAST_NAME="Brown" AGE="42"/>
</dataset>

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.

JUnit Rules

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.

Primitive Matt(ch)ers?

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
@Test
public void onePlusOneIsTwo() {
    assertThat(1 + 1, is(2));
}

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
@Test
public void onePlusOneIsTwo() {
    assertThat(Integer.valueOf(1 + 1), is(Integer.valueOf(2)));
}

However, this is not readable anymore!

Why do we need boxing in the first place?

When using assertThat() we need boxing for two reasons. First, there is no definition of assertThat() for primitive types, only for reference types:

1
<T> void assertThat(T actual, Matcher<T> matcher)

Well, why don’t we overload assertThat() with separate method definitions for each primitive type, you might say.

1
void assertThat(int actual, Matcher<int> matcher)

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
void assertThat(int actual, Matcher<Integer> matcher) {
    assertThat(Integer.valueOf(actual), matcher);
}

Without using auto boxing, we can now write:

1
2
3
4
@Test
public void onePlusOneIsTwo() {
    assertThat(1 + 1, is(Integer.valueOf(2)));
}

That solves half of our problem: We got rid of the first boxing by overloading assertEquals(). However, we still need to explicity convert our int to Integer when calling the matcher factory method. Thus, we also need to overload the is() method:

1
2
3
Matcher<Integer> is(int value) {
    return is(Integer.valueOf(value));
}

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 unrestricted 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
Matcher<Byte> is(byte value) {
    return is(Byte.valueOf(value));
}
Matcher<Short> is(short value) {
    return is(Short.valueOf(value));
}
Matcher<Integer> is(int value) {
    return is(Integer.valueOf(value));
}
Matcher<Long> is(long value) {
    return is(Long.valueOf(value));
}
Matcher<Float> is(float value) {
    return is(Float.valueOf(value));
}
Matcher<Double> is(double value) {
    return is(Double.valueOf(value));
}
Matcher<Boolean> is(boolean value) {
    return is(Boolean.valueOf(value));
}
Matcher<Character> is(char value) {
    return is(Character.valueOf(value));
}

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
Matcher<Integer> zero(int value) {
    return zero(Integer.valueOf(value));
}

Summing up, it would be great if Hamcrest provided built-in support for primitive types.

Update

My proposal was rejected by the Hamcrest maintainers.

Combining SuiteBuilder and ClasspathSuite

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
@RunWith(Suite.class)
@SuiteClasses({
    SomeTest.class,
    YetAnotherTest.class
})
public class AllTests {}

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
@RunWith(ClasspathSuite.class)
@IncludeJars(true)
@ClassnameFilters({".*Test", "!.*AllTests"})
@BaseTypeFilter(MyBaseTest.class)
public class AllTests {}

However, the 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 @IncludeCategory and @ExcludeCategory, the SuiteBuilder offers a more flexible alternative.

Introducing SuiteBuilder

The 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 SuiteBuilder:

1
2
3
4
5
6
@RunWith(SuiteBuilder.class)
public class AllTests {
    @Classes
    public Listed classes =
        new Listed(SomeTest.class, YetAnotherTest.class);
}

In addition, you can filter the resulting test runners by annotating a field of type SuiteBuilder.RunnerFilter.Value with @RunnerFilter. For example, the latest commit included a CategoryFilter that filters tests by category:

1
2
3
4
5
6
7
8
9
@RunWith(SuiteBuilder.class)
public class OnlyYes {
    @Classes
    public Listed classes =
        new Listed(SomeTest.class, YetAnotherTest.class);

    @RunnerFilter
    public CategoryFilter filter = CategoryFilter.include(Yes.class);
}

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
@RunWith(SuiteBuilder.class)
public class OnlyYes {
    @Classes
    public InClasspath classes = new InClasspath();

    @RunnerFilter
    public CategoryFilter filter = CategoryFilter.include(Yes.class);
}

The wrapper offers the same flexibility as the ClasspathSuite, e.g.:

1
2
3
4
5
6
7
8
9
10
@RunWith(SuiteBuilder.class)
public class OnlyYes {
    @Classes
    public InClasspath classes = new InClasspath().includingJars()
            .filteredBy(".*Test", "!.*AllTests")
            .includingOnlySubclassesOf(MyBaseTest.class);

    @RunnerFilter
    public CategoryFilter filter = CategoryFilter.include(Yes.class);
}

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 InClasspath class.

Update

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.

Applying DRY to JUnit Categories

Long awaited, JUnit 4.8 introduced support for categorizing test cases.

A category marker is simply a class or interface, e.g.

1
public interface SlowTests {}

Tests can be marked using the @Category annotation:

1
2
3
4
5
6
7
8
public class A {
    @Test
    public void a() {}

    @Category(SlowTests.class)
    @Test
    public void b() {}
}

The annotation works both on methods and classes:

1
2
3
4
5
@Category(SlowTests.class)
public class B {
    @Test
    public void c() {}
}

Test suites that include or exclude the SlowTests category are defined by specifying the Categories runner and using the @ExcludeCategory or @IncludeCategory annotation, respectively:

1
2
3
4
5
6
7
8
9
@RunWith(Categories.class)
@SuiteClasses( { A.class, B.class })
@ExcludeCategory(SlowTests.class)
public class AllFastTests extends AllTests {}

@RunWith(Categories.class)
@SuiteClasses( { A.class, B.class })
@IncludeCategory(SlowTests.class)
public class AllSlowTests extends AllTests {}

In this example, AllFastTests would execute only A.a while AllSlowTests would ignore A.a but run A.b and B.c.

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
@RunWith(Suite.class)
@SuiteClasses( { A.class, B.class })
public class AllTests {}

… and declare subclasses that filter the list of classes by category:

1
2
3
4
5
6
7
@RunWith(Categories.class)
@ExcludeCategory(SlowTests.class)
public class AllFastTests extends AllTests {}

@RunWith(Categories.class)
@IncludeCategory(SlowTests.class)
public class AllSlowTests extends AllTests {}

Generic Matcher Pitfalls

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
@Factory
public static <E> Matcher<Collection<E>> empty() {
    return new IsEmptyCollection<E>();
}

Great, I thought. So I readily changed our tests to use the pre-defined matcher…

1
assertThat(new TreeSet<String>(), empty());

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:

1
assertThat(new TreeSet<String>(), Matchers.<String>empty());

But that looked horrible. My first shot was to define an own factory method…

1
2
3
4
@Factory
public static <E> Matcher<Collection<E>> emptyOf(Class<E> clazz) {
    return new IsEmptyCollection<E>();
}

…that can be used like this:

1
assertThat(new TreeSet<String>(), emptyOf(String.class));

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
public class IsEmptyCollection extends TypeSafeMatcher<Collection<?>> {

    @Override
    protected boolean matchesSafely(Collection<?> collection) {
        return collection.isEmpty();
    }

    public void describeTo(Description description) {
        description.appendText("empty");
    }

    @Factory
    public static Matcher<Collection<?>> empty() {
        return new IsEmptyCollection();
    }
}

In conclusion, I think it is not trivial to write usable generic matchers. Therefore, avoid generics when you don’t need them!