TDD is a great method in software design. Traditionally, the process of TDD consists of the following steps: 1. Always write a unit test before everything else and of course il will fail 1. Write some code to pass the test, the code can be inelegant 1. Refactor the code 1. Repeat all above
Test-driven does not simply verify the correctness of the code but more important it drives the design.
Here are the great principles :
- Write test before the implementation. This ensures in this way that all written code is covered by at least one test. This gives the programming team, and subsequent users, a greater level of confidence in the code.
- A Contract Design Pattern. The programmer is concerned with interface before implementation. It approaches the code through usage rather than assumptions and preconceptions.
- Take small steps when required. It allows a programmer to focus on the task at hand as the first goal is to make the test pass.
- The test is a form of specs, this drives programmer to understand the specs before all because she will have to translate it into test code later. Tests are not specs, of course not, but a test should meet the specs in some way.
- Test is the first level design. When we write a unit test, we begin to divide a feature into parts. The more test is simple and clear, the more code is going to be clear and simple.
Besides theses principles, in practice, the pure TDD shows some issues and inefficiency :
- Tests are not real software code, there is a risk of losing productivity because of too much test code written. This is not exactly a TDD issue but a design issue, if the test code is complex this means probably the implementation does too much work and should be divided into subsets.
- In the step 2, we are intended to write code just for passing the test without consideration of code quality and we achieve this by refactoring later. That indicates we will always rework our code. Personally, I don’t like it. And refactoring may violate the original idea of TDD : design before coding, but refactoring here just seems like some mechanic cleaning job. Can’t we write good quality code in the first place using all OO design principles and code conventions? Once done, the code should be reliable and maintainable.
- Write test before implementation, it sounds very strange, how can we run a test without any implementation code? How we compile the test if the feature class is not yet written, but if the class is created even with just a skeleton, does this mean we write something else before the test and this is not test-driven.
In daily work, the TDD is not easy to apply at first because it appears to add some extra work and it changes the regular habits of programming, and some or all of the above issues are not well concerned. That’s why some people failed and blamed TDD as an anti-productivity method. My goal here is to make this fantastic method not hard to apply and really productive.
I will show in another blog how in detail these issues can be resolved and the code could be written in a J2EE project by using good practice and appropriate tools. Here I want to underline some guidelines of using the TDD method:
- TDD is about design not about test. Use the test code to design not just to verify the correctness. Yes we write some extra code than we needed for the feature of the software, but this code is valuable : it’s a validation, it’s a design and it can even be a spec document.
- Test is for requirement not for implementation. Let the test guide the implementation. We build the contract first, then we implement it.
- Keep it simple and clear. A test or an interface is written for one requirement not some requirements. A technic to verify about this is by asking what does it test or what does it do? The answer should not contain the word “and”.
- Test before program or interface before implementation. Stick to it, this is the “top down” principle. Think and define the contract before realize it. Ask yourself before writing any code : what does it do? What does it expect? What are the rules?
- TDD is one method and mustn’t ignore other OO design principles. Good practice, code convention, design patterns are encouraged to use other than ignored while applying the method.
- TDD is a tool, use it do not suffer it. A tool helps you, not slow you down, if the method drives you crazy, there must be something wrong, don’t ignore it, find it and try to manage it in an easier way.
You can find some good examples regarding TDD on the net:
- An other nice introduction on TDD with a PHP Demonstration
- An excellent demenstration of TDD on JAVA practice
- A nice book of TDD: Test Driven Development: By Example, Kent Beck, Addison-Wesley Longman, 2002, ISBN 0-321-14653-0, ISBN 978-0321146533
Wish you enjoined it.