Testing Bliss: Hamcrest Matchers

Part 2 of my testing rant – Hamcrest!

I love hamcrest because it makes my life easier. Instead of writing loops to verify a collection or horrible string matches regex in a assertTrue() method, I can use hamcrest to write a clean and concise assertion. When you write an assertion using hamcrest, it reads like a simple statement; “Assert that value is not null” or “Assert that collection has item”.

Of course there are plenty of other articles and tutorials that cover how to use hamcrest, but there are several features that are not covered particularity well by any of them and it can be hard to find documentation on some of the more advanced matchers.

Hamcrest Basics

The heart of hamcrest is the assertThat() method. The assertion accepts a value and a set of matchers, if the matchers can be applied to the value (i.e., they match) then the assertion passes. You’ll use this assertion for all your hamcrest tests as the assert relies on the matchers you supply to define the check and validation.

The most basic matcher is equalTo(), or it’s shorter, easier to read alias is(). The equalTo() matcher can be used just like the old assertEquals() assertion, but it’s power will really shine through later when combined with other matchers.


import org.testng.annotations.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

@Test
public class HamcrestTest {

    @Test
    public void equality {
        String value = "abc";

        assertThat(value, equalTo("abc"));
        assertThat(value, is("abc"));
    }
}


Logical Matchers

One of the nice things about hamcrest matchers is that you can use some logical operators to modify or group multiple matchers under a single assertion.

  • not() – negate a matcher
  • allOf() – pass assertion if all matcher conditions pass
  • anyOf() – pass assertion if any matcher conditions pass

@Test
public void logicalOperators {
    String value = "abc";
  
    // pass if condition does not match
    assertThat(value, not(is("123"))); 

    // pass if all of the conditions match
    assertThat(value, allOf(startsWith("a"), endsWith("c"));

    // pass if any of the conditions match
    assertThat(value, anyOf(is("abc"), is("def"), is(not("123")));
}


Text Pattern Matchers

With the hamcrest-text library you can build pattern matching expressions for complex string matching using the PatternMatcher. Text matching is also included with hamcrest-all, but beware that it’s omitted from the matchers that are included with TestNG.

You might be thinking that a Regular Expression can already be used for this purpose, but what what you gain in a regex power you lack in it’s clarity (you maybe strong in the Regex-fu, but what about your co-workers?). On the other hand, a hamcrest matcher is VERY clear and easy to read.


import org.testng.annotations.Test;
import org.hamcrest.text.pattern.PatternMatcher;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.text.pattern.PatternMatcher.*;
import static org.hamcrest.text.pattern.Patterns.*;

@Test
public class PatternMatcherTest {

    PatternMatcher alphanumeric = new PatternMatcher(
            oneOrMore(
                    either(anyCharacterIn("0-9"),
                           anyCharacterIn("A-Z"),
                           anyCharacterIn("a-z"), 
                    )
            )
    );

    @Test
    public void textMatching {
        // string matches alphanumeric pattern
        assertThat("abc123", matchesPattern(alphanumeric)); 

        // string does NOT match alphanumeric pattern
        assertThat("abc 123 !@#$", not(matchesPattern(alphanumeric));
    }
}


Collection Matchers

The trick with collection matchers is that you can’t use the static imports with matchers that have a generic type. To get the full effect, you need to use the fully qualified path with the generic type on the Matcher classes static method.


@Test
public void collections() {
    List list = Arrays.asList("a string", "another", "more strings");

    // list contains "a string"
    assertThat(list, Matchers.<String>hasItem("a string"));

    // list contains one of many possible items
    assertThat(list, anyOf(Matchers.<String>hasItem("a string"), Matchers.<String>hasItem("splort!"));
}


JavaBeans Property Matchers

JavaBeans property matchers are useful for verifying properties of complex types for matching. It’s exceptionally useful to verify the properties of complex types in a list, where normally you would need to iterate through the entire collection.

The syntax for the hasProperty() matcher is different than your average matcher too. The matcher itself takes the name of the property and another matcher for verifying the value.


public class Car {
    private String make;
    private String colour;

     // getters and setters omitted ...
}

@Test
public void bean() {
    Car car = new Car("Subaru", "blue");

    assertThat(car, Matchers.<Car>hasProperty("make", is("Subaru"));
}

@Test
public void beanList() {
    List<Car> cars = Arrays.asList(new Car("Subaru", "blue"), new Car("Mazda", "red"));

    // list of cars contains a Subaru
    assertThat(cars, hasItem(Matchers.<Car>hasProperty("make", is("Subaru")));    

    // list of cars contains a car that's red
    assertThat(cars, hasItem(Matchers.<Car>hasProperty("colour", is("red")));    
}

Testing Bliss: TestNG

Woo! Testing!

Ok, so testing honestly isn’t exciting. But it is essential, and if you use the right tool it can be quick and easy too.

I completely understand the frustration of many developers who insist that testing just wastes valuable time. Many are stuck using old-school, poorly written testing frameworks that are not as intuitive as they should be. These old frameworks use naming patterns instead of annotations, offer very little in the way of control in how your tests are run (such as running certain tests in a sequence, or easily grouping tests into functional, integration, and unit test suites) and often require you to override base methods to get the desired functionality. If you haven’t guessed it, I’m pointing the giant foam finger of blame at JUnit 3.x.

Even though JUnit 3.x was originally a de-facto standard and a godsend to testing; it’s a horrible framework by today’s standards. JUnit 4 is marginally better, replacing naming patterns and method overrides for annotations, but it still offers little in the way of configuration and control and lacks any major improvement over its predecessor.

Because of this, I’ve turned to TestNG for my all of my current projects. I won’t get into a full comparison between TestNG and JUnit 4 because it’s already been done to death by others, but I will list a few of my favourite features:

  • Named groups for organising test cases.
  • Ability to re-run failed tests without running the entire suite.
  • Individual test dependencies (i.e., a test can depend on the outcome of another).
  • Test fixture support using Data Providers and injection.

I’ve also found that most reviewers rarely (if ever) show how to use these features, so I figured I’d take a shot at it. I’ll be using Ant build targets since most of my projects are still scripted that way – So if your using Maven, Ivy, Gradle or any other new-fangled system (Damn kids! back in my day we had to code our builds in XML and that’s how we likes it!) you’ll have to look elsewhere.

Test Groups

TestNG lets you tack a group name onto any @Test annotation, essentially placing your test case, or test methods, into one or many named test groups that can be run individually.


@Test(groups = { "quick", "unit" })
public class UnitTest {

    @Test
    public void yourAverageTestCase() {
    }
}

The grouping isn’t anything special, but it can come in handy when you have a large swath of tests. If you set up a group testing target in your build file you can quickly run a specific batch of tests with a few keystrokes. Something like ant test.groups -Dgroups=quick


<target name="test.groups" depends="compile.tests" if="groups" description="Run a specific test configuration set by -Dgroups">
  <testng suitename="${ant.project.name} unit test suite"
          testname="${ant.project.name} '${groups}' groups "
          groups="${groups}"
          classpathref="test.classpath"
          outputDir="./test-results/testng/"
          failureProperty="test.failure"
          verbose="2">

    <classfileset dir="./test-build">
      <include name="**/*Test*.class"/>
      <exclude name="**/*Tester*.class"/>
    </classfileset>
  </testng>        
</target>   


Re-run Failed Tests

At some point you’ll end up with more than just a handful of unit tests. Usually by this point you’ll also have a few tests that take more than a few milliseconds to run as well. A “run previously failed tests” target is a godsend in these cases. You can make your changes to fix the test, and run the target to see if you’ve fixed the problem. The alternative is to run the whole suite again (which can be time consuming depending on the test suite), or to comment out the other test (which I don’t count as a real alternative).


<target name="test.failed" depends="init" description="Re-run all previously failed tests.">
  <property name="build.noclean" value="true"/>
  <antcall target="compile.tests"/>

  <testng classpathref="test.classpath"
          outputDir="${test-results.dir}/testng/"
          failureProperty="test.failure"
          verbose="${testng.verbose}">

      <xmlfileset dir="${test-results.dir}/testng/" includes="testng-failed.xml"/>
  </testng>
</target>

<target name="clean" unless="build.noclean">
  <!-- Delete old build artifacts ONLY if "build.noclean" isn't set. -->   
</target>

TestNG automatically creates a “testng-failed.xml” document whenever tests fail. Providing you keep the XML file around between test runs (don’t clean the build before running the failed tests), you can run the failed test configuration again with the above target.


Testing Dependencies

This one’s pretty self explanatory, only run a test if the dependencies pass first. You wouldn’t think that this would be that big of a deal, but it’s an immensely useful feature.


@Test
public class UnitTest {
    @Test
    public void testMethod1() {
    }

    @Test(dependsOnMethod = { "testMethod1" })
    public void testMethod2() {
    }
}


Test Fixtures (Data-providers)

Data providers are an awesome way of compacting several tests into a single compact testing method. The data provider provides a list of arguments that get passed into your test method. The Object[][] looks a bit daunting at first, but it makes sense if you think of it as a list of method arguments.


@Test
public class UnitTest {
    @DataProvider(name = "names_list")
    public void Object[][] getNames() {
        return new Object[] {
            { "bob" },
            { "fred" },
            { "jack" }
        }
    }

    @Test(dataProvider = "names_list")
    public void testSomeParameters(String name) {
    }
}

Enjoy!

Generic Visitors

Why is it so hard to find a good example of a Visitor Pattern using Java 5 generics? All of the examples I’ve been able to find have been over complicated, too simplistic, or like in the Java Generics and Collections book; used to solve a completely different problem.

I should clarify my position on the Java Generics and Collections Visitor/Visitable example. The book shows an implementation meant to deal with parallel class hierarchies, which is not a common problem for most of us. It’s nice that that they provided an advanced example, but they failed to cover the simple case first. Don’t take this to mean that it’s a bad book. I still heartily recommend reading it :) .

My criteria for a solid, re-usable Visitor and Visitable interface is relatively simple:

  • Visitable classes can only accept Visitor’s of the same type (i.e., type-safe).
  • Visitors can have a typed return value, no casting necessary.


Our Visitable interface needs to accept a type token defining the visitable class. When this is interface is implemented, the type token will end up referencing the implementing class -meaning the Visitable class can only ever accept Visitors implemented specifically for it. The #accept() method has a separate return value type that will be bound by the visitor.

The Visitor interface is much the same. It accepts a type token for the visitable class and a separate return type token. When implemented, the Visitor will define both what Visitable types it can be used with, and it’s own return type.


public interface Visitable<V> {
    public <R> R accept(Visitor<V, R> visitor);
}

public interface Visitor<V, R> {
    public R visit(V v);
}

It doesn’t look like much, in-fact it might not even make much sense until you see it in action. So without further ado, a (very) simple “Tree” class with children nodes.


public class Tree implements Visitable<Tree> {
    private Integer id;
    private Set<Tree> children = new HashSet<Tree>();

    public Tree(Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return id;
    }

    public Set<Tree> getChildren() {
        return children;
    }

    public <R> R accept(Visitor<Tree, R> visitor) {
        return visitor.visit(this);
    }
}

Note that the implementation of the Visitable #accept() method will almost always have the same method body. You could very easily add an abstract class into the mix but we’ll leave that aside for now.

The Visitor is the fun bit. Below is a simple visitor that generates a string representing the entire tree. When the visitor is applied to a node, it will also visit all children of the node (and the children’s children, children’s children’s children etc.) collecting the ID of each.


public class ToStringTreeVisitor implements Visitor<Tree, String> {
    public String visit(Tree tree) {
        String str = getId() + ", ";

        // visit all child nodes
        for (Tree child : getChildren()) 
            str += child.accept(this);

        return str;
    }
}

Tree root = new Tree(1);
root.getChildren().add(new Tree(2));
root.getChildren().add(new Tree(3));

String str = root.accept(new ToStringTreeVisitor());
// returns => "1, 2, 3"

Dreamhost API in 10 lines of Perl

In 10 lines (ok, it’s actually 11 excluding whitespace) of code; A simple Perl LWP function that can perform any Dreamost API call and return the result as a Perl data structure. After writing this function I was able to hack out a simple Dynamic DNS updater script in under 30 minutes.


my $agent = LWP::UserAgent->new;

sub api_call {    
    my $cmd       = shift;      
    my $post_data = shift;
        
    $post_data->{key}     = "6SHU5P2HLDAYECUM";
    $post_data->{cmd}     = $cmd;
    $post_data->{format}  = 'perl';
    
    my $resp = $agent->post("https://api.dreamhost.com/", $post_data);                   
    return new Safe()->reval($resp->decoded_content) if ($resp->is_success);
    croak "API call $cmd failed: " . $resp->status_line;
}

Edit: I had the function down to 10 lines, but I accidentally introduced a bug and the resulting code was somewhat less readable. I’ll take another crack at slimming it down later.

While the subroutine has been slightly compressed to hit the 10 line goal, it’s still perfectly readable. One caveat to using the above code is that you need to have Crypt::SSLeay installed as the Dreamhost API operates over HTTPS.


# list all dns records
my $records = api_call("dns-list_records");
print Dumper($records);

# create an alias dns record for a subdomain
my $result = api_call("dns-add_record", {
                            record => "subdomain.pointyspoon.com",
                            type   => "A",
                            value  => "192.168.0.1",
                            comment => "DNS forwarding alias"
                       });
croak "dns-add_record failed: " . $result->{data} if ($result->{result} ne "success");   

Of course you could always use the WWW::DreamHost::API module, but ironically DreamHost doesn’t include this module on their own servers.

Happy Dreamhost API Hacking!

Hacking Hibernate: ID Generators

Every programmer will have to deal with the problem of unique identifier generation at some point in their lives. Normally you can just pass this off to your database vendor when persisting an entity, or roll your own using an incrementing value. But then there are the edge cases (Damn those edge cases!). You know the ones, where your working in a clustered environment and the ID needs to be unique across multiple JVM’s, or when you don’t have a entity to write to the database to provide your ID generation for you.

In 99% of most web applications this isn’t a problem. You simply make use of whatever ORM tool you have handy and write an object to your database, letting the database handle the ID generation and storage in whatever vendor defined way is available (auto incrementing columns, sequences, whatever). The reason this is so often done is that databases excel at dealing with unique identifiers. The database already deals with all the necessary locking and atomicity of ID generation, meaning you don’t have to worry about it. Even in a clustered environment your application will still be talking to the same database, so you get your cross JVM synchronization for free as well.

Before we go any further I want to state that using the internals of a 3rd party library in this way is almost always a bad idea. There is no guarantee that it will work with future versions of hibernate (I’m using Hibernate 3.3.2.GA with Hibernate Annotations 3.4.0.GA) and there is no way to know if this hack will cause issues in other areas of the system.

Anyways, back on topic. The tricky part is figuring out how to re-use the ID generation framework of our ORM tools for our own nefarious purposes. The code below shows how to instantiate a Hibernate ID generator using a table generation scheme (Section 5.1.5. Enhanced identifier generators of the docs). This ID generator uses a database table to store ID values and calculate new ones. The nice part about this strategy is that it works with any database providing that you’ve created the hibernate_sequence table.


CREATE TABLE hibernate_sequence (
    sequence_name varchar(255),
    next_val integer
);

Here’s my HibernateIdGenerator class that instantiates a generator manually. You should be able to reverse engineer any of the Hibernate generator classes by building a similar Property set using the generator classes constants. Note that I’m fetching my SessionFactory from a Spring container, but you could also retrieve it from JNDI or the EntityManager#getDelegate() method.


public class HibernateIdGenerator {

    private IdentifierGenerator generator;
    private SessionFactory sessionFactory;

    public HibernateIdGenerator(String segmentValue) {
        Properties configuration = new Properties();
        configuration.setProperty(TableGenerator.TABLE_PARAM, "hibernate_sequence");
        configuration.setProperty(TableGenerator.SEGMENT_COLUMN_PARAM, "sequence_name");
        configuration.setProperty(TableGenerator.SEGMENT_VALUE_PARAM, segmentValue);
        configuration.setProperty(TableGenerator.VALUE_COLUMN_PARAM, "next_val");
        configuration.setProperty(TableGenerator.INCREMENT_PARAM, "100");

        ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml"});
        sessionFactory = (SessionFactory) appContext.getBean("sessionFactory");

        generator = IdentifierGeneratorFactory.create("org.hibernate.id.enhanced.TableGenerator",
                                                      new IntegerType(),
                                                      configuration,
                                                      ((SessionFactoryImpl) sessionFactory).getDialect());
    }

    public Serializable getId() {
        StatelessSession session = sessionFactory.openStatelessSession();
        Serializable id = generator.generate((StatelessSessionImpl) session, new Id());
        session.close();
        return id;
    }

    /**
     * Target object for ID generation
     */
    private static class Id {
        private Integer id;

        @Id
        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }
    }
}

HibernateIdGenerator generator = new HibernateIdGenerator("my_sequence_name");
(Integer) generator.getId(); // returns 1
(Integer) generator.getId(); // returns 2

The downside to this approach is that the ID generator still needs to make a trip to the database to fetch an ID. Well, that plus all the aforementioned warnings about unpredictability, easy breakage and doom.

Have fun!