September 08, 2015

Triggering Cucumber tag from a Cucumber step

I am working on a legacy web application that has limited unit test and dependency on multiple applications.  To reduce the manual testing effort, we had to write end-to-end UI tests with help of Cucumber, Capybara.

We had to chain few tests (generally BAD PRACTICE) as there was no way to create the seed data in every end-to-end test. We had to reuse the data from other scenarios. Rather than going into further details, here is an example where you can trigger another cucumber tag from a step:


Feature: As a Cucumber user
  I want to run other feature from a step

  Scenario: run job
    Given no exception is raised

  Scenario: run job
    Given exception is raised

  Scenario: Child
    Given I trigger @success_child_process job
    And no exception is raised
    And I trigger @failure_child_process job


Given /^no exception is raised$/ do
  # do nothing here

Given /^exception is raised$/ do
  raise 'Exception is raised'

Given /^I trigger (@.*) job$/ do |tag|
  CucumberChildProcess.run_tag tag


require 'childprocess'

module CucumberChildProcess

  def self.run_tag(tag) "Triggering the child process for tag '#{tag}'"
    process ='bundle'), 'exec', 'cucumber', '-t', tag)!
    process.start "********* CHILD PROCESS LOGS for tag '#{tag}' - START **********"
    process.wait "********* CHILD PROCESS LOGS for tag '#{tag}' - END **********"
    raise "Child process failed while running the tag '#{tag}'. Check the log for more information. Exit code: #{process.exit_code}" unless process.exit_code == 0 "Successfully executed the tag '#{tag}' as Child process"

  def self.find_executable(cmd)
    ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
      next if path.empty?
      path = File.join(path, cmd)
      ['.exe', '.bat'].each do |ext|
        return path + ext if File.exists?(path + ext)
    raise "Unable to find command '#{cmd}' in the PATH"