TDD – Is It Bad Practice to Write Helper Class for Unit Tests?

designtddtestingunit testing

Sometimes when writing a unit test using Test Driven Development (TDD) one may find that checking if the result is the correct one is "more complicated than one line of code", probably deserving its own function.

In that case, writing an auxiliary method or even helper/ extension class could be something that comes to mind. For instance, if you find yourself doing the same operations in many test cases, why not improve the readability of that test by refactoring it?

But then the question rises: If I am writing an utility/helper class to improve how I am writing test cases, should I unit test it? Should I be even writing that helper class at all? Is it a bad practice?


To exemplify, I will give a reduced example:

Suppose I have the following public API requirements:

  • MyList should allow values to be added to it
  • Those values need to be retrieved. Order does not matter.

To satisfy that, I am writing the following test:

public class MyListTests
{
    [Test]
    public void Add_AddingValues_ValuesArePresentInList()
    {
        MyList myList = new MyList();
        myList.Add(3);
        myList.Add(1);
        myList.Add(1);
        myList.Add(2);

        int[] expectedValues = new int[] { 1, 1, 2, 3 };
        // Assert that myList.GetValues have the same elements as expectedValues;  
    }
}

However, // Assert that myList.GetValues have the same elements as expectedValues; can be quite a non trivial task by its own if order does not matter. In fact, one could argue that testing if two enumerable have the same set of elements, including number of occurences, should be its own function.

How one should handle this situation? Should a helper class be implemented to better allow this test case? Should this helper class be united tested?


As a side note, both implementations should satisfy the test:

Implementation A:

public class MyList
{
    private List<int> values = new List<int>;

    public void Add(int value)
    {
        values.Add(value);
    }

    public void IReadOnlyCollection<int> GetValues()
    {
        return values;
    }
}

Implementation B:

public class MyList
{
    private List<int> values = new List<int>;

    public void Add(int value)
    {
        List<int> newValueAsList = new List<int>();
        newValueAsList.Add(value);

        this.values = newValueAsList.Concat(this.values);
    }

    public void IReadOnlyCollection<int> GetValues()
    {
        return values;
    }
}

This is a question about testing behavior using TDD. Not implementation. The efficiency of the implementation of MyList is not a concern.

Best Answer

Your example is probably too contrived to demonstrate why helper classes may be useful, and why they may require tests on their own. But I am working right here with a lot of automated tests, all driven by NUnit, and we have several helper classes

  • to compare the output of specific data formats in a non-brittle way (proprietary formats, or specific CSV or XML formats, standard CAD file formats, and so on)

  • to provide certain kinds of test data (especially when it is simpler and more maintainable to generate the data programmatically than to store the data itself in a serialized form)

  • for controlling some of the more complex testing steps

To be honest, most of these helper classes play a bigger role in automated tests which are not really unit tests any more. But nevertheless they are extremely useful for us, some of them would probably deserve unit tests on their own (though I guess we currently don't have many unit tests for those classes), and I don't see any "bad practice" in using or introducing such classes into a sensible testing process, quite the opposite.

Related Topic