Test Driven Development
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Outside-in design with TDD
TDD helps us design the public interface of our objects to be easy to use.
The key is to write code that calls our object using what we think will be a good public interface. We do this before writing code inside our object. This forces us to think about making the calling code simple. Our ‘backwards thinking’ of OOP again.
This piece of code is known as the test code. It will set up our object, call a behavioural method on it, and then check whether that method worked or not.
This test does two things for us:
- verifies the behaviour is correct
- verifies the call is easy to make - a hallmark of good design
If our design is hard to set up or hard to use, we’ll see that in hard to read test code.
Java projects use the wonderful JUnit test framework to help out with this. I like to add AssertJ to help with the checking part.
Let’s use TDD to build a little calculator that can add up our restaurant bill. As you follow along, notice the rhythm of TDD - write a bit of test, see a failure, fix it with a bit of code, repeat.
Our calculator class should do two things:
- give us a running total of all the items we’ve added
- add another item.
We start by writing an empty test. We want this test to prove something that will be true of our BillCalculator class as soon as we create it. If we create this object and don’t add any items to it, the total must be zero.
Let’s start to write a test for that.
First test: total starts at zero
1 class BillCalculatorTest {
2 @Test
3 public void totalStartsAtZero() {
4 // ... todo
5 }
6 }
We’ve got a test class and a test harness method all named for what they do.
Now we do a tiny step of design for our object. We want to be able to access the latest running total. For this, despite all my bleating in previous chapters, a getTotal() method seems like the simplest, most clear design.
Let’s add this design decision to the test:
1 class BillCalculatorTest {
2 @Test
3 public void totalStartsAtZero() {
4 // Act
5 float total = calculator.getTotal();
6 }
7 }
The compiler will be loudly complaining at this point, as indeed might you if this is your first TDD session: “There isn’t any object yet!”
Quite right. Let’s fix that.
Using your IDE shortcuts, create a new Class called BillCalculator:
1 class BillCalculator {
2 }
Now, we can fix the first of our compiler’s many complaints and create a calculator object:
1 class BillCalculatorTest {
2 @Test
3 public void totalStartsAtZero() {
4 // Arrange
5 var calculator = new BillCalculator();
6
7 // Act
8 float total = calculator.getTotal();
9 }
10 }
I’m using the ‘var’ keyword from recent Java editions (don’t ask me which one; I never was a language lawyer kind of guy). I think this reads very clearly here.
The compiler will grudgingly accept we are now not complete idiots and remove the red X from under ‘calculator’. It will then move on to its next complaint. We need to add the getTotal() method.
Let the IDE shortcuts do this, because the IDE has all the information it needs to get it right:
1 class BillCalculator {
2 public float getTotal() {
3 return 0.0;
4 }
5 }
I love working backwards like this. The IDE has enough information to do most of the grunt work and not make as many typing mistakes as I do. It’s also a very fast way to work once you get into the rhythm of it. You even look (to the clueless) like a 10x mega ninja rock star programmer.
Anyway. The compiler will be happy, allowing us to add our check that everything is ok. We’ll use the wonderful ‘AssertJ’1 library to provide the ‘assertThat’ method.
1 class BillCalculatorTest {
2 @Test
3 public void totalStartsAtZero() {
4 // Arrange
5 var calculator = new BillCalculator();
6
7 // Act
8 float total = calculator.getTotal();
9
10 // Assert
11 assertThat(total).isZero();
12 }
13 }
We can run this test - and it will pass! Our calculator object has passed its first and only test. It just so happens that the only thing we are testing is that the total is zero and the IDE generated code always returns zero.
Arrange, Act, Assert - a rhythm inside each test
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Red, Green, Refactor - a rhythm in between tests
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Second test: Adding an item gives us the right total
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Designing the second feature
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
TDD Steps - Too much? Too little?
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
YAGNI - You Ain’t Gonna Need It
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
YAYA - Yes, You Are
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Optimise for Clarity with well-named tests
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
TDD and OOP - A natural fit
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
FIRST Tests are usable tests
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Real-world TDD
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
The Good
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
The Bad
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
The Ugly
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.