Hello, Dave

There are quite a few good tools available for developers who are interested in writing more expressive tests. Frequent readers of this blog will doubtless know that I am a big proponent of easyb which is a very effective groovy-based Behavior Driven Development (BDD) tool. But what if your organization doesn’t support the use of Groovy or you are not fortunate enough to use the IntelliJ IDE (for which easyb has direct support for)? Other popular tools in this vein include Fit, Fitnesse, GreenPepper, RSpec, and Concordian among others. These all share a desire to more expressively represent system behavior in an automated manner. But like all tools, they have their own challenges as well. They all introduce their own syntax for expressing behavior which can make writing specs more cumbersome. And they all require special methods for running them introducing very real tooling issues. In this brief post I will introduce how you can begin to write more expressive BDD-styled tests through JUnit, and how the JUnit-based BDD tool JDave can help you find some of the expressiveness offered by the tools listed above without having to venture out beyond the ubiquitous JUnit platform.


BDD is an extension to Test Driven Development (TDD) which re-orients the language of testing from the structure of your code (classes and tests) to the behaviors your system should exhibit. Consider the following user story:

As a bank customer
I want to be able to withdraw funds from my account
So that I can have ready access to cash

We can refine this specification by identifying some acceptance criteria:

Given an account with a balance of $500
When a customer withdraws $100
Then the account should have a balance of $400

We could write a test for this behavior using traditional unit testing syntax as follows:

public class AccountTest extends TestCase {
	public void testWithdraw() {
		Account account = new Account(500);
		account.withdraw(100);
		assertEquals(400, account.balance());
	}
}

With this approach the structure of test is coupled to the structure of our implementation class. Specifically, the AccountTest class is related by naming convention to the Account class and the testWithdraw method is related to the withdraw method of Account. A BDD approach would change the syntax of this tests to relate it to a system behavior rather then specific implementation component. In BDD parlance this is referred to as a spec instead of a test and could look like the following:

public class WhenWithdrawingMoney {
	@Test
	public void shouldDecreaseAccountBalance() {
		Account account = new Account(500);
		account.withdraw(100);
		assertThat(account.balance(), is(400));
	}
}

Reading the test class name and the method name together produces the phrase “When withdrawing money should decrease account balance.” This is very descriptive of behavior that the spec is asserting the system should exhibit.

JDave is a JUnit-based BDD framework that expands the syntax available for use in writing BDD-styled specs such as should, must, not, where, contains, etc. We can express the same test uses JDave as follows:

@RunWith(JDaveRunner.class)
public class AccountSpecs extends Specification<Account> {
	public class WhenWithdrawingMoney {
		public void shouldDecreaseAccountBalance() {
			Account account = new Account(500);
			account.withdraw(100);
			specify(account.balance(), should.equal(400));
		}
	}
}

So there are a host of tools and techniques that enable one to write expressive tests with just Java and JUnit. These are great ideas to keep in your developer toolkit. But even with techniques such as these writing tests built upon plain Java doesn’t rival these same conciseness afforded to tools such as easyb which are free of the constraints of the Java language. For example, consider this test written with JDave:

	public class WhenWithdrawingMoney {
		public void shouldNotAllowWithdrawalOfNegativeAmount() {
			final Account account = new Account(500);
			specify(new Block() {
				public void run() throws Throwable {
					account.withdraw(-100);
				}
			}, must.raise(RuntimeException.class));
		}
	}

Because Java doesn’t offer support for closures this test is slightly obscured by three additional lines required to define an anonymous inner class. Instead easyb this test could be expressed as:

it "should throw exception for negative withdraw amounts", {
  Account account = new Account(500);
  ensureThrows(RuntimeException) { account.withdraw(-100) }
}

In conclusion, if you would like to write more expressive, BDD-styled, specifications for your system and aren’t able to use more powerful tools for whatever reason, you can still go quite a towards accomplishing this goal with the Java language, and JUnit. And tools such as JDave, and Hamcrest (which I didn’t cover here) can help make these tests yet more expressive while not deviating from the ubiquity of the JUnit platform.

There are no comments on this post

Leave a Reply