An introduction to the TDD methodology
Everyone knows that tests are needed, but do you know really why? What are the benefits?
In the beginning of our projects, we are in a green field where every code we write is nice and works, the speed of the project is high, the number of bugs is low and developers and clients are happy.
As the project advance the code start to get messy, every time we have to make a change is harder, in more places and force us to hack our own code or add some nasty code.
After a few months our code is rotten, becomes rigid and fragile. The speed of the team decreases and the number of bugs increases. The developer is scared to introduce changes to the code and to refactor because he doesn’t know if he will break another functionality, all the bug fixes or changes to existing code are small hacks.
So the developer is scared to touch the code because it is too fragile, he needs some kind of protection that he doesn’t break any functionality. This protection are the Tests.
Imagine to have a suite of test that could detect the vast majority of the bugs that could be run just with the click of a button in a few minutes… this is what TDD aims for.
What is TDD?
It is an Agile methodology which consists in letting our tests drive the development of the product writing them first to force us to write the exact code that makes those test pass.
Reduce the debug time
If we have a complete suite of tests we keep writing and updating them and running quite often, every time there is a bug, this bug will appear in the test as an error, so is already spotted just when it was created, and it will be easier to fix since it is located in the code that we just wrote so it is fresh to our mind. You don’t have to spend hours debugging through the whole call stack to check when, where and about what is the bug.
Normally when we try to use a new API we go directly to the examples of code that shows how to use the API, and sometimes we even copy & paste the example and try to tweak it to use it in our code. So well, the Unit tests are those examples. If you have a complete set of Unit test in your product you only need to take a look at them in order to know how your code works.
You have in your set of tests an example of every possible way to use your code. Is the perfect documentation that is reliable and is always updated.
The courage for change
Thanks to the suite of unit tests that covers most of your code you can be sure that your code is working, this will eliminate the fear of the developer to change anything allowing him to clean the code and refactor freely. Tests stop the code from rotting.
Why to write tests first?
Writing tests first makes the production code testable. Ok that’s obvious but what is de benefit? If the production code is testable it means that it is decoupled, if you can test a part of the production code by separate in one unit test then that part is decoupled from the rest of the components. The more decoupled the system is the more flexible and extensible is.
You get a better design just by writing test first.
Normally if you write your tests after writing your production code they won’t be as complete as if they were written first because you already know your code works and it is boring to write only tests, sometimes you are tempted to take shortcuts and you miss some tests.
If you write the test first you are writing code to pass those test, so every line of production code is covered by a test. You trust your test, they are more complete than if you write them after.
And how do we do TDD?
It consists in a 3 phases cycle, known as red, green, refactor. This cycle must be very short and the iterations must be quite fast in order to not be much time outside of the green phase where all your code is working.
There are 3 phases:
Writing a failing test first.
Writing the production code to pass the test.
Refactoring the production and the test code.
In the Red phase we write a unit test that fails that will force us to write the production code that we want to write.
In the Green phase we are able to write the production code to make that failing unit test pass. We write no more no less.
In the Blue phase, when our production code works as desired, we clean the production and the test code, making it more sustainable, extensible, removing duplication, in other words, we clean the code.
The 3 laws of TDD.
TDD is a discipline, as any discipline it has a set of rules that for the beginners can sound a little extreme, but with time they will become more and more logical. Here are the 3 Uncle’s Bob TDD rules, read them well and understand them well:
• 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.
Follow these 3 rules and they will force you to write alternating between test and production code in short time periods and you will always have production code that is passing all the tests or at least was not long time ago.
At the beginning coding in the TDD way will be slow and hard, but with time you will change your mindset and you will be automatically thinking about features that your code should do, instead of solutions, writing tests for it instead of implementing the production code directly and thinking how to write your production code to be easily testable and decoupled from other functionality.
Most of the information was obtained from the teachings of Robert C. Martin Aka Uncle Bob in his videos. You can download his videos at CleanCoders.com and follow his company blog for more interesting articles 8thLight Blog.
Clean Code – by Robert C. Martin
Growing Object-Oriented Software, Guided by Tests – by Steve Freeman and Nat Pryce
Test Driven Development. By Example – by Kent Beck