parallel_tests 3.3.0 → 4.2.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.
- checksums.yaml +4 -4
- data/Readme.md +53 -27
- data/bin/parallel_cucumber +2 -1
- data/bin/parallel_rspec +2 -1
- data/bin/parallel_spinach +2 -1
- data/bin/parallel_test +2 -1
- data/lib/parallel_tests/cli.rb +154 -92
- data/lib/parallel_tests/cucumber/failures_logger.rb +1 -1
- data/lib/parallel_tests/cucumber/features_with_steps.rb +4 -3
- data/lib/parallel_tests/cucumber/runner.rb +10 -7
- data/lib/parallel_tests/cucumber/scenario_line_logger.rb +4 -4
- data/lib/parallel_tests/cucumber/scenarios.rb +9 -8
- data/lib/parallel_tests/gherkin/io.rb +2 -3
- data/lib/parallel_tests/gherkin/listener.rb +9 -10
- data/lib/parallel_tests/gherkin/runner.rb +29 -35
- data/lib/parallel_tests/gherkin/runtime_logger.rb +2 -1
- data/lib/parallel_tests/grouper.rb +57 -6
- data/lib/parallel_tests/pids.rb +5 -4
- data/lib/parallel_tests/railtie.rb +1 -0
- data/lib/parallel_tests/rspec/failures_logger.rb +2 -2
- data/lib/parallel_tests/rspec/logger_base.rb +9 -7
- data/lib/parallel_tests/rspec/runner.rb +32 -19
- data/lib/parallel_tests/rspec/runtime_logger.rb +12 -10
- data/lib/parallel_tests/rspec/summary_logger.rb +2 -3
- data/lib/parallel_tests/spinach/runner.rb +6 -2
- data/lib/parallel_tests/tasks.rb +130 -71
- data/lib/parallel_tests/test/runner.rb +90 -41
- data/lib/parallel_tests/test/runtime_logger.rb +19 -14
- data/lib/parallel_tests/version.rb +2 -1
- data/lib/parallel_tests.rb +13 -13
- metadata +10 -10
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "parallel_tests/test/runner"
|
2
3
|
|
3
4
|
module ParallelTests
|
@@ -6,24 +7,26 @@ 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
|
-
|
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
|
-
|
16
|
-
when File.exist?("bin/rspec")
|
15
|
+
if File.exist?("bin/rspec")
|
17
16
|
ParallelTests.with_ruby_binary("bin/rspec")
|
18
|
-
|
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
|
-
|
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
|
@@ -44,26 +47,36 @@ module ParallelTests
|
|
44
47
|
# --order rand:1234
|
45
48
|
# --order random:1234
|
46
49
|
def command_with_seed(cmd, seed)
|
47
|
-
clean = cmd
|
48
|
-
|
50
|
+
clean = remove_command_arguments(cmd, '--seed', '--order')
|
51
|
+
[*clean, '--seed', seed]
|
49
52
|
end
|
50
53
|
|
54
|
+
# Summarize results from threads and colorize results based on failure and pending counts.
|
55
|
+
#
|
56
|
+
def summarize_results(results)
|
57
|
+
text = super
|
58
|
+
return text unless $stdout.tty?
|
59
|
+
sums = sum_up_results(results)
|
60
|
+
color =
|
61
|
+
if sums['failure'] > 0
|
62
|
+
31 # red
|
63
|
+
elsif sums['pending'] > 0
|
64
|
+
33 # yellow
|
65
|
+
else
|
66
|
+
32 # green
|
67
|
+
end
|
68
|
+
"\e[#{color}m#{text}\e[0m"
|
69
|
+
end
|
51
70
|
|
52
71
|
private
|
53
72
|
|
54
|
-
# so it can be stubbed....
|
55
|
-
def run(cmd)
|
56
|
-
`#{cmd}`
|
57
|
-
end
|
58
|
-
|
59
73
|
def color
|
60
|
-
'--color --tty' if $stdout.tty?
|
74
|
+
['--color', '--tty'] if $stdout.tty?
|
61
75
|
end
|
62
76
|
|
63
77
|
def spec_opts
|
64
|
-
options_file = ['.rspec_parallel', 'spec/parallel_spec.opts', 'spec/spec.opts'].detect{|f| File.file?(f) }
|
65
|
-
|
66
|
-
"-O #{options_file}"
|
78
|
+
options_file = ['.rspec_parallel', 'spec/parallel_spec.opts', 'spec/spec.opts'].detect { |f| File.file?(f) }
|
79
|
+
["-O", options_file] if options_file
|
67
80
|
end
|
68
81
|
end
|
69
82
|
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 unless RSPEC_2
|
14
13
|
|
15
14
|
def example_group_started(example_group)
|
16
15
|
@time = ParallelTests.now if @group_nesting == 0
|
@@ -27,16 +26,19 @@ class ParallelTests::RSpec::RuntimeLogger < ParallelTests::RSpec::LoggerBase
|
|
27
26
|
super if defined?(super)
|
28
27
|
end
|
29
28
|
|
30
|
-
def dump_summary(*
|
31
|
-
|
32
|
-
def
|
33
|
-
|
29
|
+
def dump_summary(*); end
|
30
|
+
|
31
|
+
def dump_failures(*); end
|
32
|
+
|
33
|
+
def dump_failure(*); end
|
34
|
+
|
35
|
+
def dump_pending(*); end
|
34
36
|
|
35
|
-
def start_dump(*
|
36
|
-
return unless ENV['TEST_ENV_NUMBER'] #only record when running in parallel
|
37
|
+
def start_dump(*)
|
38
|
+
return unless ENV['TEST_ENV_NUMBER'] # only record when running in parallel
|
37
39
|
lock_output do
|
38
40
|
@example_times.each do |file, time|
|
39
|
-
relative_path = file.sub(
|
41
|
+
relative_path = file.sub(%r{^#{Regexp.escape Dir.pwd}/}, '').sub(%r{^\./}, "")
|
40
42
|
@output.puts "#{relative_path}:#{time > 0 ? time : 0}"
|
41
43
|
end
|
42
44
|
end
|
@@ -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 unless RSPEC_2
|
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
|
data/lib/parallel_tests/tasks.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'rake'
|
2
3
|
require 'shellwords'
|
3
4
|
|
@@ -8,16 +9,8 @@ module ParallelTests
|
|
8
9
|
'test'
|
9
10
|
end
|
10
11
|
|
11
|
-
def rake_bin
|
12
|
-
# Prevent 'Exec format error' Errno::ENOEXEC on Windows
|
13
|
-
return "rake" if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
|
14
|
-
binstub_path = File.join('bin', 'rake')
|
15
|
-
return binstub_path if File.exist?(binstub_path)
|
16
|
-
"rake"
|
17
|
-
end
|
18
|
-
|
19
12
|
def load_lib
|
20
|
-
$LOAD_PATH << File.expand_path(
|
13
|
+
$LOAD_PATH << File.expand_path('..', __dir__)
|
21
14
|
require "parallel_tests"
|
22
15
|
end
|
23
16
|
|
@@ -27,13 +20,17 @@ module ParallelTests
|
|
27
20
|
end
|
28
21
|
end
|
29
22
|
|
30
|
-
def run_in_parallel(cmd, options={})
|
23
|
+
def run_in_parallel(cmd, options = {})
|
31
24
|
load_lib
|
32
|
-
|
25
|
+
|
33
26
|
# Using the relative path to find the binary allow to run a specific version of it
|
34
|
-
executable = File.expand_path(
|
35
|
-
command =
|
36
|
-
|
27
|
+
executable = File.expand_path('../../bin/parallel_test', __dir__)
|
28
|
+
command = ParallelTests.with_ruby_binary(executable)
|
29
|
+
command += ['--exec', Shellwords.join(cmd)]
|
30
|
+
command += ['-n', options[:count]] unless options[:count].to_s.empty?
|
31
|
+
command << '--non-parallel' if options[:non_parallel]
|
32
|
+
|
33
|
+
abort unless system(*command)
|
37
34
|
end
|
38
35
|
|
39
36
|
# this is a crazy-complex solution for a very simple problem:
|
@@ -46,16 +43,14 @@ module ParallelTests
|
|
46
43
|
# - pipefail makes pipe fail with exitstatus of first failed command
|
47
44
|
# - pipefail is not supported in (zsh)
|
48
45
|
# - defining a new rake task like silence_schema would force users to load parallel_tests in test env
|
49
|
-
# - do not use ' since run_in_parallel uses them to quote stuff
|
50
46
|
# - simple system "set -o pipefail" returns nil even though set -o pipefail exists with 0
|
51
47
|
def suppress_output(command, ignore_regex)
|
52
48
|
activate_pipefail = "set -o pipefail"
|
53
|
-
remove_ignored_lines = %
|
49
|
+
remove_ignored_lines = %{(grep -v #{Shellwords.escape(ignore_regex)} || true)}
|
54
50
|
|
55
|
-
if
|
56
|
-
|
57
|
-
|
58
|
-
%Q{/bin/bash -c '"'"'#{activate_pipefail} && (#{command}) | #{remove_ignored_lines}'"'"'}
|
51
|
+
if system('/bin/bash', '-c', "#{activate_pipefail} 2>/dev/null")
|
52
|
+
shell_command = "#{activate_pipefail} && (#{Shellwords.shelljoin(command)}) | #{remove_ignored_lines}"
|
53
|
+
['/bin/bash', '-c', shell_command]
|
59
54
|
else
|
60
55
|
command
|
61
56
|
end
|
@@ -83,12 +78,61 @@ module ParallelTests
|
|
83
78
|
# parallel:spec[2,models,options]
|
84
79
|
# parallel:spec[,models,options]
|
85
80
|
count = args.shift if args.first.to_s =~ /^\d*$/
|
86
|
-
num_processes = count.
|
81
|
+
num_processes = (count.to_s.empty? ? nil : Integer(count))
|
87
82
|
pattern = args.shift
|
88
83
|
options = args.shift
|
89
84
|
pass_through = args.shift
|
90
85
|
|
91
|
-
[num_processes, pattern
|
86
|
+
[num_processes, pattern, options, pass_through]
|
87
|
+
end
|
88
|
+
|
89
|
+
def schema_format_based_on_rails_version
|
90
|
+
if rails_7_or_greater?
|
91
|
+
ActiveRecord.schema_format
|
92
|
+
else
|
93
|
+
ActiveRecord::Base.schema_format
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def schema_type_based_on_rails_version
|
98
|
+
if rails_61_or_greater? || schema_format_based_on_rails_version == :ruby
|
99
|
+
"schema"
|
100
|
+
else
|
101
|
+
"structure"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def build_run_command(type, args)
|
106
|
+
count, pattern, options, pass_through = ParallelTests::Tasks.parse_args(args)
|
107
|
+
test_framework = {
|
108
|
+
'spec' => 'rspec',
|
109
|
+
'test' => 'test',
|
110
|
+
'features' => 'cucumber',
|
111
|
+
'features-spinach' => 'spinach'
|
112
|
+
}.fetch(type)
|
113
|
+
|
114
|
+
type = 'features' if test_framework == 'spinach'
|
115
|
+
|
116
|
+
# Using the relative path to find the binary allow to run a specific version of it
|
117
|
+
executable = File.expand_path('../../bin/parallel_test', __dir__)
|
118
|
+
executable = ParallelTests.with_ruby_binary(executable)
|
119
|
+
|
120
|
+
command = [*executable, type, '--type', test_framework]
|
121
|
+
command += ['-n', count.to_s] if count
|
122
|
+
command += ['--pattern', pattern] if pattern
|
123
|
+
command += ['--test-options', options] if options
|
124
|
+
command += Shellwords.shellsplit pass_through if pass_through
|
125
|
+
command
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def rails_7_or_greater?
|
131
|
+
Gem::Version.new(Rails.version) >= Gem::Version.new('7.0')
|
132
|
+
end
|
133
|
+
|
134
|
+
def rails_61_or_greater?
|
135
|
+
Gem::Version.new(Rails.version) >= Gem::Version.new('6.1.0')
|
92
136
|
end
|
93
137
|
end
|
94
138
|
end
|
@@ -96,30 +140,40 @@ end
|
|
96
140
|
|
97
141
|
namespace :parallel do
|
98
142
|
desc "Setup test databases via db:setup --> parallel:setup[num_cpus]"
|
99
|
-
task :setup, :count do |_,args|
|
100
|
-
command = "
|
143
|
+
task :setup, :count do |_, args|
|
144
|
+
command = [$0, "db:setup", "RAILS_ENV=#{ParallelTests::Tasks.rails_env}"]
|
101
145
|
ParallelTests::Tasks.run_in_parallel(ParallelTests::Tasks.suppress_schema_load_output(command), args)
|
102
146
|
end
|
103
147
|
|
104
148
|
desc "Create test databases via db:create --> parallel:create[num_cpus]"
|
105
|
-
task :create, :count do |_,args|
|
149
|
+
task :create, :count do |_, args|
|
106
150
|
ParallelTests::Tasks.run_in_parallel(
|
107
|
-
"
|
151
|
+
[$0, "db:create", "RAILS_ENV=#{ParallelTests::Tasks.rails_env}"],
|
152
|
+
args
|
153
|
+
)
|
108
154
|
end
|
109
155
|
|
110
156
|
desc "Drop test databases via db:drop --> parallel:drop[num_cpus]"
|
111
|
-
task :drop, :count do |_,args|
|
157
|
+
task :drop, :count do |_, args|
|
112
158
|
ParallelTests::Tasks.run_in_parallel(
|
113
|
-
|
114
|
-
|
159
|
+
[
|
160
|
+
$0,
|
161
|
+
"db:drop",
|
162
|
+
"RAILS_ENV=#{ParallelTests::Tasks.rails_env}",
|
163
|
+
"DISABLE_DATABASE_ENVIRONMENT_CHECK=1"
|
164
|
+
],
|
165
|
+
args
|
166
|
+
)
|
115
167
|
end
|
116
168
|
|
117
169
|
desc "Update test databases by dumping and loading --> parallel:prepare[num_cpus]"
|
118
|
-
task(:prepare, [:count]) do |_,args|
|
170
|
+
task(:prepare, [:count]) do |_, args|
|
119
171
|
ParallelTests::Tasks.check_for_pending_migrations
|
120
|
-
|
172
|
+
|
173
|
+
if defined?(ActiveRecord) && [:ruby, :sql].include?(ParallelTests::Tasks.schema_format_based_on_rails_version)
|
121
174
|
# fast: dump once, load in parallel
|
122
|
-
type =
|
175
|
+
type = ParallelTests::Tasks.schema_type_based_on_rails_version
|
176
|
+
|
123
177
|
Rake::Task["db:#{type}:dump"].invoke
|
124
178
|
|
125
179
|
# remove database connection to prevent "database is being accessed by other users"
|
@@ -128,82 +182,87 @@ namespace :parallel do
|
|
128
182
|
Rake::Task["parallel:load_#{type}"].invoke(args[:count])
|
129
183
|
else
|
130
184
|
# slow: dump and load in in serial
|
131
|
-
args = args.to_hash.merge(:
|
185
|
+
args = args.to_hash.merge(non_parallel: true) # normal merge returns nil
|
132
186
|
task_name = Rake::Task.task_defined?('db:test:prepare') ? 'db:test:prepare' : 'app:db:test:prepare'
|
133
|
-
ParallelTests::Tasks.run_in_parallel(
|
187
|
+
ParallelTests::Tasks.run_in_parallel([$0, task_name], args)
|
134
188
|
next
|
135
189
|
end
|
136
190
|
end
|
137
191
|
|
138
192
|
# when dumping/resetting takes too long
|
139
193
|
desc "Update test databases via db:migrate --> parallel:migrate[num_cpus]"
|
140
|
-
task :migrate, :count do |_,args|
|
194
|
+
task :migrate, :count do |_, args|
|
141
195
|
ParallelTests::Tasks.run_in_parallel(
|
142
|
-
"
|
196
|
+
[$0, "db:migrate", "RAILS_ENV=#{ParallelTests::Tasks.rails_env}"],
|
197
|
+
args
|
198
|
+
)
|
143
199
|
end
|
144
200
|
|
145
201
|
desc "Rollback test databases via db:rollback --> parallel:rollback[num_cpus]"
|
146
|
-
task :rollback, :count do |_,args|
|
202
|
+
task :rollback, :count do |_, args|
|
147
203
|
ParallelTests::Tasks.run_in_parallel(
|
148
|
-
"
|
204
|
+
[$0, "db:rollback", "RAILS_ENV=#{ParallelTests::Tasks.rails_env}"],
|
205
|
+
args
|
206
|
+
)
|
149
207
|
end
|
150
208
|
|
151
209
|
# just load the schema (good for integration server <-> no development db)
|
152
210
|
desc "Load dumped schema for test databases via db:schema:load --> parallel:load_schema[num_cpus]"
|
153
|
-
task :load_schema, :count do |_,args|
|
154
|
-
command =
|
155
|
-
|
211
|
+
task :load_schema, :count do |_, args|
|
212
|
+
command = [
|
213
|
+
$0,
|
214
|
+
ParallelTests::Tasks.purge_before_load,
|
215
|
+
"db:schema:load",
|
216
|
+
"RAILS_ENV=#{ParallelTests::Tasks.rails_env}",
|
217
|
+
"DISABLE_DATABASE_ENVIRONMENT_CHECK=1"
|
218
|
+
]
|
156
219
|
ParallelTests::Tasks.run_in_parallel(ParallelTests::Tasks.suppress_schema_load_output(command), args)
|
157
220
|
end
|
158
221
|
|
159
222
|
# load the structure from the structure.sql file
|
160
|
-
|
161
|
-
|
223
|
+
# (faster for rails < 6.1, deprecated after and only configured by `ActiveRecord::Base.schema_format`)
|
224
|
+
desc "Load structure for test databases via db:schema:load --> parallel:load_structure[num_cpus]"
|
225
|
+
task :load_structure, :count do |_, args|
|
162
226
|
ParallelTests::Tasks.run_in_parallel(
|
163
|
-
|
164
|
-
|
227
|
+
[
|
228
|
+
$0,
|
229
|
+
ParallelTests::Tasks.purge_before_load,
|
230
|
+
"db:structure:load",
|
231
|
+
"RAILS_ENV=#{ParallelTests::Tasks.rails_env}",
|
232
|
+
"DISABLE_DATABASE_ENVIRONMENT_CHECK=1"
|
233
|
+
],
|
234
|
+
args
|
235
|
+
)
|
165
236
|
end
|
166
237
|
|
167
238
|
desc "Load the seed data from db/seeds.rb via db:seed --> parallel:seed[num_cpus]"
|
168
|
-
task :seed, :count do |_,args|
|
239
|
+
task :seed, :count do |_, args|
|
169
240
|
ParallelTests::Tasks.run_in_parallel(
|
170
|
-
|
241
|
+
[
|
242
|
+
$0,
|
243
|
+
"db:seed",
|
244
|
+
"RAILS_ENV=#{ParallelTests::Tasks.rails_env}"
|
245
|
+
],
|
246
|
+
args
|
247
|
+
)
|
171
248
|
end
|
172
249
|
|
173
250
|
desc "Launch given rake command in parallel"
|
174
251
|
task :rake, :command, :count do |_, args|
|
175
252
|
ParallelTests::Tasks.run_in_parallel(
|
176
|
-
"RAILS_ENV=#{ParallelTests::Tasks.rails_env}
|
177
|
-
|
253
|
+
[$0, args.command, "RAILS_ENV=#{ParallelTests::Tasks.rails_env}"],
|
254
|
+
args
|
255
|
+
)
|
178
256
|
end
|
179
257
|
|
180
258
|
['test', 'spec', 'features', 'features-spinach'].each do |type|
|
181
259
|
desc "Run #{type} in parallel with parallel:#{type}[num_cpus]"
|
182
|
-
task type, [:count, :pattern, :options, :pass_through] do |
|
260
|
+
task type, [:count, :pattern, :options, :pass_through] do |_t, args|
|
183
261
|
ParallelTests::Tasks.check_for_pending_migrations
|
184
262
|
ParallelTests::Tasks.load_lib
|
263
|
+
command = ParallelTests::Tasks.build_run_command(type, args)
|
185
264
|
|
186
|
-
|
187
|
-
test_framework = {
|
188
|
-
'spec' => 'rspec',
|
189
|
-
'test' => 'test',
|
190
|
-
'features' => 'cucumber',
|
191
|
-
'features-spinach' => 'spinach',
|
192
|
-
}[type]
|
193
|
-
|
194
|
-
if test_framework == 'spinach'
|
195
|
-
type = 'features'
|
196
|
-
end
|
197
|
-
# Using the relative path to find the binary allow to run a specific version of it
|
198
|
-
executable = File.join(File.dirname(__FILE__), '..', '..', 'bin', 'parallel_test')
|
199
|
-
|
200
|
-
command = "#{ParallelTests.with_ruby_binary(Shellwords.escape(executable))} #{type} " \
|
201
|
-
"--type #{test_framework} " \
|
202
|
-
"-n #{count} " \
|
203
|
-
"--pattern '#{pattern}' " \
|
204
|
-
"--test-options '#{options}' " \
|
205
|
-
"#{pass_through}"
|
206
|
-
abort unless system(command) # allow to chain tasks e.g. rake parallel:spec parallel:features
|
265
|
+
abort unless system(*command) # allow to chain tasks e.g. rake parallel:spec parallel:features
|
207
266
|
end
|
208
267
|
end
|
209
268
|
end
|