Saikat...
Saikat...

Reputation: 767

Need to execute a step (each feature may have diff step) only once before a Cucumber feature file

I want to execute a specific step only once before each cucumber feature files. A cucumber feature files can have multiple scenarios. I don't want Background steps here which executes before each scenario. Every feature file can have a step (which is different in each feature) which will execute only once. So i can't use that step into before hook as i have a specific step for every 20 features. Sample Gherkin shows below:

Scenario: This will execute only once before all scenario in this current feature
When Navigate to the Page URL

Scenario: scenario 1
When Some Action
Then Some Verification

Scenario: scenario 2
When Some Action
Then Some Verification

Scenario: scenario 3
When Some Action
Then Some Verification

I hope you guys understand my Question. I am using Ruby Capybara Cucumber in my framework.

Upvotes: 3

Views: 1916

Answers (5)

moertel
moertel

Reputation: 1559

Some suggestions have been given, especially the one quoting the official documentation which uses a global variable to store whether or not initial setup has been run.

For my case, where multiple features were executed one after another, I had to reset the variable again by checking whether scenario.feature.name has changed:

$feature_name ||= ''
$is_setup ||= false

Before do |scenario|
  current_feature_name = scenario.feature.name rescue nil
  if current_feature_name != $feature_name
    $feature_name = current_feature_name
    $is_setup = false
  end
end

$is_setup can then be used in steps to determine whether any initial setup needs to be done.

Upvotes: 0

diabolist
diabolist

Reputation: 4099

This must be in the top 5 most frequent questions on the Cucumber mailing list. You can do what you want with hooks. However you almost certainly should not do what you want. The execution time you save by taking this approach is totally outweighed by the amount of time and effort it will take to debug the intermittent failures that such an approach generally leads to.

One of the foundations of creating automated tests is to start from a consistent place. When you have code that setups key things in scenarios, but that is not run for every scenario you have to do the following:

  1. Ensure your setup code creates a consistent base to start from (this is easy)
  2. Ensure that every scenario that uses this base, does not modify the base in any way at all (this is very very difficult)

In your example you'd have to ensure that every action in every scenario ends up on your original page URL. If just one scenario fails to do that, then you will end up with intermittent failures, and you will have to go through every scenario to find your culprit.

In general it is much easier and more effective to put your effort into making your setup code FAST enough so that you are not worried about running it before each scenario.

Upvotes: 1

Sarabjit Singh
Sarabjit Singh

Reputation: 790

Yes, This can be done by passing the actual value in you feature file and using "(\\d+)" in you java file. Look at below shown code for better understanding.

Scenario: some test scenario
Given whenever a value is 50

In myFile.java, write the step definition as shown below

@Given("whenever a value is (\\d+)$")
public void testValueInVariable(int value) throws Throwable {
 assertEqual(value, 50);
}

you can also have a look at below link to get more clear picture: https://thomassundberg.wordpress.com/2014/05/29/cucumber-jvm-hello-world/

Upvotes: 0

jshort
jshort

Reputation: 1016

Cucumber doesn't really support what you are asking about. A way to implement this with cucumber hooks would be to use these two pieces of doc:

https://github.com/cucumber/cucumber/wiki/Hooks#tagged-hooks

https://github.com/cucumber/cucumber/wiki/Hooks#running-a-before-hook-only-once

You would tag all your feature files appropriately and you can implement tagged Before hooks that execute once on a per feature tag basis.

It's not beautiful but it accomplishes what you want without waiting on a feature request (or using a different tool).

Upvotes: 2

SaeeK
SaeeK

Reputation: 237

This can be achieved by associating a Before, After, Around or AfterStep hook with one or more tags. Examples:

Before('@cucumis, @sativus') do
  # This will only run before scenarios tagged
  # with @cucumis OR @sativus.
end

Upvotes: 1

Related Questions