What kind of “silly” advice? The kind that tells you never to do this or always to do that or you don’t need to do this or you need to do that. When I see someone giving advice like this, especially if they are a Big Consulting Company That Everyone Pays Attention To, I usually see a trail of frustrated comments nearby arguing about context and the like.

I used to be the person giving that kind of advice. I used to be the person annoyed by that advice. I’ve left a few frustrated comments over the years. I’m sorry about all that.

We can make use of that “obviously wrong” advice and skip the frustrated comments. I’d like to share how by starting with a common example: the structure of writing code-level tests and drawing attention to that structure in the code. A version of this that triggered my writing today was the suggestion to write comments such as these in your tests:

@Test unimportantExample() {
    // Arrange
    var subject = new SubjectUnderTest(collaborators...);
    // Act
    var result = subject.theActionToCheck(arguments...);
    // Assert
    assertEquals(expectedResult, result);

Every so often, an experienced TDD practitioner writes “You don’t need those comments”, when they often mean something more like “You don’t need those comments, just because some article somewhere called them a ‘best practice’. Try living without them for a while to give yourself a chance to decide. If you don’t need them, then stop writing them! See? Isn’t that nicer?!”

Quite often, after that, we have:

  • a handful of people saying “I do this and I like it, so shut up”.
  • a handful of people saying “Yeah, when I see this, I have to laugh. Stupid n00bs.”
  • at least one person yelling “CONTEXT!”

Yes, I understand. I’d like to rewind to the beginning and try again.

Writing Code-Level Tests: Some Advice

A code-level test has only two essential elements: an action and an assertion. Everything else is optional. We do something and describe what ought to happen when we do it; the computer checks the current behavior and yells when it’s surprised. That’s enough.

The 3 As (arrange, act, assert) and GWT (given, when, then) act as documentation: miniature checklists to help you remember what to do and headings to help others understand what you did. Making this clear in your code, such as by writing comments or extracting functions or using vertical whitespace, is entirely optional.

So, Should We or Shouldn’t We?

I don’t know. When I need to choose, I ask these questions:

  • How much does it cost to do?
  • How much does it cost to undo or remove?
  • Who would use it?
  • How would we (all) benefit?
  • Could I get (enough of) those benefits a cheaper way?
  • Would I be setting an unhelpful precedent or standard or habit by doing this? or a helpful one?

There are probably more, but these ones come to mind in the first minute of thinking about it.

These questions help me make use of advice in the form of “Do this” or “Don’t do that” or “You don’t need that” or “You need this”. Asking these questions allows me to skip the usual eye-rolling by digging for the genuine attempt to help that lies behind the crusty exterior of blaming.

So… Should We or Shouldn’t We?!

I don’t know how much it matters, but I’ll share my current habits related to writing code-level tests, just in case you find them instructive.

I call it “The 3 As”, because that’s how I learned the concept and “GWT” doesn’t make it any clearer for me. I’m old.

I use vertical whitespace to separate the action from the assertion and typically refactor my tests so that the assertion is always the last “paragraph” and the action is the second-last “paragraph”. Everything before it is preamble and you can think of it as “arrange”. The “arrange” part is sometimes a mess and that mess continually reminds me to keep trying to isolate the action further from its context.

I tend to refactor my tests so that the assertion is a single command. I do this for the design benefit: as I refactor towards a single command, that nudges me towards helpful Value structures or objects that combat Primitive Obsession.

I always prefer improving names to writing comments of any kind, and so when I write a comment, I do so due to time constraints or because the explanation needed goes well beyond the names of the surrounding bits of code. When I read a comment, I always spend a brief moment looking for a way to replace it with better names.

How Does That Feel?

When I encounter this kind of “silly” advice, I usually see the kernel of genuine help in there. With a little practice, I built the habit of looking for that kernel and bringing it out into the open where more people could see it. I feel significantly less frustration and annoyance that way.

I hope you do, too.