Wednesday, October 10, 2007

Keep behavioural driven naming out of unit testing

Something is happening in the Test First world. There appears to be growing use of "Behavioural Driven Design" (BDD). That is, the test names in test classes are becoming sentences describing what the class should do, eg testFailsForDuplicateCustomers(). In my opinion this trend is damaging the effectiveness of Test First Design in the field.

Don't get me wrong - I think the fundamental idea behind BDD is sound. But I am finding that this kind of naming approach for unit tests is seriously detracting from the "code is the documentation" ideal. If you have a class with method "X", you should expect a test method "testX" that defines the method's contract. If the method's contract is more complex, you might expect to see a set of methods like "testX_NullInput" etc. This approach documents the class pretty damned well in my experience.

Now image the same class being tested by something like "testFailsIfCustomerIsNull". What fails? What input? Have I tested method "Y"? But method "Z" shouldn't fail if Customer is null! You end up doing some serious analysis to work out what is going on which fundamentally defeats the object of the tests replacing design documentation. Using BDD test naming here is actively obfuscating how the system works at a class level, not clarifying.

(Note - nothing that I am suggesting excuses obscure method naming. A method should do what it says and say what it does, with the detailed clarification of the contract being defined in the tests. All I am saying is that there should be a simple, obvious mapping between methods and the tests that verify their behaviours)

Where BDD comes into its own is when defining interactions. Integration tests that check the interaction of closely cooperating classes benefit hugely from descriptive naming. Also User acceptance tests reap huge rewards from the approach since the tests are described in business language that allows a Customer to understand what is being testsed. Yes, use BDD naming in these cases because it does help.

Just keep it away from Unit Tests!

0 comments: