How to change the default execution order of feature files in Cucumber

When you are running all your Cucumber feature scripts from Rake, often you would want to change the default execution order. Currently, cucumber loads all the feature files in ‘features/’ directory in alphabetical order and executes them.

This can be very annoying, specially when you want to execute certain critical features run before running the other not so critical features. Cucumber does not have any provision for feature ordering. But with some minor hacks, you can achieve this.

1st, you need to give each of your features a certain ‘weight’ in a yml file:

features/vcc_admin_create_test.feature: 80
features/transferred_acd_call.feature: 9
features/supervisor_create_test.feature: 8
features/super_force_signout_test.feature: 7
features/simple_queue_call_test.feature: 6
features/queue_delivered_count_test.feature : 67
features/queue_create_test.feature : 13
features/queue_call_treatment_test.feature : 12
features/email_status_monitor_test.feature : 11
features/email_forward.feature : 10
features/dynamic_and_static_number_test.feature : 9
features/agent_profile_change_test.feature : 8
features/agent_email_receiver_test.feature : 7
features/agent_create_test.feature : 6
features/agent_acd_state_test.feature : 5
features/agent_acd_call_duration_test.feature : 4
features/agent_acd_call_count_test.feature : 3
features/admin_call_distribution_policy_test.feature : 2
features/CC_create_test.feature : 1

next, update your env.rb file for adding a hook:

# Overrides the method +method_name+ in +obj+ with the passed block
def override_method(obj, method_name, &block)
  # Get the singleton class/eigenclass for 'obj'
  klass = class <<obj; self; end
 
  # Undefine the old method (using 'send' since 'undef_method' is protected)
  klass.send(:undef_method, method_name)
 
  # Create the new method
  klass.send(:define_method, method_name, block)
end
 
 
  
def get_weight(x)
  weights = YAML::load(File.open('order.yml')) #this is expensive but is done only on rake start
  weight = weights[x]
  if weight == nil or weight == ''
    weight = '100' #this is because we want to run the newly added tests first.
  end
  return weight.to_i()
end
 
def sort_according_to_weights(features)
  return features.sort { |x,y|  get_weight(y)  &lt;=&gt; get_weight(x)}
end
 
 
AfterConfiguration do |configuration|
  puts "\n\n\n *****  config: #{configuration} "
  featurefiles =  configuration.feature_files
 
  override_method(configuration, :feature_files) {
    puts "overriding the old featurefiles according to their weight"
    sorted_files = sort_according_to_weights(featurefiles);   
    sorted_files
  }
 
    puts "\n\n *************************** features will be executed in following order: \n"
    for i in configuration.feature_files
      puts "#{i} : weight: #{get_weight(i)}"
    end
end

After Cucumber loads the feature files from the directory, it calls “AfterConfiguration” before it starts executing the features. Sadly the configuration.feature_files is not an array which you can just sort. Its a method ! But with ruby being a dynamic language, you can push new method definition into the configuration instance so that it returns the features according to the order you specified !

5 thoughts on “How to change the default execution order of feature files in Cucumber

  1. There appears to be an error in line 23 of the env.rb. After adding this to my env.rb my interpreter reports:

    D:/testing/support/env.rb:49: syntax error, unexpected tIDENTIFIER, expecting ‘}’
    return features.sort { |x,y| get_weight(y) get_weight(x)}
    ^ (SyntaxError)

    where the little ^ points to the first paren in get_weight(x)}

    I haven’t debugged yet, but I’m about to.

    • Hi dholcombe,

      Thanks for reporting the issue. I didn’t realize before that wordpress ate the “<=>” sign in th sort function.

      This should be like the following:

      def sort_according_to_weights(features)
      return features.sort { |x,y| get_weight(y) <=> get_weight(x)}
      end

  2. This is a great solution and works really well when using it with rake build commands. The problem i am having is that we are currently using an msbuild solution which i am able to hook my cucumber tests in to, unfortunatley when i try to include the ordering code to make it run this also it falls on its ass.
    The error from the console i am getting when kicking off the ms build procedure with cucumber tests can be seen below.

    Any help would be appreciated others i weill juts have to go back to the old fashioned way of numbering the feature files, 😦

    overriding the old featurefiles according to their weight
    \\buildsrv3\build\releases\Adgistics.Build.Scripts\current\msbuild\adgistics.cu
    cumber.targets(34,3): error MSB3073: The command “cucumber ENVIRONMENT=http://s
    tc-ci.adgistics.com/ -t @automated -f pretty -f html –out C:\Projects\stc\buil
    d\test\artifacts\cucumber.html C:\Projects\stc\test\rb\acceptance\features” exi
    ted with code 1.
    Done Building Project “C:\Projects\stc\build.proj” (AcceptanceTagAutomated targ
    et(s)) — FAILED.

  3. Thanks for sharing, this info. Its of great worth 🙂
    When I paste this code in my env.rb file. I am unable to execute the default cucumber commands such as :
    cucumber -t @abc.

    Is there a workaround that I can run the file sequentially when I need and run a particular scenario/feature file using tags.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s