In Let your examples flow, Dan North describes how “Don’t Repeat Yourself” (DRY) isn’t necessarily the most important guideline for tests. While I agree with his conclusions, I think the DRY principle is still extremely important for tests.
Dan’s point is that the most important attribute of tests is that they can be read like a story. “Store a page with the text ‘foo’ in the database, simulate a web request, check that the word ‘foo’ is present in the response”.
What would happen if “store a page with the text ‘foo’ in the database” was refactored out to a setup method (or a constructor)? The test would dump us into the middle of the story. In medias res is a well know technique for fiction. It’s not as useful for software.
So Dan recommends against overapplying “Don’t Repeat Yourself” in tests.
I would echo this recommendation, but not quite. Anyone who has maintained a large suite of unit tests knows that duplication can be devastating for maintainability. So I often have custom “assert” methods (
assertNoErrors(ProcessedEntity) is my favorite), I make sure my domain objects are easy to construct from test, and sometimes, I construct classes which are only used to support tests.
The important fact is that this reused code is called directly from the flow of the test method and the names of the methods and classes have been chosen carefully to ensure that the tests read well.
So: Do follow the DRY principle in tests. But do avoid “magical” setup methods.