• Posted by Intent Media 09 Dec
  • 0 Comments

Testing a Dropwizard application with Cucumber-JVM and jUnit

Dropwizard has quickly become the framework of choice for implementing new web services at Intent Media.

Because we take testing seriously, one of the first things we do when developing a new Dropwizard application is write some integration tests to make sure it will interact with its ecosystem in the way we expect.

Suppose you want to write some integration tests for a Dropwizard server application using Cucumber-JVM, the Java implementation of the popular BDD test framework.

How do you start your application and make it available within Cucumber’s test context? Dropwizard provides easy support for unit testing with jUnit, and fortunately Cucumber-JVM works with jUnit as well. Add a DropwizardAppRule with an @ClassRule annotation to your test runner class like so:

package your.dropwizard.app;

import cucumber.api.junit.Cucumber;
import io.dropwizard.testing.junit.DropwizardAppRule;
import org.junit.ClassRule;
import org.junit.runner.RunWith;

@RunWith(Cucumber.class)
public class RunCukesTest {

    @ClassRule
    public static final DropwizardAppRule RULE =
            new DropwizardAppRule(YourApplication.class, "path/to/config/file");
}

Run the test, and you’ll see your Dropwizard app starting up before your feature steps execute. It will then shut down automatically after the tests are finished. Here’s a good tutorial if you need help getting your step definitions wired up to your feature tests.

So far, so good. But there’s a drawback to this solution. One of the key benefits of DropwizardAppRule is that it conveniently brings your application’s configuration and environment into test scope via the RULE object. However, because Cucumber test steps are defined in a separate class, we aren’t able to refer to RULE where we need it.


The workaround our team settled on was to write a DropwizardHolder class exposing getters and setters for the application properties we needed in our step definitions. A basic implementation might look something like this:

package your.dropwizard.app;
import io.dropwizard.testing.junit.DropwizardAppRule;

public class DropwizardHolder {

    private static DropwizardAppRule rule;

    public static void setRule(DropwizardAppRule rule) {
        DropwizardHolder.rule = rule;
    }

    public static DropwizardAppRule getRule() {
        return rule;
    }
}

Now add a @BeforeClassmethod to your test runner class to set the rule:

package your.dropwizard.app;

import ...

import static your.dropwizard.app.DropwizardHolder.setRule;

@RunWith(Cucumber.class)
public class RunCukesTest {

    @ClassRule
    public static final DropwizardAppRule RULE = ...

    @BeforeClass
    public static void buildDropwizardHolder() {
        setRule(RULE);
    }

}

Now you can import the DropwizardHolder in your step definitions class, and access any of the properties exposed by the rule object.

With this framework in place, you can write new integration tests just as fast as you can implement new features.

Happy testing!

Amasa Amos is a Quality Assurance Engineer at Intent Media, where he builds tools to drive cross-platform integration testing. When not breaking things, he enjoys board games, hiking, and ashtanga yoga. You can sometimes find him on Twitter or on Github.

Post Comments 0