“Why So Granular?”

So, I get some funny looks when I write Cucumber scenarios.

Normally what I see a lot of is scenarios written up like business specifications, like this:

Given I log into the Intergalactic Wholesale Parts shop
When I add 1 Fusion Chamber to my shopping cart
And I pay for it
Then I should get a confirmation message

Here’s how I do it:

Given I log into the Intergalactic Wholesale Parts shop
When I enter "Fusion Chamber" into the search box
And I click the search button
And I click the 1st view button
And I click on the Add to Cart button
And I click the Payments link
And I enter "Zaphod" into the first name field
And I enter "Beeblebrox" into the last name field
And I enter my intergalactic credit card number into the credit card number field
And I click on the Purchase button
Then I verify that the confirmation message says "Thank you for your purchase, Zaphod! Your delivery will arrive in 3-6 Earth weeks."

Here’s why I write them this way:

It’s Actually a Lot Simpler

The first example uses 3 different steps. Each one will have some code written for the step definitions.

The second example can be written with just 4 step definitions: one for logging in, one for clicking elements, one for entering text into textfields, and one for verifying an element’s contents.

But these can be applied across all of your scenarios that you’ll ever write. 

And it’s not magic. The click step for example basically does this:

  • (if you’re using page objects) figure out what page you’re on
  • Call up that page object dynamically
  • Take the element part of the step (ex: Search, View, Add to Cart, Payments) and normalize it to what it would look like in the page object (ex: search, view, add_to_cart, payments)
  • Extract the locator that’s defined for that element in the page object
  • Wrap a reasonable time-limited loop around clicking on the element at that locator

Regexes Work Better

With more complex steps like in the first example above, there are a lot of ways to say the same thing. No two people will describe the process in exactly the same way.

With simpler steps like in the second example, the number of possibilities is greatly decreased.

How many different ways can you say that you’re going to click on something?

  • I click the search button
  • I click the search element
  • I click on the search button
  • I have clicked on the search element
  • The user clicks the search button

A regex that can cover all combinations for the first example would be horrendous if not impossible.

But one that can cover all of the above would look like this:

/(?:I|The user) (?:clicks|have clicked|click) (?:on the|the|on) (.*) (?:button|element)$/

Regular expressions are a powerful feature of any BDD tool. If your steps are granular enough, and your regexes cover enough combinations, you can write scenarios without writing any new code. (Read more here)

We Can’t Read Peoples’ Minds

When I write a scenario, I know what’s in there because I wrote it. When you write one, it’s the same way.

If someone is getting ready to write a new test step, they have a decision to make: do I look for one that’s already made, or write one myself?

If we take time to search through the other scenarios, it takes time away from writing the test. Plus, we might think we didn’t find one and write a duplicate one. Bad for maintenance.

But: when our test steps are written based on the actions we’re doing instead of the intended results, we have a much higher chance of finding the right step, and not having to write any new code.

Shorter Tests Mask Complexity

If all of your scenarios are 3-5 lines long, it can be difficult to tell how much activity is really going on. All of the stuff in the second example is happening in the first, but it’s hidden by the more complex steps.

This makes detecting complex tests tricky. Unless you’re willing to dip into each step definition and see where the culprits are, you might have trouble seeing where there’s an unnecessarily complex test that could use refactoring.

But when all of the steps are broken out into their single actions, you can easily see when a test could maybe be broken into separate pieces. If each step makes up one action, and you find a step that does 500 things, guess what? Time to refactor.

They Shorten Your Reach

With scenarios written as in the first example: Yes anybody can write those. It’s pretty much freeform thought.

The problem is: the only people who can actually back those scenarios with runnable code are developers or automators. The audience reach for these types of tests is very short.

When writing scenarios as in the second example, yes anybody can still write those, but there’s a pretty good chance that little to no code needs to be written to get the test going.

The reach is much higher–more contributors to test scenarios (and a much faster turnaround)

They Help With Bug Reproduction

One great thing about Cucumber is that it helps with bug reproduction. If a test fails, you’ll get a colorful output of exactly where it bonked, and what was done up to that point.

If test steps are more complex, they can sometimes be ambiguous. It might not be obvious what was meant and what the test was supposed to be testing–which leads to having to ask people for clarification.

But if test steps are really granular, such as in the second example, there’s no ambiguity. The message the test is trying to convey to us, the users, is much clearer.

Much Less Code Needs Written

As said earlier: when we can boil down tests into discrete actions, we don’t need to write near as much code. The same algorithm can be applied when clicking any element on the screen–what page am I on, what element am I looking for, what’s the locator for that element, click().

And, as I wrote in an earlier post, although it’s fun to write code that tests software for you, technically we’re not paid to code. It’s perfectly valid (and encouraged!) (by me at least!) to write automation in such a way that you don’t need to write much code later.

My mutant superpower is: I see patterns in things. One pattern I see is: we make test automation out to be harder than it is.

I’ve turned that same pattern recognition skill onto test automation itself, and learned some crazy stuff in the past years. Shoot, I’m even learning breakthrough stuff every WEEK lately. 

If you’re not able to release quality software as fast as you want, there’s probably something in that space that I could help you with. Let’s connect and discuss. I’d be happy to make your acquaintance. 


2 thoughts on ““Why So Granular?”

  1. You have a great writing style,
    Keep up the good work.
    Where I work we have computerized inspection machines that check parts for different elements of conformance to the part specifications, a round part may have many radial slots that are required to be concentric to the outside diameter +or- .005″. When a part fails they simply hand it to us with a printout telling us how much it’s out of tolerance. What’s missing (and I’ve been complaining about this for over 10 years) is the axis in which it has the greatest degree of error. Or maybe they could number the slots just like the dentist numbers the teeth in your mouth.
    But instead I’m required to begin manually testing the parts with hand tools which are less accurate than the machine that told me the part was out of tolerance.
    Every time I suggest the possibility that the testing machine knows more than it’s telling us I just see people’s eyes glaze over, and it seems like they think I’m asking them to reinvent the wheel.
    Resistance is of course futile.


    1. I’ve wondered for awhile how portable software testing skills would be to tool and die work, and vice versa.

      There’s surely something that we’d both benefit from if these fields would bleed over.

      One of these days I might ask if I can come out for a field trip 😉


Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s