Step Organization

You can have all of your step definitions in one file, or in multiple files. When you start with your project, all your step definitions will probably be in one file. As your project grows, it will be easiest to split them into meaningful groups in different files. This will make your project easier to maintain.

How Cucumber finds your features and step definitions 🔗︎

Be aware that, regardless of the directory structure employed, Cucumber effectively flattens the features/ directory tree when running tests. This means that anything ending in under the starting point for a Cucumber run is searched for Feature matches. This is either the default case or the location specified with the option.

Grouping steps 🔗︎

Technically it doesn’t matter how you name your step definition files, or which step definitions you put in a file. You could have one giant file and put all your step definitions in there. But that would get very messy, and hard to maintain. Instead, we recommend creating a separate file for each domain concept.

A good rule of thumb is to have one file for each major

For example, in a Curriculum Vitae application, we might have:

The first three files would define all the Given, When, and Then step definitions related to creating, reading, updating, and deleting the various The last file would define step definitions related to logging in and out, and the different things a certain user is allowed to do in the system.

If you follow this pattern you also avoid the Feature-coupled step definitions anti-pattern.

Writing step definitions 🔗︎

Don’t write step definitions for steps that are not present in one of your scenarios. These might end up as unused cruft that will need to be cleaned up later. Only implement step definitions that you actually need.

Helper methods 🔗︎

Always keep in mind that Cucumber is simply a DSL wrapper around the programming language whose full expressiveness remains available to you in the step definition files (but not in feature files). On the other hand, do not lose sight that every step called as such in a step definition file is first parsed by Gherkin and therefore must conform to the same syntax as used in feature files.

In fact, it is recommended to refactor step definitions into helper methods for greater flexibility and easier reuse. The method can reside in the same file as the step definition.

This makes your project a lot easier to understand for people who join your project at a later date; which also makes your project easier to maintain.

Grouping step definitions 🔗︎

Avoid writing similar step definitions, as they can lead to clutter. While documenting your steps helps, making use of helper methods to abstract them can do wonders.

For example, take the following steps:

    Given I go to the home page
    Given I check the about page of the website 
    Given I get the contact details

If all of these steps just open the respective webpages, you might be writing redundant steps. While the underlying code for these steps could be different, their behaviour is essentially the same, i.e. to open the Home, About or Contact page.

As such, you can use abstract helper methods to reduce them into a single step:

Given I go to the {} page

And the following step definition:

@Given("I go to the {string} page")
public void i_want_to_open_page(String webpage) {
  webpageFactory.openPage(webpage);
}
 //TODO
 Given 'I go to the {string} page' do |page|
   open_web_page page
 end
 //TODO

Your step definitions are the glue to the actual code (in this example, a factory method to decide which page to open). They can also be used to hide implementation details by calling several reusable helper methods from one step definiton.

This helps in a number of ways,

  • Increased maintainability.
  • Increased scalablility with reusable steps.
  • Easier to understand tests.

You can handle other behaviours, like validating a webpage, clicking a button, etc., the same way.

Also, using Data Tables for providing inputs to steps helps increase maintainability and understandability.


You can help us improve this documentation. Edit this page.