17 May 2017

DRY and the Test Suite

So I mentioned that there are some rules we should follow when developing a test suite. One of those rules that we normally apply to code is to make it DRY (Don't Repeat Yourself). I think test suites, particularly Microtests need to observe a special form of this rule.

Typically when we make code DRY we work very hard to reduce repetition. I've seen developers go to extraordinary lengths to ensure that only the boilerplate gets duplicated and that no module of code exists twice. I've done this myself and it generally pays off well. Though I must admit, sometimes the code becomes somewhat contrived. 

I don't think this is entirely appropriate within a test suite. When I think of a Microtest I think of code that expresses essentially three things. The relevant setup, the particular execution, and a single assertion. Nothing more and nothing less. Its that nothing less that causes us to repeat ourselves. 

Consider the following pair of tests;


That code is not at all dry, but it tells a complete story of what the foo function should do. We could take this code to an extreme when we dry it out though. That might look like this;



So what is wrong here? Well, it is no longer obvious which inputs go with with outputs. I have to read both the setup code and the test code to figure out how each test works. In my contrived example here this is pretty easy, there are only two tests. But when there are dozens of tests this become much more difficult. 

Here is a reasonable compromise;



This code reveals our intent with a minimum of duplication and clearly expresses our the intent of our code. There is just enough duplication that each test will expose its intent without you having to read more code and drys out just enough code that it will be easy to maintain. 

Even if you don't like this particular example (I know, its kinda horrid), finding the balance between expressive and crafted is important when developing a suite of tests in order to ensure that the integrity of each test is maintained without making a nightmare out of your tests by duplicating everything for each test.