This is the first part of a series of post regarding TDD (Test Driven Development), how it works, why YOU should use it, how to do it and how not to do it.
How I got started
As part of my final year of University, I've started working on a Ruby port an executable specification framework called GreenPepper.
My team and I decided to develop the entire thing while sticking religiously to the TDD methodology. Two months into the project we have over 98% code coverage.
TDD Simply Put
Very simply put, here are the 3 easy steps of TDD.
How I got started
As part of my final year of University, I've started working on a Ruby port an executable specification framework called GreenPepper.
My team and I decided to develop the entire thing while sticking religiously to the TDD methodology. Two months into the project we have over 98% code coverage.
TDD Simply Put
Very simply put, here are the 3 easy steps of TDD.
- Write a test that fails
- Write code to make it pass
- Refactor
Those three steps are essential, they must all be done and in that precise order. In a future post, I'll give a more concrete example of how to apply these three steps. But for now, understand that if you're doing TDD, you cannot write code unless a test is failing.
The Benefits
The benefits of TDD are all tied to those three easy steps. The obvious benefits is that by following all those steps, the near entirety of your code is covered by your tests.
Also, by writing the tests first, you're forcing yourself to write code with easy and simple APIs. Lets face it, you're gonna be the one calling your code, might as well make it easy to use.
Another key benefits of writing test is that you are in fact writting an example of how to use your code. In a project where everything is properly tested, if you wish to learn how to use a class, you simply need to locate the tests for this class and you'll have a very complete example.
Now, the biggest advantage of unit testing is easy refactoring. When working of code that is not automatically tested, developpers are understandably frighten of huge refactorings. I myself worked in projects where features were abandon because it was too likely implementing it would break something. If everything is tested, you can change whatever you want without worrying about regressions.
A Real World Example
A testimony to easy refacoring with TDD is my last change to GreenPepper Ruby. We were using the standard Ruby XML library REXML for all our DOM parsing. This turned out to be a bad decision for several reason. REXML is sloooow, poorly documented and the API is simply awful. A much better choice was libxml. We didn't originally go with libxml because the OS X version was broken at the time. Recently the libxml team released the 1.0 version that fixed OS X. I decided it would be a good time to jump ship before the cost of changing library was even greater.
So I went in and change every class that used REXML. GreenPepper uses DOM extensively, so it was a huge change, several class had to be heavilly modified. It took me less than 5 hours to completly replace the parser.
I am 100% confident I did not break anything in the code. Why? Because EVERYTHING is tested and every test still passes!
There is no way in hell I would have dare change that parser if it wasn't for TDD.
The Bottom Line
TDD makes you more confident your software works at any given time. You can refactor without fear, thus creating much better code. If you plan on writing software that will be maintainable, you absolutely need unit testing and the best way to achieve that is thought TDD.
You should do TDD.
The Benefits
The benefits of TDD are all tied to those three easy steps. The obvious benefits is that by following all those steps, the near entirety of your code is covered by your tests.
Also, by writing the tests first, you're forcing yourself to write code with easy and simple APIs. Lets face it, you're gonna be the one calling your code, might as well make it easy to use.
Another key benefits of writing test is that you are in fact writting an example of how to use your code. In a project where everything is properly tested, if you wish to learn how to use a class, you simply need to locate the tests for this class and you'll have a very complete example.
Now, the biggest advantage of unit testing is easy refactoring. When working of code that is not automatically tested, developpers are understandably frighten of huge refactorings. I myself worked in projects where features were abandon because it was too likely implementing it would break something. If everything is tested, you can change whatever you want without worrying about regressions.
A Real World Example
A testimony to easy refacoring with TDD is my last change to GreenPepper Ruby. We were using the standard Ruby XML library REXML for all our DOM parsing. This turned out to be a bad decision for several reason. REXML is sloooow, poorly documented and the API is simply awful. A much better choice was libxml. We didn't originally go with libxml because the OS X version was broken at the time. Recently the libxml team released the 1.0 version that fixed OS X. I decided it would be a good time to jump ship before the cost of changing library was even greater.
So I went in and change every class that used REXML. GreenPepper uses DOM extensively, so it was a huge change, several class had to be heavilly modified. It took me less than 5 hours to completly replace the parser.
I am 100% confident I did not break anything in the code. Why? Because EVERYTHING is tested and every test still passes!
There is no way in hell I would have dare change that parser if it wasn't for TDD.
The Bottom Line
TDD makes you more confident your software works at any given time. You can refactor without fear, thus creating much better code. If you plan on writing software that will be maintainable, you absolutely need unit testing and the best way to achieve that is thought TDD.
You should do TDD.
No comments:
Post a Comment