Respect your test code #1: Hide object instantiation behind methods with meaningful names

One thing, that I find really annoying, is that somehow it seems to be accepted that test code creates instances of this and that like crazy! In a system I am currently maintaining with about 1MLOC where ~40% is test code, I often come across test fixtures with something like 20 individual tests, and each and every one of them creates instances of maybe 5 different entities, builds an object graph, runs some code to be tested, and does some assertions on the result.

This is a super example on how to write brittle and rigid tests, because what happens if the signature of one of the ctors changes? Or the semantics of the object graph? Or [insert way too many ways for the test to break for the wrong reasons here…].

When I come across these tests, I usually factor out the creation of all but the most simple objects behind methods with meaningful names. This has two advantages: 1) It’s more DRY because they can be re-used, and 2) It serves as brilliant documentation. Consider this rather simple assertion that requires a few objects to be in place:

compared to this:

MUCH more clear! The factory method acts as brilliant documentation on which aspects of the test are relevant to the outcome – it is clear, that a mortgage deed which has not yet begun its amortization must report its first term date as the actual principal date.

Go on to test another property of the mortgage deed before amortization:

– and we have already saved us from writing 50 lines of brittle rigid test code. Keep factoring out common stuff, so that the ctor of the mortage deed is still only called in one place… e.g. create methods like this:

which allows me to write cute easy-to-understand tests like this:

This is also a good example on how to avoid writing // bla bla comments all over the place – it’s just not necessary when the methods have sufficiently well-describing names.

Respect your test code

Sometimes I think it is funny to reminisce a bit about where I was and where I am now. One area where I think I have moved quite a lot, is in regards to testing! And I can’t help to think that part of this “journey” was necessary to learn what I think I have learned, but somehow I still can’t put off the thought that I might have gotten here quicker if someone had told me some basic stuff… therefore, I will try to capture in this post a few points, that I pay attention to when writing tests – in hopes that someone might benefit from a little guidance, and hoping not to be categorized as an old man rambling on about his own percieved experience.

To make it more digestible, I will list some points and show examples on why each point is good where I see fit.

  1. Hide object instantiation behind methods with meaningful names
  2. Create base classes for your test fixtures
  3. Make your tests orthogonal