The Art of Test Driven Development: Running unit tests conditionally

There comes a time where Java’s promise of “write once, run anywhere” breaks down for some of us. In my case and my Windows users, file paths present platform specific challenges. This article will show you how to run unit tests conditionally; only on Windows for example.

I talked about conditionally ignoring tests in JUnit in the past, but I’d like to revisit this topic in a little more detail.

I have an application that uses URIs for file references, but for most sane Windows users, a file reference is something like E:\some\folder\foo.txt, not file:///E:/some/folder/foo.txt. Is it ‘file’, a colon, and two slashes, or three, or four? Darn!

To make life easier for normal and power users, the application supports both Windows paths and URIs. The application converts Windows file paths to URIs internally and everyone’s happy. How do you unit test this? Just as always, you say. The trick comes when your build runs on a farm of Windows and Linux boxes, and some of your carefully crafted tests pass on Windows but fail on Linux for obtuse reasons that are not the point of this write up. The bottom line is that I want to run certain tests on Windows only. Fortunately, JUnit provides a nice way to do this using its Assume class.

Here’s how you do it:

private static final boolean IS_WINDOWS =

public void testMeOnWindows() {

We first set a Boolean constant that indicates that we are running on Windows or not. To do that, we simply lookup the system property and check that it starts with the String “Windows”.

The JUnit Assume class causes JUnit to ignore a test if the given condition fails. In our example, the test method will only proceed on Windows; but the test will not fail.

A failed assumption does not mean you have a bug or that the test failed, it means that JUnit should not continue running the test and not mark it as a failure. JUnit test runners will skip tests will failing assumptions. Your mileage may vary with other test runners.

Assume checks can be for any condition, giving you and your tests a lot of flexibility.

Under the hood

How does JUnit do this? When you call an Assume method like assumeTrue(), the following appens:

public static void assumeTrue(boolean b) {
  assumeThat(b, is(true));

JUnit calls the more general assumeThat() method with a Hamcrest matcher from

public static <T> void assumeThat(T actual, Matcher<T> matcher) {
  if (!matcher.matches(actual)) {
    throw new AssumptionViolatedException(actual, matcher);

The expression matcher.matches(actual) uses Hamcrest to evaluate your condition and returns true if it passes. If your condition fails, the method assumeThat() throws an AssumptionViolatedException; which JUnit uses to implement assumptions. The JUnit guts catch these exceptions and handle them differently than other exceptions by adding the assumption violation to a list it uses in its reports.

There you have it, JUnit assumptions give your tests an extra level of flexibility by allowing you to run tests conditionally.

Happy Coding,
Gary Gregory

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s