Test Driven Development
A design is simple to the extent that it:
- passes its tests
- minimises duplication
- maximises clarity
- has fewer elements.
We make sure first that the behaviour of the system is correct, and then we make sure that the code is clean. We do this by writing tests first, and then writing the code to pass the tests. This is called test driven development. Test driven development works in a cycle:
- Write a failing test
- Write the simplest code to pass the test
- Refactor the code
- Repeat
This is not just about testing - it is a design process.
Behaviour Driven Development
We want to use tests that verify the behaviour of our system. The tests in the example below are written in a way that describes the behaviour of the system, as a specification for the system.
1public class CustomerLookupTest { 2 @Test 3 findsCustomerById() { 4 ... 5 } 6 7 @Test 8 failsForDuplicateCustomers() { 9 ... 10 } 11}
Fibonacci Example
Our fibonacci sequence object must:
- define the first two terms to be 1
- has later terms calculated as the sum of the previous two
- is not defined for negative indicies
1public class FibonacciTest { 2 3 FibonacciSequence s = new FibonacciSequence(); 4 5 @Test 6 firstTwoTermsAreOne() { 7 assertThat(s.term(0), is(1)); 8 assertThat(s.term(1), is(1)); 9 } 10 11 @Test 12 laterTermsAreSumOfPreviousTwo() { 13 assertThat(s.term(2), is(2)); 14 assertThat(s.term(3), is(3)); 15 assertThat(s.term(4), is(5)); 16 } 17 18 @Test 19 notDefinedForNegativeIndicies() { 20 try { 21 s.term(-1); 22 fail("should throw exception"); 23 } catch (IllegalArgumentException e) { 24 assertThat(e.getMessage(), is("negative index")); 25 } 26 } 27}