Monday, July 02, 2007

Unit testing (from objectives)

Still responding to the questions posted in response to my TDD and objectives entry. The question was about how to do TDD, specifically UI and also about what happens when the general consistency fails.

Well the UI question is easy: You can’t really do TDD for user interfaces.  You can, but you have to jump through hoops to get your test framework to push buttons.  Of course there are tools which will do this for you but these usually fall into the realm of ATDD (Acceptance TDD) and system testing.

But, what TDD can help you with is the logic behind the UI.  We all know we should separate program and business logic from the UI but we also all know it has a habit of getting in there.  Well if you are practising TDD you separate the two (as you know you should) and you can TDD the logic and leave the UI as a lot more trivial. (And testable with other tools.)

The other way of doing it is to test the output.  Increasingly application emit XML or HTML to generate their user interfaces and you can test that.  You can test small segments of XML to see if it contains the expected data.

For me the secret of TDD is that it is a Design technique, thats what the second D stands for after all.  It is about designing your code with tests rather than UML, or flow charts or what ever.  You do it before you write the code, it forces you to think about what you are about to write and that is design.

Second part of the question: general consistency.  Well, true, a little change might break a lot of tests, but actually you want that to happen.  If someone removed operator== then you want your tests to break because it highlights the change. 

A good set of tests round your code ensures that any unexpected changes are found quickly.

Of course, when you make a significant change in your code you might find a lot of tests broken, and you end up having to fix lots of tests but:

  • Firstly a major change should product major breakage so you can get it right

  • Second a well structured, properly separated design, will be less prone to breaking.  Writing tests is itself an engineering exercise.

All in all TDD promotes a lot of good practises which we know are good but somehow forget to do.