parallel_tests 3.3.0 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|