Unit Test Tip: No Conditional Logic in a Test Case

I thought I’d share my response to this e-mail from a colleague:

I find myself having huge arguments with someone at work about how to write unit tests. In particular, things like having ifs and loops in tests. I am wondering if you could send me resources about the format of writing unit tests.

The definitive resource is xUnit Test Patterns: Refactoring Test Code by Gerard Meszaros. I’ve often used the book to influence people: if you don’t agree right now I will club you with this book that I’m holding. Kidding.

Most of the book is online. In the part of the book that describes test smells, Meszaros calls out Conditional Test Logic as a code test smell. There is a section of the Result Verification chapter that describes how to Avoid Conditional Test Logic.

I prefer to write test code that is straight line code: no conditional logic whatsoever. I suggest you adopt this guideline and see how it works for you. I would be interested in seeing any of your tests where you felt that conditional logic was needed.

2 Comments

SteveJune 28th, 2011 at 12:40 pm

Hi, I’ve had a look at the website and I am very interested in continuing to read about it (no clubbing required :)).

At the moment I am looking at using Python for some development and for learning better ways to create unit tests. On this page I have found an example I wonder how you would do without a loop: http://diveintopython.org/unit_testing/testing_for_success.html

I suppose you could use list comprehension, but that’s basically a loop anyway.

What do you think?

Alistair McKinnellJuly 4th, 2011 at 3:26 pm

Steve, thank you for a great example of when it is okay have conditional logic in a test.

In your Python example, a loop is used to create a parameterized test. That is, a test that uses the same test method with different data sets.

I’m fine with this use of conditional logic in test code. I can read the test and be confident that I understand of how the test works.

I still believe that in most cases you want to avoid conditional logic in tests.

Whenever a test fails, I want to spend my time looking for the cause of the failure in the production code rather than wondering whether the failure is due to a logic error in the test code itself.

So what causes conditional logic to show up in test code? In my experience, it is due to complex test fixture setup or complex interaction with collaborators.

I use test data builders to tame complex test fixture setup and mocking to tame complex interaction with collaborators.

If I find that my test remains complex, I have a strong clue that I need to rework the design of my production code. I start by looking for these code smells: long parameter list, feature envy, data clumps, primitive obsession, and message chains.

Leave a comment

Your comment