Tuesday, December 8, 2009

Writing Maintainable BDD Specs/Tests

I will continue my thoughts on interviewing and hiring in the near future. But now I would like to add to a set of discussions, from Dale Emery and Uncle Bob Martin, on making acceptance tests maintainable or as I titled this post BDD specs/tests maintainable. Both blogs are excellent and the video is a nice demonstration of making this happen with FitNesse.

One point I want to add to is duplication versus keeping the spec/test customer understandable. Keeping them customer readable/focused is not being done by many of the tests I have seen that have duplication too. I am afraid everyone will focus on the duplication and miss the other very important details about removing, what Dale calls, the ‘incidental details’ and ‘naming essential ideas’. In my opinion these are more important in the test than the duplication. Removing duplication is second to making the intent clear which are hidden by ‘incidental details’ and confused by not getting ‘naming essential ideas’.

Naming essential ideas is better described in a combination of Domain Driven Design’s ‘ubiquitous language’ and Behavior Driven Development’s ‘getting the words right’.

I also think if removing the duplication makes it difficult for the customer to understand the tests, which are really specifications first, then you should find a better way to remove the duplication or keep it so the intent stays clear.

Some of the examples I have seen of un-clear intent lately:

  • Test of a specific gui (web or otherwise) that show the complete flow to get the application in the state to do the real test.
  1. Instead describe the current state (given step in BDD). e.g. the user is ready to purchase X.
  2. There should be other tests which describe and verify the steps in the flow prior to the ‘ready to purchase X’ state.
  3. Keep a single flow tests for each flow path but name it as such and do not display it in every tests that depends on it.
  • Tables to setup large amounts of data that contain significant amounts of ‘incidental details’
  1. Instead break these into ‘scenarios’ or separate test pages that test specific expectations.
  2. If an object in the domain is required for the tests and the important information is the date then make that clear: given a flight on SomeDate SomeTime.
  • Tables with large sets of data to verify (then BDD steps) action (when BDD steps) results
  1. Instead break these into specific steps/rows that describe the expected behavior.
  2. If flight A at some time and data should arrive the next day based on an action then state it clearly: Then flight A should arrive the day after departure because the DST time zone change
  3. If there are multiple verifications make sure each is clear why this action causes that and verify each in a different row (Uncle Bob does this is the video but does not explain why. He has a vast amount of experience and has mastered acceptance tests and probably just did it because he intuitively knew it was needed.)
I am also not saying do not test the flow. I am acutally saying the exact opposite. Test the flow and make it clear that this is being tested. Do not obscure your non-flow based functionality with flow and vice versa.

I am not saying never use tables to setup or verify data. There are times when they are helpful, and that is the key, in understanding but it is not as often as they are used.

Thanks Dale and Uncle Bob for having this conversation. I needed some help convincing others that they were creating a mess.

No comments:

Post a Comment