Often a situation faced by coders, especially when following test-driven development, is the writing of very similar test cases, changing only in, for example, the expected and actual values, along with some set up parameters. We often end up writing dozens, nay hundreds of near identical test cases, and end up with a test class that looks that it has suffered from a terminal case of copy-paste. This blog post shows a little-known technique for making this sort of test class a little more readable using the nUnit TestCase attribute.
Repetitive test cases
I am one of the QA developers at thetrainline.com, and am often called upon to guide the testing strategy. I’m an advocate of TDD, and also often write tests at an end-to-end level, often turning out to be repetitive and similar to each other. This situation is common enough when I’m not involved in the dev cycle until code is complete, but it more often crops up when I’m called upon to pair on the coding part of a dev task.
At thetrainline.com, the vast majority of our software uses the .NET framework to implement our solutions, and nUnit to write our tests. We have a lot of TDD practitioners amongst us (me included), and often when writing tests on a class, I end up writing dozens of tests that essentially behave the same way save for a few small details.
By way of example, I wrote a class that calculates terms of the Fibonacci sequence, defined by the following recursive equations.
Ignoring the fact that there exists a formula for calculating the Fibonacci sequence, namely
we can easily write a recursive method to calculate the general term of the sequence.
And being a good TTD practitioner, in parallel, we have written a test class like this.
This test class makes sure that our Fibonacci generator class will generate terms in the sequence in an acceptable amount of time. (The more observant of you will notice that the last couple of tests take approximately infinite time to run. Exercise for the reader to work around that problem…)
The nUnit TestCase attribute
What a lot of developers would do to DRY this code out is to generate a generic test, and call this in each of the test cases, thus, something like this.
In fact, coming from the Java world, this appears to be one of the only options.
However, in cases like this, you can use nUnit’s ‘TestCase’ attribute to DRY this out even further.
which is probably as readable as you’re going to get this.
By using the nUnit TestCase attribute, we’ve removed all the boiler-plate code of the original test suite, avoided a whole load of copy and pasting, and made the test class much more easily maintainable and DRY than we would have otherwise have managed.