Blog from June, 2015

Even when automating UI tests, it is important to keep your scenarios as readable as possible, or you threaten to lose all benefits from a plain-text approach.  In this post I’ll give you some tips that can help you with the basics.

1 Organize your features

Over the course of time you will probably end up having many features and scenarios.  Try to define features logically and avoid having very large feature files containing many scenarios.  Organize your features in separate folders.

2 Use tags

Tags are a great way to group scenarios or features.  A simple example:

tags.png

All feature runners allow you to filter on any combination of tags.  

You can attach any meaning to tags, but I’ve frequently seen them used to indicate long-running scenarios or to group scenarios based on the external integrations they need.

A Scenario or Feature block can have multiple tags, separated with spaces or newlines. If you add a tag on a Feature, it will automatically be added to all Scenarios and Scenario Outlines of that Feature.

3 Use meaningful scenario and feature names

Try to summarize the gist of a scenario in a single line.  Both scenario and feature names are used in the reports, so it really helps if you do not stick to a single-word-says-all approach.

Consider the following example:

names-bad.png

It does not take much effort to add more information:

names-good.png

4 Add a feature or scenario description where useful

If you cannot put enough information in the feature or scenario name, consider providing a more elaborate description.  You can add any kind of text below a Feature up until the first Scenario, Scenario Outline or Background statement.  If you want to add a description at the beginning of a scenario you can do so using a docstring:

descriptions.png

5 Use the reserved words meaningfully (or don’t use them at all)

Gherkin (the Cucumber syntax) has only a couple of reserved words, but I’ve seen the Given/When/Then keywords misused in many places.  A simple example explains the correct use of Given/When/Then:

given-when-then.png

Use Given to put the system in a known state.

 Use When to perform the user actions.

Use Then to verify the outcome.

Use And and But

If you have multiple Given/When/Then statements you should combine them using And steps instead of repeating the same keyword over and over again.  This way the overall structure of your scenario remains more clear.  Consider the following example:

keywords-bad.png

With only repeating And you get the following improved result:

keywords-good.png

Use * if you are not really testing anything at all

If you are not really writing a scenario but simply using CWB as a browser script runner, then it does not make much sense to use the Given/When/Then structure.  All you’re doing is executing steps in sequence.  In that case you can drop the keywords and start every step with a *.

keywords-none.png

6 Structure large scenarios with comments

Usually it is best to keep your scenarios as short as possible, but sometimes there’s just no easy way around writing that lengthy test.  Apart from the reserved words, the only alternative to add some structure to a single scenario is to introduce comments that give context about what’s happening… especially if the steps are not self-explanatory.

comments.png

7 Use backgrounds (wisely)

If you have multiple scenarios performing the same steps in the beginning, you can extract those steps into a Background section.  Each feature can have one Background section and it should be positioned before all Scenarios and Scenario Outlines.

The Background is executed before every Scenario or Scenario Outline example.

However, be careful that in case you have a long background and many scenarios in a single feature: it might become unclear what is involved in running the scenario.  Consider refactoring the scenarios to Scenario Outline examples instead, or create a custom step to perform the required actions.  If none of those are possible, you can still add a comment or scenario description that explains the state created by the background.

backgrounds.png

Note that just like a scenario, you can give a background a name and description.

8 Know thy steps

Writing readable scenarios comes down to using the most appropriate step for the job.  Sometimes there’s more than one way to perform the same action, consider for instance the following form posting example from the SAHI library:

know-thy-steps-bad.png

Which could also be written like:

know-thy-steps-good.png

A list of all standard steps available can be found in the user documentation language reference.

9 Don’t be shy of custom steps

Even though the CWB libraries come with a bunch of standard steps, there’s absolutely no requirement to stick to those.  When a standard step becomes very unreadable, consider writing a custom step instead.  Especially if you see the same group of steps coming back all over the place, bunch them up in a single custom step to improve readability.

After all, the following classic example:

custom-steps-bad.png

is easier to understand if you rewrite it like:

custom-steps-good.png

Note that if you want to create a loop or apply some conditional logic, a custom step is pretty much the only way to go about this.

 

Test readability entails basic housekeeping of your entire test suite.  Simple best practices like the ones presented in this post can go a long way there.  These practices can be applied to Cucumber scenarios in general.  In a follow-up post I’ll provide some additional tips focusing on improving readability of website tests using the SAHI library of CWB.

If you have any additional tips of your own, don’t hesitate to share them in the comments.

 



Chrome browser options

Common browser options that we configure in browser_types.xml for Google Chrome (for optimal behavior as well as mobile emulation):

Normal browser

--user-data-dir=$userDir\browser\chrome\profiles\sahi$threadNo --incognito --proxy-server=localhost:9999 --no-first-run --start-maximized --disable-popup-blocking --test-type --ignore-certificate-errors --disable-save-password-bubble --disable-translate --disable-client-side-phishing-detection --safebrowsing-disable-auto-update

iPhone

--user-data-dir=$userDir\browser\chrome\profiles\sahi$threadNo --incognito --proxy-server=localhost:9999 --no-first-run --disable-popup-blocking --test-type --ignore-certificate-errors --disable-save-password-bubble --disable-translate --disable-client-side-phishing-detection --safebrowsing-disable-auto-update --user-agent=Mozilla/5.0.(iPhone.U.CPU.OS.3_2.like.Mac.OS.X.en-us).AppleWebKit/531.21.10.(KHTML.like.Gecko).Version/4.0.4.Mobile/7B334b.Safari/531.21.10 --window-size=339,659

iPad

--user-data-dir=$userDir\browser\chrome\profiles\sahi$threadNo --incognito --proxy-server=localhost:9999 --no-first-run --disable-popup-blocking --test-type --ignore-certificate-errors --disable-save-password-bubble --disable-translate --disable-client-side-phishing-detection --safebrowsing-disable-auto-update -user-agent=Mozilla/5.0.(iPad;.CPU.OS.7_0.like.Mac.OS.X).AppleWebKit/537.51.1.(KHTML,.like.Gecko).Version/7.0.Mobile/11A465.Safari/9537.53 --window-size=1042,859