Monday, September 14, 2009

Failed attempt to apply Tdd response

This is a response to the post "Why my attempt to apply tdd failed?" on the whyjava blog. I am a test-infected developer and I want to give some support to whoever had the courage to change and adopt new methodologies.

In the post the author makes a list of points which summarize the difficulties encountered while trying out Test-Driven Development. I have some comments on this list, but before analyzing it in depth I remind you that the TDD mantra is red-green-refactor. Keep in mind it every single minute since it's easy to drift away without noticing it.
  1. Time lost: this is a classic myth about TDD, but it's true that initially writing tests will require time that has to be subtracted from writing production code. But if you look at the overall picture, you will find out that tests will save you more time in the long run that the amount spent to write them. While debugging and maintaining an application having a safety net composed by good unit tests is an aid that I won't exchange even with source control. Tests also act as a documentation and this will save time for new developers who has to learn how the components works together. They also keep regression out of your project.
  2. Boring to write test cases: while practicing TDD, a developer has to find his own balance within test the obvious and not test anything. Experience at this game will make you not test getters and setters.
  3. Client support: the client does not want the developers to write tests. Besides the fact the working in this way the client is never going to know if the application works, I would find strange to tell my surgeon I don't want you to use that bistoury, I have my Miracle Blade at home.
  4. Writing exhaustive test cases: "I think tdd will make sense when you are able to cover most of the scenarios in your test class". You're right, but since in TDD you write the test cases before any production code, and only the absolutely necessary production code to make those tests pass, there's only covered scenarios. If you find a feature which is not covered by a unit test it means it has been developed before them, which is not TDD anymore.
  5. Patience: of course every technique has its learnign curve. TDD is no exception.
  6. Poor examples: if you think books are teaching you by simplicistic situations, simply download an open source software which is developed with TDD.
  7. Legacy code: it's hard to replace old (maybe procedural) code with a TDD approach, and this is a valid point. However, you should apply TDD for new features if the design allows this.
I hope to have inspired the reader to embrace Test-Driven Development, or to continue his journey in it. Becoming test-infected was like seeing the Light for me, and I think I'm becoming a better developer every day because testable code leads to decoupled and reusable code.

7 comments:

Roberta said...

great post! however, when u say "...since in TDD you write the test cases before any production code, and only the absolutely necessary production code to make those tests pass, there's only covered scenarios. If you find a feature which is not covered by a unit test it means it has been developed before them, which is not TDD anymore.", i cant stop thinking about code that is not suitable for tdd, like IO operations, database access, etc. I mean, thats production code too, but it cant be covered with unit tests.

Giorgio said...

Tipically the low level code is insulated in adapter classes which can be mocked easily. This means you have a fake database adapter which you use in tests and a real one that is a pure wiring layer. If the database access is already object-oriented like in Java, you can mock out its classes directly.

Omar said...

Hi Giorgio,

Can you point us to an open source project that's a good example of TDD?

One of the biggest issues that I've had is testing database applications, if you've any tips on this it would be much appreciated!

Thanks,

Omar

Giorgio said...

I don't know what is your language of choice, but in php I often refer to the Zend Framework. However, the point of testing is to insulate the domain classes from the database to allow indipendent testing; I'll write an article on this subject today.

Artur said...

I would second Omar here - can you provide a link for open source project of reasonable size (50k+ LOC let's say) which is fully TDD? Extra points if it is multithreaded thing (single-threaded applications are bit too obvious to test in many cases).

I had a friend to used to say that you can give him any non-trivial multithreaded code written by somebody and he will be always able to find at least few bugs (and also to make it faster that it is currently, but it is not a point). I would like to have the example of TDD project proving him wrong.

Bob Lauer said...

@Omar: Most testing frameworks have been TDD'ed (e.g. Mockito).

bicyclerepairman (the python refactoring tool) is quite an extreme example with its verbose tests.

Giorgio said...

Roberta, Omar, I wrote up an article to answer your questions:
http://giorgiosironi.blogspot.com/2009/09/how-to-tdd-database-application.html

ShareThis