Archive for May, 2008

Test Driven Development – Some practical tips

May 11, 2008

In an earlier post, I had touched upon TDD very briefly, and had promised some practical tips on implementing TDD in a future post….Here you go…

 

Having managed teams implementing TDD, Yours Truly has learnt the hard way, that implementing TDD is not cakewalk, the glamour and hype attached to it notwithstanding. So if you are contemplating on implementing TDD, here are some practical tips:

 

1) There will be starting-trouble, since this calls for a complete paradigm shift in the minds of the developers. Most ( if not all) of us have grown up by hearing and practicing this – Write code, then test. TDD turns that completely topsy-turvy. It says, write a test case (it will obviously fail since it is checking for code which is still not there). Then write code which will just satisfy the test case and make it run (note that the code should do nothing more than barely making the test case run). Then write the next test case, and make it pass by writing the corresponding code. This concept requires some unlearning, and so pls be prepared to add sufficient buffer in your deliverables for implementing this, and don’t crucify your developers for taking some extra time in the beginning of your TDD roll-out. This extra time will come down once they are comfortable with this approach, and then they’ll reach a desirable mindset where they’ll find it difficult to write code without writing test cases, but till then, patience….

 

2) Better to involve those experienced folks who know Unit Testing (eg NUnit, JUnit). If they have worked on Unit Testing for some duration, and have been writing the test cases after the code was written, then they would definitely have faced issues where they’ve had to refactor the code in order to increase the code coverage from the unit test cases written. This is a constant pain, and TDD removes this by having tests initially, so code-coverage is not an issue (in case you are wondering, ‘code-coverage’ gives a measure of how much of the codebase is covered/tested by the unit-test-cases-suite).

 

3) Start with a very small but determined pilot team. Starting with a big team is not really manageable, because of the delivery pressures…

 

4) It is very easy for them to slip back into the traditional way of coding, if there is a schedule pressure….so watch out closely for that.

 

5) Go for a code coverage of about 70-80%…more than that could become an overkill in the initial stages… looks like the Pareto rule is kind-of applicable here too — you can achieve 80% of code coverage with 20% of effort, but the remaining 20% will take about 80% of the effort. Do I have a big array of statistics to prove this? Nope…Just a few metrics collected in those projects, and a gut feel evolved over time. I have seen the enthusiasm die down because of the amount of additional effort needed to cover that last stretch …It will take significant effort from you to rekindle the enthusiasm. So better to aim for about 70-80 % initially, and it’ll work.

 

6) Its ok to have less unit tests for UI, since UI needs to get covered more by the Functionality/Usability testing. Focus on using TDD more for the sub-strata (layers below the UI).

 

7) In the middle layer(s), there would be integration points, and we should make sure that we are not ignoring these parts, especially if they are part of the critical functionality/logic. Now the question is, we are doing Unit Testing (or in other words, we are not doing Integration testing), so how do we cater to the integration points, since there would be some chatting between modules/classes. The solution is to use stubs. That is, create stubs which will be called (instead of the actual foreign class/module) by the unit, and return various values, and so the behavior of the unit can be tested based on the different values returned by the stub. Now the point is, writing stubs can be cumbersome. So for that, you could use some third-party API. For eg, there’s a very good API for this very purpose, called TypeMock.

  

What is outlined above is but some of the pitfalls that you need to watch out for, in your journey towards TDD. Happy Test Driving !

To TDD or not to TDD – Yet another chicken-egg situation ?

May 11, 2008

Before trying to answer the above question, let us quickly touch base on what is the difference between the terms ‘Unit Testing’ and ‘Test Driven Development (TDD)’, or is there a difference at all?

 Here’s what. Unit Testing simply means that you write unit test cases to exercise minute parts of the codebase. The term ‘Unit Testing’ by itself doesnot state the chronological order, ie whether the code comes first and then the unit test case is written, or was it the other way round, ie whether the test case is written first. The latter is actually a simplistic definition for TDD. That is, write unit test cases first and then write code to satisfy those test cases.

 So TDD is actually the next step in the evolution of Unit Testing, in that the test cases are written upfront, before the code is written, thus providing various advantages. The code that comes out of TDD is rock solid, high quality, better designed, easily testable (especially regression testing), and easily maintainable (one of the reasons being that the test cases act as documentation). So from that perspective, the question whether TDD makes sense or not, ie whether the code should be written first and then the test case or should it be vice-versa, is a no-brainer (IMHO). TDD has come way beyond the hype stage, and writing test cases first definitely makes proven sense, but whether it will be successful or not, depends wholly on the way it is implemented, the acceptance of this within the team, and the management support to make it work. That’s asking for too much, eh? There are several pitfalls that you need to watch out for, in your journey towards TDD. We’ll examine these in a separate post.

Anyway, TDD is not the be-all-end-all of Agile. If you’re able to make it work, great, you’ll see the benefits. But if you’re not, don’t fret, there are other tenets in Agile which can be implemented easily and fetches good results. We’ll examine some of them in the forthcoming posts.
Ciao