
While atOfferup.com I had to useCucumber to runGherkin style tests. I had not used this style of test writing before. While it seems easy and straight forward at first, I quickly realized that its flexibility would allow the wording and structure of tests to quickly diverge and become unmanageable.
Here is my approach to writing decent tests, Gherkin best practices, and how to name elements. These guidelines are designed to make the tests as understandable, concise, and flexible while reducing duplicated code. A lot of ideas were taken from thisAutomation Panda post, which is good reading.
General
- Describing behavior in a concise manner is the most important thing
- You should strive to use short phrases to accurately convey what each line is doing
- What you write should describe what you are doing, not how or why
- Feature titles should follow theScenario rules below
- Do not use the
Rules
keyword. More than one is not supported bycucumber.js, which makes it very awkward - Try to not use the
Background
keyword. Since it is common setup, it can render theGiven
sections of tests irrelevant. Leaving out theGiven
then makes the flow odd.- You could use
Background
then make a step definition for “Given The Background task passed” and have it do nothing. This would just serve to create decent Gherkin in the spec file.
- You could use
Example
Scenario: Create a new account using valid informationGivenThe user starts on the create account screenWhenThe user enters valid account informationAndpresses the"Create Account > Create Account" buttonThenThe user arrives at the"Secure Your Account" screen
The wording is concise and describes what is being done so anyone can easily see what this test does. It is also worded in a way that allows for flexibility with dynamic items (phrases in quotes).
Embedded Test Data
- Don't use scenario outlines or data tables to execute extra cases you don’t need just because you can
- This increases the execution time and increases the change of a random failure
- Most of the time one element of a behavioral set is fine to verify the behavior of all. For example, you don’t need to open up every search category if they all look the same, but you may want to do one of one type and one of another if they can result in different results.
Example
Scenario: The first message page contains the proper elementsGivenThe user is logged inWhenThe user taps the"Item > Inquire" buttonThenThe user sees these elements on the"Send Message" page|SendAMessageHeading||UserProfile||ItemDetails||NewMessageInput|
A data table is appropriate here since we want to verify a number of elements are present. One may be sufficient if we just wanted to know if we were on that page, but the Scenario clearly says we want to verify all proper elements.
Scenario Outline: Send a first message with each suggested messageGivenThe user is logged inWhenThe user taps the"Send A Message > <suggested response>" buttonThenThe first sent message is"<suggested response>"Examples:|index|suggestedresponse||0|Hi,isthisstillavailable?||1|Hi,Iwanttobuythis||2|Hi,canyoumeet?||3|WillyoushipviaFrobozz?|
Like the previous example this makes sense since we want to test each option presented to the user and each results in a different behavior.
Scenario Text
- Scenario titles should be one line, any additional info can go in the description
- Watch out for usage of "and" and "or" which can indicate the need to split into multiple scenarios
- "Because", "since", and "so" portions can be left out since they describe why you are doing this, not what
- No "verify" or "should" since that is about assertions, not describing behavior. This belongs in the steps.
Examples
Scenario Outline: Send a first message with each suggested message
Not bad, but the "suggested message" part could probably be cut or moved to theDescription
section.
Scenario: Selecting the email login method takes you to that landing page
The "takes you to that landing page" part has an implicit "should" in front of it and should probably be removed. This phrase describes a result, and that should be covered by a subsequentThen
statement.
Scenario Content
- Scenarios should be 10 lines or less
- Try to have only one
Given/When/Then
flow per scenario. This is the idea of one scenario equals one behavior. - Lengthy sections can be encapsulated into a single step definition. This could also enable reuse of behavior since it is done outside of thespec file.
- It may be possible to skip long setup sections by directly navigating to the start of the actual test. This is most appropriate for UI tests.
Examples
ThenThe user sees the"Account > Public Profile Name" elementAndsees the"Account > Public Profile Ratings" elementAndsees the"Account > Public Profile Bought Count" elementetc...
All of these conditions could be collapsed into a single step definition and replaced with something like:
ThenThe Account page contains all expected elements
Sometimes you may want to break the singleGiven/When/Then
block in the scenario: If a test depends on the state of a previous test and there is not an easier way to set up those conditions atomically. You could make a step definition and use it twice in two tests. However, this could greatly increase run time since you are executing a long section of behavior twice.
Instead, you could do something like this:
Scenario: Scrollable items can be scrolledGivenThe user is on the"Home" screenWhenThe user swipes"left" on the"Home > Category Bar" sectionThenThe user does not see the"Home > All Categories" buttonGivenThe previous block passedWhenThe user scrolls the"Home > Items Grid" section"down"ThenThe user does not see the"Home > Main Search Bar" element
The step “Given The previous block passed” actually does nothing in it’s step definition code. It is just here to provide proper Gherkin by saying what is going on. This allows you to build off previous functionality, but still break things up into individualGiven/When/Then
blocks that are atomic.
The drawback is this is really multiple tests per scenario, and will be reported as such in the results. But the time savings and code reuse is worth it.
Steps
- Each step should be less than 120 characters
- Reading each line by itself should tell you exactly what it is doing. Use the form: subject, action, predicate
- Don't spell out content that is implied, such as pressingSubmit after doing something
- Try to not depend on exact data if it doesn't matter (ex: if you just care the list has content, look for a first item, not "item equals X" in your data)
- Hide data in step definitions instead of polluting the feature with it, unless it is critical to having the step text make sense
- Like scenario titles, if you have “and” or “or” in the text, split it into multiple steps
- If you have more than one or two
And
s orBut
s, you probably need to encapsulate them into a new keyword with a more descriptive name
Example
GivenThe user is logged in as"Test Seller"Andhas at least one messageWhenThe user opens message number 1
Here the steps are short and declarative. There is some data included, but it is needed to specify an exact object acted upon.
TheAnd
clause is a separate behavior and split off like this. It also is made more generic since we just care that we have a message, not what it is or any other details.
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse