0

I used Gauge for a while and they have the idea of a concept, which is defined as "Concepts provide the ability to combine re-usable, logical groups of steps into a single unit. A concept presents the summary of a business intent by combining logical groups of steps" (Gauge conpect documentation).

With that one can easily group several steps and reuse them as a single step in another test case.

I was wondering, whether Cucumber/Gherkin has something similar ?

The background is that I have an end2end test case, which contains multiple asserts in between, which i like to untangle and create multiple scenarios. But then I would have multiple scenarios with duplicated steps - I would like to group the relevant ones and so minimize the individual steps inside the respective scenarios.

Thanks :)

emersoncod
  • 53
  • 3

2 Answers2

0

Gauge is a framework to write acceptance tests. A specification in gauge is basically a manual test script that has been made executable. Because of this it makes sense to reuse steps because they tend to describe low level operations.

Cucumber on the other hand facilitates BBD and you use Gherkin to capture the behavior of the system rather then the operations in a test. So instead of writing Login as user "Charles: and create project "Firebird" which describes operations you'd write Given Administrator "Charles" created the project "Firebird".

This is quite a shift in perspective but helps communicate clearly what the software is supposed to do rather then how it supposed to be operated.

As a result you generally avoid writing low level operations in Gherkin. Rather you extract these into methods and call these methods from your step. You can then also reuse these methods in other steps.

For example suppose we have two steps that both create a user:

  • Given Administrator "Charles" created the project "Firebird"
  • And "Jullia" is added to project "Firebird"
@Given("{role} {persona} created the project {project}")
public void persona_with_role_creates_a_project(Role role, Persona persona, Project project){
    createRole(role);
    createUserForPersona(persona);
    addRoleToUserForPersona(persona, role);
    loginUserForPersona(persona);
    createProject(project);
}

@And("{persona} is added to project {project}")
public void persona_with_role_creates_a_project(Persona persona, Project project){
    createUserForPersona(persona);
    addUserForPersonaToProject(persona, project);
}


@ParameterType("\"([^"]+)\"")
public Persona persona(String name){
   // look up the persona by name from somewhere e.g. a config file
}

ect...

private void createRole(Role role){
    // API calls to make a role here
    // For test isolation it is important you don't reuse anything between tests.
}

private void createUserForPersona(Persona persona){
   // API calls to create a user
   // Don't forget to store the credentials for the persona somewhere
}

ect..

Note that quite allot of information might be needed to create a user and project. So rather then spelling all this information out in the feature file we reference a personas ("Charles", "Firebird") which act as templates for the type of project we create. We can provide these to the step definitions objects rather then plain strings by using parameter types ({persona}, {project}). These will convert the string into an object before the step is executed.

M.P. Korstanje
  • 10,426
  • 3
  • 36
  • 58
0

In Gherkin you just create a step definition for your group of steps and use it just as in a human language. The Ruby example below illustrates a reuse of Given "a valid user" under Given "user is on the login page".

Given /^a valid user$/ do
  @user = User.create!({
             :email => "example@gmail.com",
             :password => "password"
           })
end
Given /^user is on the login page$/ do
  Given "a valid user"
  visit signin_url
end
When /^user fills in Username with (.*?)/ do |username|
  fill_in "Email", :with => username
end
And /^user fills in Password with (.*?)$/ do |password|
  fill_in "Password", :with => password
end
And /^user presses "Login"$/ do 
  click_button "Sign in"
end
Then /^user should be on the users home page$/ do 
  assert_equal (getCurrentUrl(), 
  "https://www.linkedin.com/feed/")
end
Anatoliy Sakhno
  • 146
  • 1
  • 7