We always tell you how we test our features and what tools we use to do this. As an example, we had good practice posts on acceptance tests and how to think about testing early in the quality process within our agile team with Cucumber.
We adopted Cucumber to create our acceptance tests and applied some usage practices to maintain the quality of the test code and how to reuse it. I will bring some of these practices to help you know how to best use this tool.
1. Use Background and be DRY
When we started to learn how to write Gherkin our focus was to go out writing all the scenarios and, I do not know, but at some point, I’ve already repeated some steps that were used in all the other scenarios that I was describing in that Feature.
Until one day I discovered that there is a reserved Gherkin word known as Background. When writing using a context, we can add steps that are repeated in all scenarios, avoiding matching responsibilities and rework if there is any change in the feature.
An example is a functionality of creating users in an application:
No Background
@create_users @javascript Feature: Create new users In order to create new users As a App user I want to have access to the App Scenario: Show success message when create user with all information filled Given I have logged in And I have access to the Create Users App And I am on create new user page And I insert all of user information When I click on save button Then I should see a success message Scenario: Show error message when try to create user without email Given I have logged in And I have access to the Create Users App And I am on create new user page When I do not fill the email And I insert all of other user information And I click on save button Then I should see an error message
With Background
@create_users @javascript Feature: Create new users In order to create new users As a App user I want to have access to the App Background: Given I have logged in And I have access to the Create Users App Scenario: Show success message when create user with all information filled And I am on create new user page And I insert all of user information When I click on save button Then I should see a success message Scenario: Show error message when try to create user without email And I am on create new user page When I do not fill the email And I insert all of other user information And I click on save button Then I should see an error message
Yes, the Background is a Rspec Before type used in the code. If Before hooks and Background exist in your test before the hooks run first.
2. Learn more about so-called Scenario Outline
See the following situation:
Scenario: Show a sum result when I execute a sum operation Given I am on the calculator When I press the number 4 And I press the number And I choose the sum operation Then I should see the 6 as result Scenario: Show a subtraction result when I execute a subtraction operation Given I am on the calculator When I press the number 4 And I press the number 2 And I choose the subtraction operation Then I should see the 2 as result Scenario: Show a multiplication result when I execute a multiplication operation Given I am on the calculator When I press the number 4 And I press the number 2 And I choose the multiplication operation Then I should see the 8 as result Scenario: Show a divide result when I execute a divide operation Given I am on the calculator When I press the number 4 And I press the number 2 And I choose the divide operation Then I should see the 2 as result
Observing the above situation, notice that the 4 scenarios created have the same validation for the result and practically the same steps. Also, think that you now want to make scenarios for more operations on the calculator. Does not look cool, does it? Since it does not scale and makes maintenance difficult.
So, Cucumber brings us a way to organize these scenarios and keep them as Scenario Outlines are, or if you want to call Scenery Schemes.
When you use Scenario Outlines, you create a table of examples where each row of it will represent a scenario. Going back to the 4 scenarios presented above, it is as if you create variables for the values that change in each scenario and use them on the table. Stays like this:
Scenario: Show a right result when I execute an operation on calculator Given I am on the calculator When I press the number <number_one> And I press the number <number_two> And I choose the <operation> operation Then I should see the <result> as result Examples: | number_one | number_two | operation | result | | 4 | 2 | sum | 6 | | 4 | 2 | subtraction | 2 | | 4 | 2 | multiplication | 8 | | 4 | 2 | divide | 2 |
The first row of the table represents the written variables as <variable>you use them in the scenario, and the other lines are the examples for running the tests with their respective expected results.
See how easy it is to write and maintain scenarios? Besides being more readable as well.
3. Write more declarative and less imperative scenarios
According to Hugo Baraúna in his book Cucumber and Rspec, Cucumber is more a documentation tool than test automation. Moreover, writing acceptance tests in Gherkin requires clarity as our primary goal.
That is why most of the tips that are ready here are always intended to make it easier to understand what we transpose in our Gherkin file. The next one is related to the relevance that we give in some scenarios for steps with many unnecessary details.
For these scenarios, we call them imperatives, that is, they describe what the behavior of the scenario should be like and not exactly what it wants. For example:
Scenario: Show success message when creating new user Given I am on the Create Users App When I click on the "Create" button And I fill in the "Name" field with "user 1" And I fill in the "Email" field with "[email protected]" And I fill in the "Password" field with "password" And I fill in the "Phone" field with "123456" And I fill in the "City" field with "City" And I fill in the "Country" field with "My country" And I click on "Submit" button Then I should see "User saved"
Note that there are several steps with lots of detail that are not relevant to the person reading this scenario. There are many fields such as: name, email, password, phone, city, country and all this can take focus from what really matters: the successful creation of a new user at the base.
Refactoring the Gherkin, we would have something like below, known as a declarative scenario, which describes what is really valid for understanding what is being validated, improving its readability:
Scenario: Show success message when creating new user Given I am on the Create Users App When I fill user information And I click on submit button Then I should see "User saved"
You may notice that those details regarding the name, email, phone and other user information have been removed and it became clearer what our scenario really wants to validate. In this way, we can scale when there is a change in some field of the screen since it will be necessary to change only the implementation in the steps definitions and not the file .feature and the description of the steps definitions.
All right with our scenarios and we already know that a good practice is to leave the tests more declarative to the point that everyone reading the documentation you created, understand what is described and what should be validated in the test.
However, we must be careful in the following case:
Scenario: Show success message when creating new user Given I have logged in When I fill all information Then I should see a message
Notice how much this scenario is generic, without many indications of what will be validated and without business rules, which means that it will not be used as documentation or for automation.
4. Make use of “And” and “But”
I’ve encountered several cases of people who used the reserved words Given, When and Then more than once in their tests. It is not wrong to repeat, but it can become very confusing and incoherent for anyone who will read the scenario.
Observe the example below:
Scenario: Show error message when try to create user without email Given I have logged in Given I have access to the Create Users App Given I am on create new user page When I do not fill the email When I insert all of other user information When I click on save button Then I should see an error message
The words “Given” and “When” are repeated several times in the test and thus can easily be changed to “And” in the above scenario. Like this:
Scenario: Show error message when try to create user without email Given I have logged in And I have access to the Create Users App And I am on create new user page When I do not fill the email And I insert all of other user information And I click on save button Then I should see an error message
The “And” and “But” that you will change will have the same behavior of “Given” and “When” repeated. If you realize when you convert them to steps-definitions, they will have the same naming, but the description of their functionality will be easier to read and understand.
5. Consider Using Tags
Now imagine that you have several specified scenarios of different features and there is so much specification that when you run the tests on the terminal with Cucumber, you cannot know if it was for a given test to run if there was any delay caused by some very test Slow or if a test that was not coded was able to make your whole test suite fail.
It seems difficult to solve, but it’s not when you start using the tags that Cucumber gives you. To use a tag you create a word that means something about the context you want to differentiate from other scenarios, and prefix that word with one @by adding it before the reserved words Feature and Scenario Like this:
@create_users @wip Feature: Create new users In order to create new users As an App user I want to have access to the App Background: Given I have logged in And I have access to the Create Users App @basic_user Scenario: Show success message when creating user with all information filled And I am on create new user page And I insert all of user information When I click on save button Then I should see a success message
Explaining the tags I’ve added: a @create_users refers to the feature that is described and indicates that all tests are related to creating users on the system and this tag will be inherited by all of them. The tag @wipindicates “work in progress” and helps us here in the QAs chapter not to run tests that are not yet ready and can break the entire test suite.
The last tag @basic_user was added only for the scenario that has the user’s pre-condition logged on to the system profile, which has few privileges, but is necessary for it to be able to perform the scenario. In addition, you can add tags to Scenario Outlines and their Examples.
Here in our QA team, we use a lot of tags because we are divided into teams for each feature we have developed, and so we produce many scenarios that would be much disorganized when we wanted to run all the tests in our suite. Therefore, we decided to adhere to the tags with the names of each team that facilitates our way of executing, as well as reporting system failures.
Conclusion
All that I have said that these are the best practice tips and recommendations that we use here in Digital Results, to help you produce clearer, more cohesive documentation. Some tips are quite relevant, but not all, so I decided to split this post into two parts. In the next part, you will learn more about how to write better Steps Definitions and how to make good use of them, in addition to joining the tips I passed related to writing Gherkin.
Do you use Cucumber to create your acceptance tests? Have you used any of the above tips? Tell me in the comments.