parallel_tests 3.4.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ParallelTests
2
3
  module Gherkin
3
4
  class Listener
@@ -6,7 +7,8 @@ module ParallelTests
6
7
  attr_writer :ignore_tag_pattern
7
8
 
8
9
  def initialize
9
- @steps, @uris = [], []
10
+ @steps = []
11
+ @uris = []
10
12
  @collect = {}
11
13
  @feature, @ignore_tag_pattern = nil
12
14
  reset_counters!
@@ -16,7 +18,7 @@ module ParallelTests
16
18
  @feature = feature
17
19
  end
18
20
 
19
- def background(*args)
21
+ def background(*)
20
22
  @background = 1
21
23
  end
22
24
 
@@ -31,7 +33,7 @@ module ParallelTests
31
33
  @outline = 1
32
34
  end
33
35
 
34
- def step(*args)
36
+ def step(*)
35
37
  return if @ignoring
36
38
  if @background == 1
37
39
  @background_steps += 1
@@ -51,12 +53,10 @@ module ParallelTests
51
53
  # @param [Gherkin::Formatter::Model::Examples] examples
52
54
  #
53
55
  def examples(examples)
54
- if examples.rows.size > 0
55
- @collect[@uri] += (@outline_steps * examples.rows.size)
56
- end
56
+ @collect[@uri] += (@outline_steps * examples.rows.size) unless examples.rows.empty?
57
57
  end
58
58
 
59
- def eof(*args)
59
+ def eof(*)
60
60
  @collect[@uri] += (@background_steps * @scenarios)
61
61
  reset_counters!
62
62
  end
@@ -67,8 +67,7 @@ module ParallelTests
67
67
  end
68
68
 
69
69
  # ignore lots of other possible callbacks ...
70
- def method_missing(*args)
71
- end
70
+ def method_missing(*); end # rubocop:disable Style/MissingRespondToMissing
72
71
 
73
72
  private
74
73
 
@@ -79,7 +78,7 @@ module ParallelTests
79
78
 
80
79
  # Set @ignoring if we should ignore this scenario/outline based on its tags
81
80
  def should_ignore(scenario)
82
- @ignoring = @ignore_tag_pattern && all_tags(scenario).find{ |tag| @ignore_tag_pattern === tag.name }
81
+ @ignoring = @ignore_tag_pattern && all_tags(scenario).find { |tag| @ignore_tag_pattern === tag.name }
83
82
  end
84
83
  end
85
84
  end
@@ -1,30 +1,27 @@
1
+ # frozen_string_literal: true
1
2
  require "parallel_tests/test/runner"
2
- require 'shellwords'
3
3
 
4
4
  module ParallelTests
5
5
  module Gherkin
6
6
  class Runner < ParallelTests::Test::Runner
7
-
8
7
  class << self
9
8
  def run_tests(test_files, process_number, num_processes, options)
10
9
  combined_scenarios = test_files
11
10
 
12
11
  if options[:group_by] == :scenarios
13
12
  grouped = test_files.map { |t| t.split(':') }.group_by(&:first)
14
- combined_scenarios = grouped.map {|file,files_and_lines| "#{file}:#{files_and_lines.map(&:last).join(':')}" }
13
+ combined_scenarios = grouped.map do |file, files_and_lines|
14
+ "#{file}:#{files_and_lines.map(&:last).join(':')}"
15
+ end
15
16
  end
16
17
 
17
- sanitized_test_files = combined_scenarios.map { |val| WINDOWS ? "\"#{val}\"" : Shellwords.escape(val) }
18
-
19
18
  options[:env] ||= {}
20
- options[:env] = options[:env].merge({'AUTOTEST' => '1'}) if $stdout.tty? # display color when we are in a terminal
21
-
22
- cmd = [
23
- executable,
24
- (runtime_logging if File.directory?(File.dirname(runtime_log))),
25
- cucumber_opts(options[:test_options]),
26
- *sanitized_test_files
27
- ].compact.reject(&:empty?).join(' ')
19
+ options[:env] = options[:env].merge({ 'AUTOTEST' => '1' }) if $stdout.tty?
20
+
21
+ cmd = executable
22
+ cmd += runtime_logging if File.directory?(File.dirname(runtime_log))
23
+ cmd += combined_scenarios
24
+ cmd += cucumber_opts(options[:test_options])
28
25
  execute_command(cmd, process_number, num_processes, options)
29
26
  end
30
27
 
@@ -32,6 +29,10 @@ module ParallelTests
32
29
  @test_file_name || 'feature'
33
30
  end
34
31
 
32
+ def default_test_folder
33
+ 'features'
34
+ end
35
+
35
36
  def test_suffix
36
37
  /\.feature$/
37
38
  end
@@ -44,42 +45,38 @@ module ParallelTests
44
45
  # 1 scenario (1 failed)
45
46
  # 1 step (1 failed)
46
47
  def summarize_results(results)
47
- sort_order = %w[scenario step failed flaky undefined skipped pending passed]
48
+ sort_order = ['scenario', 'step', 'failed', 'flaky', 'undefined', 'skipped', 'pending', 'passed']
48
49
 
49
- %w[scenario step].map do |group|
50
+ ['scenario', 'step'].map do |group|
50
51
  group_results = results.grep(/^\d+ #{group}/)
51
52
  next if group_results.empty?
52
53
 
53
54
  sums = sum_up_results(group_results)
54
55
  sums = sums.sort_by { |word, _| sort_order.index(word) || 999 }
55
56
  sums.map! do |word, number|
56
- plural = "s" if word == group and number != 1
57
+ plural = "s" if (word == group) && (number != 1)
57
58
  "#{number} #{word}#{plural}"
58
59
  end
59
- "#{sums[0]} (#{sums[1..-1].join(", ")})"
60
+ "#{sums[0]} (#{sums[1..].join(", ")})"
60
61
  end.compact.join("\n")
61
62
  end
62
63
 
63
64
  def cucumber_opts(given)
64
- if given =~ /--profile/ or given =~ /(^|\s)-p /
65
+ if given&.include?('--profile') || given&.include?('-p')
65
66
  given
66
67
  else
67
- [given, profile_from_config].compact.join(" ")
68
+ [*given, *profile_from_config]
68
69
  end
69
70
  end
70
71
 
71
72
  def profile_from_config
72
73
  # copied from https://github.com/cucumber/cucumber/blob/master/lib/cucumber/cli/profile_loader.rb#L85
73
74
  config = Dir.glob("{,.config/,config/}#{name}{.yml,.yaml}").first
74
- if config && File.read(config) =~ /^parallel:/
75
- "--profile parallel"
76
- end
75
+ ['--profile', 'parallel'] if config && File.read(config) =~ /^parallel:/
77
76
  end
78
77
 
79
- def tests_in_groups(tests, num_groups, options={})
80
- if options[:group_by] == :scenarios
81
- @test_file_name = "scenario"
82
- end
78
+ def tests_in_groups(tests, num_groups, options = {})
79
+ @test_file_name = "scenario" if options[:group_by] == :scenarios
83
80
  method = "by_#{options[:group_by]}"
84
81
  if Grouper.respond_to?(method)
85
82
  Grouper.send(method, find_tests(tests, options), num_groups, options)
@@ -88,9 +85,8 @@ module ParallelTests
88
85
  end
89
86
  end
90
87
 
91
-
92
88
  def runtime_logging
93
- "--format ParallelTests::Gherkin::RuntimeLogger --out #{runtime_log}"
89
+ ['--format', 'ParallelTests::Gherkin::RuntimeLogger', '--out', runtime_log]
94
90
  end
95
91
 
96
92
  def runtime_log
@@ -98,18 +94,16 @@ module ParallelTests
98
94
  end
99
95
 
100
96
  def determine_executable
101
- case
102
- when File.exist?("bin/#{name}")
97
+ if File.exist?("bin/#{name}")
103
98
  ParallelTests.with_ruby_binary("bin/#{name}")
104
- when ParallelTests.bundler_enabled?
105
- "bundle exec #{name}"
106
- when File.file?("script/#{name}")
99
+ elsif ParallelTests.bundler_enabled?
100
+ ["bundle", "exec", name]
101
+ elsif File.file?("script/#{name}")
107
102
  ParallelTests.with_ruby_binary("script/#{name}")
108
103
  else
109
- "#{name}"
104
+ [name.to_s]
110
105
  end
111
106
  end
112
-
113
107
  end
114
108
  end
115
109
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'parallel_tests/gherkin/io'
2
3
 
3
4
  module ParallelTests
@@ -19,7 +20,7 @@ module ParallelTests
19
20
 
20
21
  config.on_event :test_run_finished do |_|
21
22
  lock_output do
22
- @io.puts @example_times.map { |file, time| "#{file}:#{time}" }
23
+ @io.puts(@example_times.map { |file, time| "#{file}:#{time}" })
23
24
  end
24
25
  end
25
26
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ParallelTests
2
3
  class Grouper
3
4
  class << self
@@ -6,13 +7,15 @@ module ParallelTests
6
7
  in_even_groups_by_size(features_with_steps, num_groups)
7
8
  end
8
9
 
9
- def by_scenarios(tests, num_groups, options={})
10
+ def by_scenarios(tests, num_groups, options = {})
10
11
  scenarios = group_by_scenarios(tests, options)
11
12
  in_even_groups_by_size(scenarios, num_groups)
12
13
  end
13
14
 
14
- def in_even_groups_by_size(items, num_groups, options= {})
15
- groups = Array.new(num_groups) { {:items => [], :size => 0} }
15
+ def in_even_groups_by_size(items, num_groups, options = {})
16
+ groups = Array.new(num_groups) { { items: [], size: 0 } }
17
+
18
+ return specify_groups(items, num_groups, options, groups) if options[:specify_groups]
16
19
 
17
20
  # add all files that should run in a single process to one group
18
21
  single_process_patterns = options[:single_process] || []
@@ -24,14 +27,14 @@ module ParallelTests
24
27
  isolate_count = isolate_count(options)
25
28
 
26
29
  if isolate_count >= num_groups
27
- raise 'Number of isolated processes must be less than total the number of processes'
30
+ raise 'Number of isolated processes must be >= total number of processes'
28
31
  end
29
32
 
30
33
  if isolate_count >= 1
31
34
  # add all files that should run in a multiple isolated processes to their own groups
32
35
  group_features_by_size(items_to_group(single_items), groups[0..(isolate_count - 1)])
33
36
  # group the non-isolated by size
34
- group_features_by_size(items_to_group(items), groups[isolate_count..-1])
37
+ group_features_by_size(items_to_group(items), groups[isolate_count..])
35
38
  else
36
39
  # add all files that should run in a single non-isolated process to first group
37
40
  single_items.each { |item, size| add_to_group(groups.first, item, size) }
@@ -45,6 +48,50 @@ module ParallelTests
45
48
 
46
49
  private
47
50
 
51
+ def specify_groups(items, num_groups, options, groups)
52
+ specify_test_process_groups = options[:specify_groups].split('|')
53
+ if specify_test_process_groups.count > num_groups
54
+ raise 'Number of processes separated by pipe must be less than or equal to the total number of processes'
55
+ end
56
+
57
+ all_specified_tests = specify_test_process_groups.map { |group| group.split(',') }.flatten
58
+ specified_items_found, items = items.partition { |item, _size| all_specified_tests.include?(item) }
59
+
60
+ specified_specs_not_found = all_specified_tests - specified_items_found.map(&:first)
61
+ if specified_specs_not_found.any?
62
+ raise "Could not find #{specified_specs_not_found} from --specify-groups in the selected files & folders"
63
+ end
64
+
65
+ if specify_test_process_groups.count == num_groups && items.flatten.any?
66
+ raise(
67
+ <<~ERROR
68
+ The number of groups in --specify-groups matches the number of groups from -n but there were other specs
69
+ found in the selected files & folders not specified in --specify-groups. Make sure -n is larger than the
70
+ number of processes in --specify-groups if there are other specs that need to be run. The specs that aren't run:
71
+ #{items.map(&:first)}
72
+ ERROR
73
+ )
74
+ end
75
+
76
+ # First order the specify_groups into the main groups array
77
+ specify_test_process_groups.each_with_index do |specify_test_process, i|
78
+ groups[i] = specify_test_process.split(',')
79
+ end
80
+
81
+ # Return early when processed specify_groups tests exactly match the items passed in
82
+ return groups if specify_test_process_groups.count == num_groups
83
+
84
+ # Now sort the rest of the items into the main groups array
85
+ specified_range = specify_test_process_groups.count..-1
86
+ remaining_groups = groups[specified_range]
87
+ group_features_by_size(items_to_group(items), remaining_groups)
88
+ # Don't sort all the groups, only sort the ones not specified in specify_groups
89
+ sorted_groups = remaining_groups.map { |g| g[:items].sort }
90
+ groups[specified_range] = sorted_groups
91
+
92
+ groups
93
+ end
94
+
48
95
  def isolate_count(options)
49
96
  if options[:isolate_count] && options[:isolate_count] > 1
50
97
  options[:isolate_count]
@@ -56,7 +103,7 @@ module ParallelTests
56
103
  end
57
104
 
58
105
  def largest_first(files)
59
- files.sort_by{|_item, size| size }.reverse
106
+ files.sort_by { |_item, size| size }.reverse
60
107
  end
61
108
 
62
109
  def smallest_group(groups)
@@ -73,7 +120,7 @@ module ParallelTests
73
120
  ParallelTests::Cucumber::FeaturesWithSteps.all(tests, options)
74
121
  end
75
122
 
76
- def group_by_scenarios(tests, options={})
123
+ def group_by_scenarios(tests, options = {})
77
124
  require 'parallel_tests/cucumber/scenarios'
78
125
  ParallelTests::Cucumber::Scenarios.all(tests, options)
79
126
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'json'
2
3
 
3
4
  module ParallelTests
@@ -42,18 +43,18 @@ module ParallelTests
42
43
 
43
44
  def read
44
45
  sync do
45
- contents = IO.read(file_path)
46
+ contents = File.read(file_path)
46
47
  return if contents.empty?
47
48
  @pids = JSON.parse(contents)
48
49
  end
49
50
  end
50
51
 
51
52
  def save
52
- sync { IO.write(file_path, pids.to_json) }
53
+ sync { File.write(file_path, pids.to_json) }
53
54
  end
54
55
 
55
- def sync
56
- mutex.synchronize { yield }
56
+ def sync(&block)
57
+ mutex.synchronize(&block)
57
58
  end
58
59
  end
59
60
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # rake tasks for Rails 3+
2
3
  module ParallelTests
3
4
  class Railtie < ::Rails::Railtie
@@ -1,24 +1,16 @@
1
+ # frozen_string_literal: true
1
2
  require 'parallel_tests/rspec/logger_base'
2
3
  require 'parallel_tests/rspec/runner'
3
4
 
4
5
  class ParallelTests::RSpec::FailuresLogger < ParallelTests::RSpec::LoggerBase
5
- if RSPEC_2
6
- def dump_failures(*args)
7
- end
8
- else
9
- RSpec::Core::Formatters.register self, :dump_summary
10
- end
6
+ RSpec::Core::Formatters.register(self, :dump_summary)
11
7
 
12
8
  def dump_summary(*args)
13
9
  lock_output do
14
- if RSPEC_2
15
- dump_commands_to_rerun_failed_examples
16
- else
17
- notification = args.first
18
- unless notification.failed_examples.empty?
19
- colorizer = ::RSpec::Core::Formatters::ConsoleCodes
20
- output.puts notification.colorized_rerun_commands(colorizer)
21
- end
10
+ notification = args.first
11
+ unless notification.failed_examples.empty?
12
+ colorizer = ::RSpec::Core::Formatters::ConsoleCodes
13
+ output.puts notification.colorized_rerun_commands(colorizer)
22
14
  end
23
15
  end
24
16
  @output.flush
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ParallelTests
2
3
  module RSpec
3
4
  end
@@ -6,33 +7,32 @@ end
6
7
  require 'rspec/core/formatters/base_text_formatter'
7
8
 
8
9
  class ParallelTests::RSpec::LoggerBase < RSpec::Core::Formatters::BaseTextFormatter
9
- RSPEC_2 = RSpec::Core::Version::STRING.start_with?('2')
10
-
11
10
  def initialize(*args)
12
11
  super
13
12
 
14
13
  @output ||= args[0]
15
14
 
16
- if String === @output # a path ?
15
+ case @output
16
+ when String # a path ?
17
17
  FileUtils.mkdir_p(File.dirname(@output))
18
- File.open(@output, 'w'){} # overwrite previous results
18
+ File.open(@output, 'w') {} # overwrite previous results
19
19
  @output = File.open(@output, 'a')
20
- elsif File === @output # close and restart in append mode
20
+ when File # close and restart in append mode
21
21
  @output.close
22
22
  @output = File.open(@output.path, 'a')
23
23
  end
24
24
  end
25
25
 
26
- #stolen from Rspec
27
- def close(*args)
28
- @output.close if (IO === @output) & (@output != $stdout)
26
+ # stolen from Rspec
27
+ def close(*)
28
+ @output.close if (IO === @output) & (@output != $stdout)
29
29
  end
30
30
 
31
31
  protected
32
32
 
33
33
  # do not let multiple processes get in each others way
34
34
  def lock_output
35
- if File === @output
35
+ if @output.is_a?(File)
36
36
  begin
37
37
  @output.flock File::LOCK_EX
38
38
  yield
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "parallel_tests/test/runner"
2
3
 
3
4
  module ParallelTests
@@ -6,32 +7,36 @@ module ParallelTests
6
7
  DEV_NULL = (WINDOWS ? "NUL" : "/dev/null")
7
8
  class << self
8
9
  def run_tests(test_files, process_number, num_processes, options)
9
- exe = executable # expensive, so we cache
10
- cmd = [exe, options[:test_options], color, spec_opts, *test_files].compact.join(" ")
10
+ cmd = [*executable, *options[:test_options], *color, *spec_opts, *test_files]
11
11
  execute_command(cmd, process_number, num_processes, options)
12
12
  end
13
13
 
14
14
  def determine_executable
15
- case
16
- when File.exist?("bin/rspec")
15
+ if File.exist?("bin/rspec")
17
16
  ParallelTests.with_ruby_binary("bin/rspec")
18
- when ParallelTests.bundler_enabled?
19
- "bundle exec rspec"
17
+ elsif ParallelTests.bundler_enabled?
18
+ ["bundle", "exec", "rspec"]
20
19
  else
21
- "rspec"
20
+ ["rspec"]
22
21
  end
23
22
  end
24
23
 
25
24
  def runtime_log
26
- 'tmp/parallel_runtime_rspec.log'
25
+ "tmp/parallel_runtime_rspec.log"
26
+ end
27
+
28
+ def default_test_folder
29
+ "spec"
27
30
  end
28
31
 
29
32
  def test_file_name
30
33
  "spec"
31
34
  end
32
35
 
36
+ # used to find all _spec.rb files
37
+ # supports also feature files used by rspec turnip extension
33
38
  def test_suffix
34
- /_spec\.rb$/
39
+ /(_spec\.rb|\.feature)$/
35
40
  end
36
41
 
37
42
  def line_is_result?(line)
@@ -44,8 +49,8 @@ module ParallelTests
44
49
  # --order rand:1234
45
50
  # --order random:1234
46
51
  def command_with_seed(cmd, seed)
47
- clean = cmd.sub(/\s--(seed\s+\d+|order\s+rand(om)?(:\d+)?)\b/, '')
48
- "#{clean} --seed #{seed}"
52
+ clean = remove_command_arguments(cmd, '--seed', '--order')
53
+ [*clean, '--seed', seed]
49
54
  end
50
55
 
51
56
  # Summarize results from threads and colorize results based on failure and pending counts.
@@ -55,9 +60,9 @@ module ParallelTests
55
60
  return text unless $stdout.tty?
56
61
  sums = sum_up_results(results)
57
62
  color =
58
- if sums['failure'].positive?
63
+ if sums['failure'] > 0
59
64
  31 # red
60
- elsif sums['pending'].positive?
65
+ elsif sums['pending'] > 0
61
66
  33 # yellow
62
67
  else
63
68
  32 # green
@@ -67,19 +72,13 @@ module ParallelTests
67
72
 
68
73
  private
69
74
 
70
- # so it can be stubbed....
71
- def run(cmd)
72
- `#{cmd}`
73
- end
74
-
75
75
  def color
76
- '--color --tty' if $stdout.tty?
76
+ ['--color', '--tty'] if $stdout.tty?
77
77
  end
78
78
 
79
79
  def spec_opts
80
- options_file = ['.rspec_parallel', 'spec/parallel_spec.opts', 'spec/spec.opts'].detect{|f| File.file?(f) }
81
- return unless options_file
82
- "-O #{options_file}"
80
+ options_file = ['.rspec_parallel', 'spec/parallel_spec.opts', 'spec/spec.opts'].detect { |f| File.file?(f) }
81
+ ["-O", options_file] if options_file
83
82
  end
84
83
  end
85
84
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'parallel_tests'
2
3
  require 'parallel_tests/rspec/logger_base'
3
4
 
@@ -8,9 +9,7 @@ class ParallelTests::RSpec::RuntimeLogger < ParallelTests::RSpec::LoggerBase
8
9
  @group_nesting = 0
9
10
  end
10
11
 
11
- unless RSPEC_2
12
- RSpec::Core::Formatters.register self, :example_group_started, :example_group_finished, :start_dump
13
- end
12
+ RSpec::Core::Formatters.register(self, :example_group_started, :example_group_finished, :start_dump)
14
13
 
15
14
  def example_group_started(example_group)
16
15
  @time = ParallelTests.now if @group_nesting == 0
@@ -21,23 +20,25 @@ class ParallelTests::RSpec::RuntimeLogger < ParallelTests::RSpec::LoggerBase
21
20
  def example_group_finished(notification)
22
21
  @group_nesting -= 1
23
22
  if @group_nesting == 0
24
- path = (RSPEC_2 ? notification.file_path : notification.group.file_path)
25
- @example_times[path] += ParallelTests.now - @time
23
+ @example_times[notification.group.file_path] += ParallelTests.now - @time
26
24
  end
27
25
  super if defined?(super)
28
26
  end
29
27
 
30
- def dump_summary(*args);end
31
- def dump_failures(*args);end
32
- def dump_failure(*args);end
33
- def dump_pending(*args);end
28
+ def dump_summary(*); end
29
+
30
+ def dump_failures(*); end
31
+
32
+ def dump_failure(*); end
33
+
34
+ def dump_pending(*); end
34
35
 
35
- def start_dump(*args)
36
- return unless ENV['TEST_ENV_NUMBER'] #only record when running in parallel
36
+ def start_dump(*)
37
+ return unless ENV['TEST_ENV_NUMBER'] # only record when running in parallel
37
38
  lock_output do
38
39
  @example_times.each do |file, time|
39
- relative_path = file.sub(/^#{Regexp.escape Dir.pwd}\//,'').sub(/^\.\//, "")
40
- @output.puts "#{relative_path}:#{time > 0 ? time : 0}"
40
+ relative_path = file.sub(%r{^#{Regexp.escape Dir.pwd}/}, '').sub(%r{^\./}, "")
41
+ @output.puts "#{relative_path}:#{[time, 0].max}"
41
42
  end
42
43
  end
43
44
  @output.flush
@@ -1,9 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  require 'parallel_tests/rspec/failures_logger'
2
3
 
3
4
  class ParallelTests::RSpec::SummaryLogger < ParallelTests::RSpec::LoggerBase
4
- unless RSPEC_2
5
- RSpec::Core::Formatters.register self, :dump_failures
6
- end
5
+ RSpec::Core::Formatters.register(self, :dump_failures)
7
6
 
8
7
  def dump_failures(*args)
9
8
  lock_output { super }
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "parallel_tests/gherkin/runner"
2
3
 
3
4
  module ParallelTests
@@ -8,11 +9,14 @@ module ParallelTests
8
9
  'spinach'
9
10
  end
10
11
 
12
+ def default_test_folder
13
+ 'features'
14
+ end
15
+
11
16
  def runtime_logging
12
- #Not Yet Supported
17
+ # Not Yet Supported
13
18
  ""
14
19
  end
15
-
16
20
  end
17
21
  end
18
22
  end