How to write a test when the test implementation isn’t obvious

by Jason Swett,

Why testers often suffer from “writer’s block”

When you write a test, you’re carrying out two jobs:

  1. Deciding what steps the test should carry out
  2. Translating those steps into code

For trivial tests, these two steps are easy enough that both can be done together, and without conscious thought. For non-trivial tests (especially tests that include complex setup steps), doing both these steps at once is too much mental juggling for a feeble human brain, or at least my feeble human brain.

This is when testers experience “writer’s block”.

Luckily, there’s a way out. When the implementation of a test eludes me, I consciously separate the job into the two steps listed above and I tackle each one at a time.

How to overcome writer’s block

Let’s say, for example, that I want to write an integration test that tests a checkout process. Maybe I can’t think of all the code and setup steps that are necessary to carry out this test. I probably can, however, think of the steps I would take just as a regular human being manually testing the feature in a web browser. So, in my test file, I might write something like this:

scenario 'create order' do
  # create a product
  # visit the page for that product
  # add that product to my cart
  # visit my cart
  # put in my credit card details, etc.
  # click the purchase button
  # expect the page to have a success message
end

Now I have all the high-level steps listed out. I can tell my brain that it’s relieved of the duty of trying to hold all the test steps in memory. Now my brain’s capacity is freed up to do other jobs. The next job I’ll give it is translating the steps into code.

I’ll start with the first line.

scenario 'create order' do
  electric_dog_polisher = create(:product)
  # visit the page for that product
  # add that product to my cart
  # visit my cart
  # put in my credit card details, etc.
  # click the purchase button
  # expect the page to have a success message
end

That was easy enough. Now I’ll move onto the next line.

scenario 'create order' do
  electric_dog_polisher = create(:product)
  visit product_path(electric_dog_polisher)
  # add that product to my cart
  # visit my cart
  # put in my credit card details, etc.
  # click the purchase button
  # expect the page to have a success message
end

And I’ll go down the comments, line by line, translating each line into Ruby code.

Not every step will be trivially easy. But at the same time, it’s unlikely that any individual line is all that hard. What’s hard is trying to solve 26 different problems at once in your head. The way to make progress is to break those problems down into tiny parts, get those parts out of your head and onto the screen, and then tackle the tiny parts one at a time.

Leave a Reply

Your email address will not be published. Required fields are marked *