Using Cucumber with outlined best practices in your automated tests ensures that your automation experience will be successful and that you’ll get the maximum return on investment (ROI). Let’s review some important best practices needed before you start developing Cucumber tests.
Feature files help non-technical stakeholders engage and understand testing, resulting in collaboration and bridging the communication gap. For this reason, well-written feature files can be a valuable tool for ensuring teams use the BDD process effectively.
Here are some suggested standards for Cucumber Feature files:
|Organization||Feature files can live at the root of the /features directory. However, features can be grouped in a subfolder if they describe a common object. The grouped filenames should represent the action and context that is covered within.|
|Feature Files||Every *.feature file consists in a single feature, focused on the business value.|
|Background||The background needs to be used wisely. If you use the same steps at the beginning of all scenarios of a feature, put them into the feature’s background scenario. The background steps are run before each scenario.|
|Scenarios||Keep each scenario independent. The scenarios should run independently, without any dependencies on other scenarios.|
|Scenario Outline||If you identify the need to use a scenario outline, take a step back and ask the following question: Is it necessary to repeat this scenario ‘x’ amount of times just to exercise the different combination of data? In most cases, one time is enough for UI level testing.|
|Write Declarative Scenarios, Not Imperative||The declarative style describes behavior at a higher level, which I think improves the readability of the feature by abstracting out the implementation details of the application.
Scenario: User logs in
Scenario: User logs in
Just avoid unnecessary details in your scenarios.
|Given, When, and Then Statements||I’ve often seen people writing the Gherkin syntax confuse when to put the verification step in the Given, When, Then sequence. Each statement has a purpose.
Just remember the ‘then’ step is an acceptance criteria of the story.
|Tagging||Since tags on features are inherited by scenarios, please don’t be redundant by including the same tags on scenarios.|
Write Step Definitions
Cucumber doesn't know how to execute your scenarios out of the box. It needs Step Definitions to translate plain text Gherkin steps into actions that will interact with the system. Step definitions are defined in Ruby files under features/step_definitions/*_steps.rb.
Here are some suggested standards for Cucumber Step Definition files:
|Step Definitions||Keep the step definitions unique. If your step definition names aren’t unique, then you will find during runtime the following exception is thrown - ambiguous match.|
|Hard-coding||As you know you shouldn't be hard coding parameters into your code. This applies to site URL’s as well to allow flexibility to globally change the value.|
|Reusable Objects||At the beginning of any automation project, you need to think about scalability and maintainability. A good programming practice is Don’t Repeat Yourself (or DRY) by creating reusable code. You will find many different ways to share code between Cucumber scenarios. Be careful!
Why use the Page Object Pattern?
|Code||No sleep statements. It is better to use method or function with a built-in timeout.|
|RSpec Expectations||The rspec-expectations library is bundled with many built-in matchers for testing validation. Each of the matchers can be used with expect(..).to or expect(..).not_to to define positive and negative expectations respectively on an object under test. I recommend using rspec-expectations matchers over Selenium matchers for Ruby testing frameworks.|
Adding Cucumber to a Ruby project is easy. Some of the configuration files needed include:
|cucumber.yml||It simplifies command-line execution by defining reusable profiles within the cucumber.yml file.|
|Gemfile||The Gemfile is used to manage dependencies for a Ruby project. We should also pin the versions of these Ruby gems. If you don’t pin a Ruby version, it will auto update and break your automation.|
|Rakefile||Rakefile is a software task management and build automation tool. It allows you to specify tasks and describe dependencies as well as group tasks in namespaces.|
|support/env.rb||The support/env.rb is an environment configuration file for Cucumber. This file is designed to provide flexibility by allowing you to do things easily, like toggle your execution environment from local to remote. To fully understand all the capabilities of this support file, you should take more time to read up on all of the capabilities.|
At the End of the Day
BDD (Cucumber) allows for team collaboration early in the planning and development phases. Keep the numbers down. Ask yourself and the team: “If I can write a low-level test for this user story, should I write an UI acceptance test?” We should automate only the things that need to be automated at the UI level. It is a known fact that low-level tests are more reliable compared to UI tests. Cucumber is code, and all types of programming require thoughts upfront before writing automated tests. It is so important to lay a test automation foundation that embraces coding standards and follows design patterns that everyone will follow during automation development.
Greg Sypolt (@gregsypolt) is a senior engineer at Gannett and co-founder of Quality Element. He is a passionate automation engineer seeking to optimize software development quality, while coaching team members on how to write great automation scripts and helping the testing community become better testers. Greg has spent most of his career working on software quality — concentrating on web browsers, APIs, and mobile. For the past five years, he has focused on the creation and deployment of automated test strategies, frameworks, tools and platforms.