I thought I'd post an update from my path to continuous integration nirvana...
Today's installment is things I have learnt about writing unit tests. Specifically I'm all about .Net and NUnit, but these are probabbly applicable in other scenarios too.
Name your unit tests correctlyWhat I mean to say is, name your tests as a verbose description of
what the purpose of your test is.
A good example:
<test()> _
Public Sub FooCanGenerateValidIDWhenInputValueIsNegative()A bad example:
<test()> _
Public Sub FooSaveMethodWorks()Can someone who dosen't code on your project (or better still, a non-coder) understand what the designed behaviour is for the
Foo class from your NUnit results?
But the most important reason is these tests must be granular and focused. If you can't tell me what you are testing by the name of the test it is probabbly time to step back and look at the code you are testing.
Bug fixes should have a unit testThis is in two flavours: Forwards and Backwards.
When I fix a bug, how do I know it is fixed? How can I prove it is fixed? Good bug reports are focused & granular. Add steps to reproduce and now you are talking about a good bug report.
It is also no mistake that the words
focused and
granular words are in this lesson too.
Forwards:
By the time the tests are done they should describe the desired end result of the bug report. Again there is no need to go all TDD unless you want to, but if the bug report is in the form:
An unhandled exception is thrown under some specified bad input data then your test should show that no exception is thrown with taht bad input data. Instant proof that the bug was fixed!
Backwards:
Looking at a closed bug report, how do I know what was done to fix the bug?
Looking at a broken build report because some unit tests failed, how do I know what bugs that code relates to so I can retest them?
The purpose of this lesson is to remove
well it worked on my PC from the developers vocabulary.
Writing unit tests is a mind-space thingWhile not going as far as
TDD in my current projects (caution:
there are TDD fanatics out there 
the lesson I learnt from the TDD thing is when you are writing your tests you need to put yourself in the mindspace of the client of your code. Forget for a minute
how you implemented the method and express what you
aimed to do in the method with your tests.
Confession alert: At first I thought this was a bunch of bovine compost when I read it in the Agile/unit testing/TDD echo chamber. Then, one day, when I wasn't paying much attention, I found a bug in my code through this method as I was writing it. Clouds parted, a little beam of sun light came down and touched my head. All became clear. Lay your hands on the radio, children; for we have a new believer.
Tests should be easy to writeWhen writing heaps of tests agains the same class or library or whatever, write a base class that does the setup etc and descend your
test class from this base class as a way of making the test method only contain as little code that is not the test as possible. This can make it easier to bang out plenty of tests.
Or if you want to use Code Rush or Snippites in VS2k5?
Or if you want to do absolutely anything else to make it easier to bang out unit tests?
...just do it. There is no wrong answer.
There is no need to make this harder on yourself than it has to be!