It should or it does?

There are two popular styles of formatting test descriptions: it('should do something') and it('does something'). Which style should you use? Is any of them objectively better, or is it just a matter of personal taste?

To help us decide, let’s take a look at should and does test styles from three points of view:

Output formatting

Let’s compare how tests for the same functionality, written in should and does styles, could print out in a console.

Should style:

Guest User
    should have temporary account
    should not have permanent account
    should be able to read posts
    should not be able to create posts

Does style:

Guest User
    has temporary account
    does not have permanent account
    can read posts
    cannot create posts

The most visible difference is that the should word acts as a “bullet point”, a constant delimiter forming a neat list. This is purely a matter of taste. Some people claim that this improves readability, making tests more “scannable”. For other people (me included) this is just a noise, that doesn’t add any useful information – and makes tests less readable.

The second, less visible difference, is how the two styles impact negations. In the should style, negation is standardized – a test always starts with either should or should not prefix, so it is immediately obvious if this is a positive or negative case. In the does style, positive and negative cases are named differently each time (e.g. has and does not have, can and cannot, writes and does not write etc.). For some people, a standardized way of negation makes tests easier to comprehend. My personal opinion is that to comprehend full implications of the test you still need to understand what exactly is being negated, so the standardized negation prefix doesn’t help much here, it only makes the description longer.

Summarizing: from the standpoint of test output readability, I prefer the does version, although it is a matter of personal taste, and there are no objective arguments for or against either style.

Documentation vs specification

There is a subtle, interesting distinction between the should and does styles. One leans more towards specification, while the other towards documentation.

A should phrase naturally fits new requirements. It sounds good when you specify a functionality that doesn’t yet exist in the system: The system should allow a user to view his payment history, The sign up should require a valid email etc.

On the other hand, should makes poor documentation. In a user manual, it sounds much better to write An eraser tool cleans the canvas than An eraser tool should clean the canvas. An end user expects that you’ll tell him how your system works, what it actually does not what it should do. (An eraser should clean the canvas – Should? So it may not clean it? Under what circumstances?)

This leads us to an interesting question: how do we treat our tests? As a specification, or as a documentation?

If you do TDD, then you write tests first, for the functionality that doesn’t yet exist. It feels natural, then, to treat them as a specification (BDD-style frameworks even explicitly call the tests “specs”). On the other hand, you don’t throw the tests away after you write the code – you leave them to act as a documentation, to helping future you and your team members remember how the system works.

So which phase is more important? On the one hand, the specification phase is crucial, because it is the phase that drives the design of the system. On the other hand, the documentation phase is much longer. You write your code once, but then you live with it often for years (re-reading it, refactoring, explaining to new team members and so on).

Personally, I lean towards the documentation (does) approach. To me, it feels more natural to read during the code maintenance phase (which, as I mentioned above, is much longer that the code creation phase) and, from my experience, using the documentation style doesn’t really hinder my ability to design code by listening to the tests during the specification phase.

Purposeful ambiguity vs clear intent

The last subtle difference between the should and does test styles lies in the perceived level of ambiguity.

The does style is uncompromising, with a clear, decisive intent. The system does that thing. If it doesn’t (if a test fails), it means that the system is broken, that there is a bug in the code.

The should style leaves more room for discussion. If you say “The system does that” there is no room for argument. If you say “The system should do that” it opens the system for questions like “Should it really? Are we sure?”. (Such an open approach is advocated by inventor of BDD, Dan North in his introductory post).

The should style also impacts how we treat failed tests. If the system only should do something, a failed test doesn’t necessarily mean that there is a bug in the code. It may as well mean that our previous assumption of what the system should do is incorrect, and that we should discuss requirements. Some people even go as far as to claim that even in the case of a regular bug the does style is a lie, because it says that the system does something, while it actually does not at the moment – thus the should style is more correct.

As far as specifying intent goes, I prefer the should style over the does. Should is more honest and it’s a better discussion starter, what’s really important if you want to be agile about your requirements.

So which style should I use?

As you can see, this is mostly the matter of very fine nuances, and in a big part purely of individual taste. Personally, I lean slightly towards the it does style. It’s less noisy and much nicer to read, and with a proper mental attitude I can still stay as open for a discussion as in the should case. However, I’m not dogmatic about it. I’m OK to work with any of the styles, as long as it’s consistently used throughout the project.

I won’t try to convince you towards either the should or does style. Choose whichever feels better to you and lets you reason more comfortably about the behavior of your system. I just hope that the above analysis will help you decide in a more conscious manner.

I’d really like to know what works for you. Which test description style do you prefer? Please share below in the comments!


What do you think?

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s