Do You Know TDD?
This is not an intro book.
I first learned TDD from Kent Beck's book, Extreme Programming Explained, a little more than a decade ago. That seems like a good way to learn, and it is provided you're working on the C3 System at Chrysler like Kent was at the time. Otherwise you probably aren't surrounded by other people who TDD that can correct you when you make mistakes like this one:
public void TestOne() {
auto database = new Database();
database.Start();
auto webserver = new Webserver();
webserver.Start();
auto synchronizer = new Synchronizer();
synchronizer.Save("KEY", {name: "NAME"});
auto webservice = new Webservice("http://localhost:8080");
auto serviceObject = webservice.Find("KEY");
auto dbConnection = new DatabaseConnection("localhost");
auto dbObject = db.Find("KEY");
ASSERT(convertToWebserviceObject(dbObject) == serviceObject);
dbConnection.close();
}
Honestly I wish that was the worst test I've ever seen, but it's probably not the worst test I've written today. Let's identify what's wrong:
- The DBConnection is left open when the assert fails, so if the test fails all tests after it are probably broken.
- It's unclear what the Arrange/Act/Assert steps are in the test. What Am I testing here?
- The test will fail if the db doesn't start, or is running.
- The test will fail if you can't connect to the webservice.
There's more but you get the idea. The test is a mess, the code is probably a mess, and you had to write a lot more than necessary to get it to pass. What happened?
Well it's likely you never properly learned TDD.
It's More Than Three Rules
Bob Martin's Three Rules of TDD are as follows:
- You are not allowed to write any production code unless it is to make a failing unit test pass.
- You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
- You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
Seems simple enough but like Othello it takes a minute to learn and a lifetime to master. More than anything it takes PRACTICE! You wouldn't start programming at work without learning a new language, so should you be using TDD without learning it properly first?
There's a process and you should follow it before you waste your employer's money and your time.
Introductory Reading
Yeah you have to do a little reading. Active Reading - where you follow along with the code examples. I think the best introductory book is still Test Driven Development By Example (not XP Explained) by Kent Beck. The examples in it aren't very real world, but the techniques are.
Basic Practice
Trying to apply that book to your real world job is likely to start causing the same problems I mentioned above. This leads to frustration and confusion when the codebase isn't greenfield like Kent Beck's money example. You need to practice, and the best way to practice TDD is through performing a Code Kata. The one I give to beginners is Prime Factors. Prime Factors has the advantage of being complicated enough to require testing but simple enough to be repeatable.
Do this kata daily for a couple weeks first thing in the morning. You're trying to make test-first a habit and that can only be done through repetition. You'll know when you've got it when you really want to write tests for your other development. While you're doing that kata...
Reading on Systems
It's time to read GOOS. While I don't agree with every aspect of their approach, I think it's a great way to start working with a real application, drilling down from higher level tests to lower level tests. You might have to read this one more than once for it to sink in. This is the advanced version of your first book.
Practice Libraries
When you've read GOOS it's time for a new kata, the String Calculator. Where the first kata just had you solve a simple problem in a test-first way, this one will force you to use the String libraries of you preferred environment and wrestle with the problems of a real application. I use this kata each time I switch environments (for instance .NET to Java) to re-familiarize myself with the new setup. It's significantly harder than Prime Factors.
When you feel ready I highly recommend recording a screencast even if you don't show anybody. Kata's are meant to be performed, and the attempt at performance will prove just how good you are at the kata. If there is any group in your area you should consider performing it in front of them.
Heck you could even send it to me. I'll definitely look at it.
A Test Application
This is the step where you are most likely to fail, especially if you just read a book and started writing your new 3D engine for Oculus Rift in it. You'll get confused, the tests will get painful, and you'll give up. You might decide TDD is too hard, when it reality it's software development that is hard not TDD.
No you need a test application with known boundaries. Something large enough to force you to design good software and wrestle with challenges, but small enough that you're finished before we're all dead. A good example is to write the game Mastermind. It has complicated rules, user input, but is simple enough to get working. Especially since you ARE going to keep it to the command line. Your goal is to practice TDD and you'll learn Mastermind to do it. If you add a UI framework on top you've now got to learn two different things at the same time, plus the challenges of testing a GUI, and you're extremely likely to fail.
Your Own Project
Now that you've made Mastermind and it's working and wonderful, pick your project. By now you'll have seen the benefits of TDD, and you'll have spent some time researching any issues you had when building Mastermind. You should be ready to pick that open-ended project you've always wanted to write. In the meantime....
Bring it to Work
You're ready to start doing TDD at your job. The challenges will be different of course, but you'll have done the research and practice necessary to be ready to tackle them. Will you be perfect? No. There's plenty more learning to do, like there always is in software, but you've got enough "test infection" to be successful.
This plan, assuming you're already a developer with some experience, should really only take a few weeks. It's two books and one fairly simple application. When you're done you'll have the foundational knowledge (from books) and practice (from katas) to practice TDD confidently.
Now that you've skimmed the above and skipped it, you're ready to work through this book.