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 !