Don’t “check” or “verify” in your tests
Tags: testing, tips
Published: 2020-07-10 21:02:47

---
title: Don’t “check” or “verify” in your tests
published: true
date: 2020-04-28 14:00:00 UTC
tags: testing,tips
canonical_url: https://gerg.dev/2020/04/dont-check-or-verify-in-your-tests/
---

Clearly communicating intent is an underrated skill in writing tests. In automated tests especially it is tempting to think that since the code defines what gets checked, the human-readable parts of the test — the description or the method names — aren’t as important to get right.

I often see people define custom assertion functions to avoid duplicate code (a good thing!) but then end up giving them names like this:

```
verifySystemState() { ... }
checkReturnCode() { ... }
```

The problem with this is that instead of describing what the _system_ does, they’re describing what the _test_ does. The _test_ is going to verify the system state or check the return code. In most code this makes sense: functions should say what they do, and usually how they do it shouldn’t matter to the caller. With functions used in tests, that’s only partially true. I still might not need to know _how_ the thing is verified or checked—I can always go to the function definition for that—but as a reader care a lot more about _why_ I’m calling that function than _what_ the function does. The name should reflect that.

I see the same mistake made on test names and descriptions themselves. Constructions like this:

```
it("checks the response code", () => { ... });
```

is (incorrectly!) describing what the test does: The _test_ checks the response code. Almost every JavaScript test framework I’ve used allows using either `test` or `it` as the function name defining a test. Take advantage of what `it` here means: it’s not an abbreviation or shorthand for something technical, it’s meant to be read as the first word in that specification describing the _system_. Constructions like:

```
describe("Foobar", () => {
    it("should be a woozle", () => { ... });
    it("should return an array", () => { ... });
    it("throws an error when called with a boolean", () => { ... });
});
```

are a series of sentences describing a `Foobar`, not describing the test:

- It should be a woozle.
- It should return an array.
- It throws an error when called with a boolean.

Less charitably, this can also be a side effect of the writer not really understanding the system being tested. Take test names like these:

```
it("checks the return code", () => { ... });
it("handles arrays", () => { ... });
it("returns", () => { ... });
```

Writing “it checks the return code” might be an answer to thinking “I should probably check what the return code is” rather than thinking “This should return a 200 OK so let’s write a test for that.” All of those examples suggest the writer had an idea of what to do next but little idea why or what to expect when they did it. Even if they did, a reader trying to understand these tests in 6 months surely won’t.

Instead of being written as commands telling the test automation what to do next, these test names and methods should answer a question or be a statement of fact.

- Question: “What should the return code be?”
- Answer: “It should be a 200 OK.”

It’s useful to module them after normal assertions or expectations:

```
expect(result).toEqual(value);
expect(getSystemState()).toEqual(expectedState);
assert(response.statusCode).toEqual(HTTP_OK);
```

Wrapping the details of how we get the necessary information in helper functions, we’d use function names like:

```
expectSystemState(expectedState);
expectStatusIs200();
```

(I’m still being a bit messy here using very generic sounding names; I get equally annoyed at variable names like “result” and “value” in real test code.) The point is the structure: “_X is Y_“, not “_Do Z_“.

While you can still create better names using “verify”:

```
verifyResponseCodeIs200();
```

it’s too easy to drop the “_is Y_” part when “_Verify X_” is still a complete sentence. Slightly better, while “_Check X_” is a complete sentence, “_Check that X_” is not.

A strict rule for it would be silly, but if helps, put “check” and “verify” on your list of weasel words to avoid in test automation. While not themselves as bad gems like “correct” and “valid”, they’re enablers of ambiguity.