This is the first of a series articles about TDD that will give you some insight on why and how you should start testing your code. My hope with this first one is to convince you that if you are not testing your code with automated test you are doing programming wrong, not that you don’t know how to code but that you are making your life harder than it should be.
A long time ago
Now try to remember your school days. One day your old nearsighted teacher gave you the test you looked at it and one of the questions was this one:
A train departing from station A travels at 220 km/h another train leaves station B at the same time and travels at 130 km/h. How many kilometers does the train departing form A travels before reaching the other train?
Obviously you don’t have the solution to the question, but it reminds you of another question you did as a homework:
Two trains are leaving the same station. Train A leaves at 10AM and travels at 130 km/h while train B leaves at 11AM and travels at 220 km/h at what time does train B reaches train A? Solution 146 minutes
You complete the test and give it to your teacher… and then hope…
Of the two questions,
- which one makes you feel most confident that you have been able to solve it correctly?
- which one will you have to wait longer to know if you did it correctly?
- which is more dangerous to give to the teacher?
Let’s get back to the current year
Now you are programmer, and your client gives a requirement document in which you find this one feature request:
- All Approved documents can be read by all registered users which are in the Readers group of higher
- Documents which are in the Draft state can be read by Editors, Administrators or by delegated users
- Draft documents can be delete d only by Administrators whom cannot Approve them, the only users able to approve the documents are the Editors excluding the Author of the document
You have three ways of implementing this requirement:
- The Punch-card Method
- the Manual Method
- The Correct Method
The Punch-card Method
Blame on you if your perception of programming is slamming the keyboard for days without verifying what you are doing and then shipping that mess that you have produced to some poor guy condamend to report you a list of all the defects that he finds! If you are working like this you are just been careless and you would do a better service to the community if you fire yourself and find some work that better fits you!
It was OK to write a program without testing it when the only means to feeding a program to a computer was by using punch-cards. Those machines where slow and it could take up to two weeks to have your program executed. Now you have to just press the F5 button and magic happens. You should at least test it manually.
The Manual Test Method
You are using the Manual Test Method if you are implementing the requirements and then checking manually all possible combinations of the feature before proceeding to the next requirement. There’s no doubt that you can build working software with this workflow and, at least, the testing guy or the client wont find a product that is packed with bugs. Lots of successful businesses build their software like this. The downside of this process is that you spend a whole lot of time testing your implementation, and the more complicated the business logic is the more time and effort you have to put on testing instead of implementing the features. You also spend most of your time in debug mode. We spend so much time in debug mode that Microsoft needed to optimize the compiler to let you change the code while you are debugging.
The Correct Method
C’mon people! We are programmers! Why do we have to keep in memory all requirements? Wouldn’t it be great if we had a way to write the requirements down in order to have the computer check the implementation against them and tell us when we have finished? It turns out that we can: almost all requirements can be expressed in a way that lets us check wether we have completed the implementation or not. but we gain also other advantages by writing down the implementation as automated tests: we get regression tests, and protection from silly bugs like typos.
This workflow of translating the requirements into executable test is said Test First at the beginning it feels awkward and wrong. It’s like programming backwards, but after some time you not only get used to it but you get frustrated when you stumble onto some part of someone else code which you can’t easily test. By using Test first you gain lots of benefits like:
- A set of automated test that protects you from bugs
- Improved code quality
- It sets you free from debugging mode and manual tests
- Free time to do what you love
- A bag full of money
well.. maybe not the last one.
The key take away
Programming is difficult. At its core, it is about managing complexity. Computer programs are the most complex things that humans make. Quality is a illusive and elusive.
The key take away of this blog is that programming is difficult, the computer executes exactly what you tell it to do. If it’s not behaving like it should is because it’s not programmed like you thought it was. This is why it’s better to find ways automatically check what is the program actually programmed to do.
In the next blog post I’ll be giving a practical example of some of the benefits that Test First gives you and how to take it to the next level