DRY and Unit Tests don’t mix well

When readingsource code, I sometimes come across unappealing code(sometimes even my own).  However, there is one kind of “bad code” I see quite frequently.  It is a set of unit tests which have had the DRY (Don't Repeat Yourself) principle unduly forced upon them.  DRY is the idea that you shouldn’t have to write the same code over and over; abstract it in a function or a class and just call the abstraction.  This is all well and good in most cases, but I find it misguided when applied to a test case. 

A test case should be like a simple short story.  The characters are introduced, action/conflict occurs and then resolution takes place (sometimes with a moral).  This (kind of) corresponds to the 3 steps of a unit test: arrange, act and assert.  You arrange and setup what you need for your test to run, you perform the action that you are trying to test and then you assert the results. The issue I find is that a coder, in attempting to apply DRY to his test cases, will abstract away all of the arrange step into a function often with a name like SetupExpectations or just Setup.  This goes against the point of a test case. A test case needs to be concise and tell me everything I need to know about how that one bit of functionality works. I don’t want to jump around the test class trying to read one test case. To me, this is like reading a book that says, “If you want to learn about the characters in this book please open this other book.”  This doesn’t stop you from understanding the test, but it slows you down…and is just annoying.

 

That is why I will come out and say do not apply DRY haphazardly to test cases.