Pick straightforward test data

Pick straightforward. Pick fast.

Code faster by picking straightforward test data. Straightforward data is fast to write, fast to read, and fast to debug.

Let’s say we’re working in a private testing environment. We need to create a user with a username and password. What else could be more straight forward than this:

username: username
password: password

If we’re making multiple accounts:

username: username[0]
password: password

username: username[1]
password: password

The programmatic notation for the ith username is username[i], therefore as programmers it’s the straightforward choice. If only alphanumeric characters are allowed, then the brackets must be dropped:

username: username0
password: password

username: username1
password: password

If we’re making accounts in a shared environment, we’ll prefix accounts with our username and - to create an adhoc namespace:

username: tadams-username[0]
password: password

username: tadams-username[1]
password: password

If we’re making objects with nested properties, we’ll pick straightforward variable names and fully scoped values based on the variable name:

salesrep = SalesRep(name: "salesrep.name")

customer = Customer(name: "customer.name")

Fast to write and fast to read.

Don’t think, write!

Manually writing straightforwardly

Writing straightforwardly is simple and has a lot of repetition. It’s easy and doesn’t require much thinking. We’re on autopilot. Faster typing. Fewer mistakes. Faster writing.

Programmatically writing straightforwardly

Let’s say we need a test with 10 customers. Because we pick straightforward values, even a computer can make the customers.

customers = [Customer(name: f"customer[{i}].name" for i in range(10)]

Imagine if we used clever names, we’d have to write them out by hand:

customers = [
    Customer(name: "John"),
    Customer(name: "Steve"),
...

Too slow. Skip the clever names, use straightforward ones.

Vimming straightforwardly

Let’s say we have to unroll the customers loop. It happens. The customers will look like:

customers = [
    Customer(name: "customer[0].name"),
...
    Customer(name: "customer[9].name"),
]

Kind of a pain to write by hand, but vim can write most of it.

Let {Esc} mean the escape key, {C-a} mean Ctrl+a, and {Enter} mean the enter key then writing this text in vim just:

ocustomers = [{Enter}    Customer(name: "customer[0].name"),{Esc}qwyyp{C-a}q8@wo]{Esc}

Let’s break this magic down.

We’ll start with inserting boiler plate and the first customer:

ocustomers = [{Enter}    Customer(name: "customer[0].name"),{Esc}

At this point the file looks like:

customers = [
    Customer(name: "customer[0].name"),

Next, we’ll record a vim macro to “w” to copy the current customer to a new line and increment the index on the new line:

qwyyp{C-a}q

At this point the file looks like:

customers = [
     Customer(name: "customer[0].name"),
     Customer(name: "customer[1].name"),

Now comes the magic, we tell vim to run the “w” macro 8 times:

8@w

Now the file is almost ready:

customers = [
    Customer(name: "customer[0].name"),
    Customer(name: "customer[1].name"),
    Customer(name: "customer[2].name"),
    Customer(name: "customer[3].name"),
    Customer(name: "customer[4].name"),
    Customer(name: "customer[5].name"),
    Customer(name: "customer[6].name"),
    Customer(name: "customer[7].name"),
    Customer(name: "customer[8].name"),
    Customer(name: "customer[9].name"),

To close the array, do it manually:

o]{Esc}

Leaving us with the final file:

customers = [
    Customer(name: "customer[0].name"),
    Customer(name: "customer[1].name"),
    Customer(name: "customer[2].name"),
    Customer(name: "customer[3].name"),
    Customer(name: "customer[4].name"),
    Customer(name: "customer[5].name"),
    Customer(name: "customer[6].name"),
    Customer(name: "customer[7].name"),
    Customer(name: "customer[8].name"),
    Customer(name: "customer[9].name"),
]

Don’t think, read!

Debugging straightforward error messages

Imagine we see this test failure because we were clever:

AssertionError: assert 'I live at 89 E 42nd Street' == 'I live at 151 W 34th Street'

Okay, we think, what object should’ve been returned and what was returned? So…who lives where? Um. Ok, looking back in the code… 89 E 42nd Street corresponds to... Grandy, okay. And 151 W 34th street? Let me look back in the code… that’s Macy.

Ew. Too slow.

Compare it to understanding this test failure because we were straightforward:

AssertionError: assert 'I live at customer[1].address' == 'I live at customer[4].address'

Immediately you know its returning customer[4] when it should return customer[1]. Done. No thinking. Just reading a straightforward error message.

Pick straightforward. Pick fast.