parallelized_specs 0.1.8 → 0.1.9
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/Readme.md +6 -12
- data/VERSION +1 -1
- data/lib/parallelized_specs.rb +136 -140
- data/lib/parallelized_specs/tasks.rb +11 -6
- data/parallelized_specs.gemspec +3 -2
- data/spec/integration_spec.rb +133 -0
- metadata +5 -4
data/Rakefile
CHANGED
data/Readme.md
CHANGED
@@ -58,22 +58,20 @@ ParallelizedSpecs uses 1 database per test-process, 2 processes will use `*_test
|
|
58
58
|
### 4: Run!
|
59
59
|
rake parallel:spec # RSpec
|
60
60
|
|
61
|
-
rake parallel:
|
62
|
-
rake parallel:
|
63
|
-
rake parallel:
|
61
|
+
rake parallel:spec[1] --> force 1 CPU --> 86 seconds
|
62
|
+
rake parallel:spec --> got 2 CPUs? --> 47 seconds
|
63
|
+
rake parallel:spec --> got 4 CPUs? --> 26 seconds
|
64
64
|
...
|
65
65
|
|
66
66
|
Test by pattern (e.g. use one integration server per subfolder / see if you broke any 'user'-related tests)
|
67
67
|
|
68
|
-
rake parallel:
|
69
|
-
rake parallel:
|
70
|
-
rake parallel:test['user|product'] # run user and product related tests
|
71
|
-
|
68
|
+
rake parallel:spec[4,user,] # force 4 CPU and run users specs
|
69
|
+
rake parallel:spec['user|product'] # run user and product related specs
|
72
70
|
|
73
71
|
Example output
|
74
72
|
--------------
|
75
73
|
2 processes for 210 specs, ~ 105 specs per process
|
76
|
-
...
|
74
|
+
... spec output ...
|
77
75
|
|
78
76
|
843 examples, 0 failures, 1 pending
|
79
77
|
|
@@ -98,10 +96,6 @@ Rspec: Add to your `spec/parallelized_specs.opts` (or `spec/spec.opts`) :
|
|
98
96
|
--format progress
|
99
97
|
--format ParallelizedSpecs::SpecRuntimeLogger --out tmp/parallel_profile.log
|
100
98
|
|
101
|
-
Test::Unit: Add to your `test_helper.rb`:
|
102
|
-
require 'parallelized_specs/runtime_logger'
|
103
|
-
|
104
|
-
|
105
99
|
SpecSummaryLogger
|
106
100
|
--------------------
|
107
101
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.9
|
data/lib/parallelized_specs.rb
CHANGED
@@ -85,181 +85,177 @@ class ParallelizedSpecs
|
|
85
85
|
|
86
86
|
tests_folder = 'spec'
|
87
87
|
tests_folder = File.join(options[:root], tests_folder) unless options[:root].to_s.empty?
|
88
|
-
if tests.is_a?(Array)
|
89
|
-
groups = tests_in_groups(tests || tests_folder, num_processes, options)
|
90
|
-
else
|
88
|
+
if !tests.is_a?(Array)
|
91
89
|
files_array = tests.split(/ /)
|
92
|
-
groups = tests_in_groups(files_array || tests_folder, num_processes, options)
|
93
90
|
end
|
94
|
-
|
91
|
+
groups = tests_in_groups(files_array || tests || tests_folder, num_processes, options)
|
95
92
|
|
96
|
-
|
97
|
-
abort "no #{name}s found!" if groups.size == 0
|
93
|
+
num_processes = groups.size
|
98
94
|
|
99
|
-
|
100
|
-
|
95
|
+
#adjust processes to groups
|
96
|
+
abort "no #{name}s found!" if groups.size == 0
|
101
97
|
|
102
|
-
|
103
|
-
|
104
|
-
end
|
98
|
+
num_tests = groups.inject(0) { |sum, item| sum + item.size }
|
99
|
+
puts "#{num_processes} processes for #{num_tests} #{name}s, ~ #{num_tests / groups.size} #{name}s per process"
|
105
100
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
puts summarize_results(results)
|
101
|
+
test_results = Parallel.map(groups, :in_processes => num_processes) do |group|
|
102
|
+
run_tests(group, groups.index(group), options)
|
103
|
+
end
|
110
104
|
|
111
|
-
|
112
|
-
|
113
|
-
|
105
|
+
#parse and print results
|
106
|
+
results = find_results(test_results.map { |result| result[:stdout] }*"")
|
107
|
+
puts ""
|
108
|
+
puts summarize_results(results)
|
114
109
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
110
|
+
#report total time taken
|
111
|
+
puts ""
|
112
|
+
puts "Took #{Time.now - start} seconds"
|
113
|
+
|
114
|
+
#exit with correct status code so rake parallel:test && echo 123 works
|
115
|
+
failed = test_results.any? { |result| result[:exit_status] != 0 }
|
116
|
+
abort "#{name.capitalize}s Failed" if failed
|
117
|
+
end
|
119
118
|
|
120
119
|
# parallel:spec[:count, :pattern, :options]
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
[num_processes.to_i, pattern.to_s, options.to_s]
|
137
|
-
end
|
120
|
+
def self.parse_rake_args(args)
|
121
|
+
# order as given by user
|
122
|
+
args = [args[:count], args[:pattern]]
|
123
|
+
|
124
|
+
# count given or empty ?
|
125
|
+
count = args.shift if args.first.to_s =~ /^\d*$/
|
126
|
+
num_processes = count.to_i unless count.to_s.empty?
|
127
|
+
num_processes ||= ENV['PARALLEL_TEST_PROCESSORS'].to_i if ENV['PARALLEL_TEST_PROCESSORS']
|
128
|
+
num_processes ||= Parallel.processor_count
|
129
|
+
|
130
|
+
pattern = args.shift
|
131
|
+
|
132
|
+
[num_processes.to_i, pattern.to_s]
|
133
|
+
end
|
138
134
|
|
139
135
|
# finds all tests and partitions them into groups
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
end
|
136
|
+
def self.tests_in_groups(tests, num_groups, options)
|
137
|
+
if options[:no_sort]
|
138
|
+
Grouper.in_groups(tests, num_groups)
|
139
|
+
else
|
140
|
+
tests = with_runtime_info(tests)
|
141
|
+
Grouper.in_even_groups_by_size(tests, num_groups, options)
|
147
142
|
end
|
143
|
+
end
|
148
144
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
145
|
+
def self.execute_command(cmd, process_number, options)
|
146
|
+
cmd = "TEST_ENV_NUMBER=#{test_env_number(process_number)} ; export TEST_ENV_NUMBER; #{cmd}"
|
147
|
+
f = open("|#{cmd}", 'r')
|
148
|
+
output = fetch_output(f, options)
|
149
|
+
f.close
|
150
|
+
{:stdout => output, :exit_status => $?.exitstatus}
|
151
|
+
end
|
156
152
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
153
|
+
def self.find_results(test_output)
|
154
|
+
test_output.split("\n").map { |line|
|
155
|
+
line = line.gsub(/\.|F|\*/, '')
|
156
|
+
next unless line_is_result?(line)
|
157
|
+
line
|
158
|
+
}.compact
|
159
|
+
end
|
164
160
|
|
165
|
-
|
166
|
-
|
167
|
-
|
161
|
+
def self.test_env_number(process_number)
|
162
|
+
process_number == 0 ? '' : process_number + 1
|
163
|
+
end
|
168
164
|
|
169
|
-
|
170
|
-
|
171
|
-
|
165
|
+
def self.runtime_log
|
166
|
+
'tmp/parallelized_runtime_test.log'
|
167
|
+
end
|
172
168
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
end
|
180
|
-
sums.sort.map { |word, number| "#{number} #{word}#{'s' if number != 1}" }.join(', ')
|
169
|
+
def self.summarize_results(results)
|
170
|
+
results = results.join(' ').gsub(/s\b/, '') # combine and singularize results
|
171
|
+
counts = results.scan(/(\d+) (\w+)/)
|
172
|
+
sums = counts.inject(Hash.new(0)) do |sum, (number, word)|
|
173
|
+
sum[word] += number.to_i
|
174
|
+
sum
|
181
175
|
end
|
176
|
+
sums.sort.map { |word, number| "#{number} #{word}#{'s' if number != 1}" }.join(', ')
|
177
|
+
end
|
182
178
|
|
183
|
-
|
179
|
+
protected
|
184
180
|
|
185
181
|
# read output of the process and print in in chucks
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
end
|
182
|
+
def self.fetch_output(process, options)
|
183
|
+
all = ''
|
184
|
+
buffer = ''
|
185
|
+
timeout = options[:chunk_timeout] || 0.2
|
186
|
+
flushed = Time.now.to_f
|
187
|
+
|
188
|
+
while (char = process.getc)
|
189
|
+
char = (char.is_a?(Fixnum) ? char.chr : char) # 1.8 <-> 1.9
|
190
|
+
all << char
|
191
|
+
|
192
|
+
# print in chunks so large blocks stay together
|
193
|
+
now = Time.now.to_f
|
194
|
+
buffer << char
|
195
|
+
if flushed + timeout < now
|
196
|
+
print buffer
|
197
|
+
STDOUT.flush
|
198
|
+
buffer = ''
|
199
|
+
flushed = now
|
205
200
|
end
|
201
|
+
end
|
206
202
|
|
207
|
-
|
208
|
-
|
209
|
-
|
203
|
+
# print the remainder
|
204
|
+
print buffer
|
205
|
+
STDOUT.flush
|
210
206
|
|
211
|
-
|
212
|
-
|
207
|
+
all
|
208
|
+
end
|
213
209
|
|
214
210
|
# copied from http://github.com/carlhuda/bundler Bundler::SharedHelpers#find_gemfile
|
215
|
-
|
216
|
-
|
211
|
+
def self.bundler_enabled?
|
212
|
+
return true if Object.const_defined?(:Bundler)
|
217
213
|
|
218
|
-
|
219
|
-
|
214
|
+
previous = nil
|
215
|
+
current = File.expand_path(Dir.pwd)
|
220
216
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
end
|
226
|
-
|
227
|
-
false
|
217
|
+
until !File.directory?(current) || current == previous
|
218
|
+
filename = File.join(current, "Gemfile")
|
219
|
+
return true if File.exists?(filename)
|
220
|
+
current, previous = File.expand_path("..", current), current
|
228
221
|
end
|
229
222
|
|
230
|
-
|
231
|
-
|
232
|
-
|
223
|
+
false
|
224
|
+
end
|
225
|
+
|
226
|
+
def self.line_is_result?(line)
|
227
|
+
line =~ /\d+ failure/
|
228
|
+
end
|
233
229
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
end
|
246
|
-
tests.sort.map { |test| [test, times[test]] }
|
247
|
-
else # use file sizes
|
248
|
-
tests.sort.map { |test| [test, File.stat(test).size] }
|
230
|
+
def self.with_runtime_info(tests)
|
231
|
+
lines = File.read(runtime_log).split("\n") rescue []
|
232
|
+
|
233
|
+
# use recorded test runtime if we got enough data
|
234
|
+
if lines.size * 1.5 > tests.size
|
235
|
+
puts "Using recorded test runtime"
|
236
|
+
times = Hash.new(1)
|
237
|
+
lines.each do |line|
|
238
|
+
test, time = line.split(":")
|
239
|
+
next unless test and time
|
240
|
+
times[File.expand_path(test)] = time.to_f
|
249
241
|
end
|
242
|
+
tests.sort.map { |test| [test, times[test]] }
|
243
|
+
else # use file sizes
|
244
|
+
tests.sort.map { |test| [test, File.stat(test).size] }
|
250
245
|
end
|
246
|
+
end
|
251
247
|
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
end
|
248
|
+
def self.find_tests(root, options={})
|
249
|
+
if root.is_a?(Array)
|
250
|
+
root
|
251
|
+
else
|
252
|
+
# follow one symlink and direct children
|
253
|
+
# http://stackoverflow.com/questions/357754/can-i-traverse-symlinked-directories-in-ruby-with-a-glob
|
254
|
+
files = Dir["#{root}/**{,/*/**}/*#{test_suffix}"].uniq
|
255
|
+
files = files.map { |f| f.sub(root+'/', '') }
|
256
|
+
files = files.grep(/#{options[:pattern]}/)
|
257
|
+
files.map { |f| "/#{f}" }
|
263
258
|
end
|
259
|
+
end
|
264
260
|
|
265
261
|
end
|
@@ -13,19 +13,24 @@ namespace :parallel do
|
|
13
13
|
ParallelizedSpecs.execute_parallel_db('rake db:drop RAILS_ENV=test', args)
|
14
14
|
end
|
15
15
|
|
16
|
-
desc "update test databases by dumping and loading --> parallel:
|
17
|
-
task(:
|
16
|
+
desc "update test databases by dumping and loading --> parallel:dump_load[num_cpus]"
|
17
|
+
task(:dump_load, [:count] => 'db:abort_if_pending_migrations') do |t, args|
|
18
18
|
if defined?(ActiveRecord) && ActiveRecord::Base.schema_format == :ruby
|
19
19
|
# dump then load in parallel
|
20
20
|
Rake::Task['db:schema:dump'].invoke
|
21
|
-
Rake::Task['parallel:load_schema'].invoke
|
21
|
+
Rake::Task['parallel:load_schema'].invoke
|
22
22
|
else
|
23
|
-
# there is no separate dump / load for
|
23
|
+
# there is no separate dump / load for s(args[:count])chema_format :sql -> do it safe and slow
|
24
24
|
args = args.to_hash.merge(:non_parallel => true) # normal merge returns nil
|
25
|
-
ParallelizedSpecs.execute_parallel_db('rake db:test:
|
25
|
+
ParallelizedSpecs.execute_parallel_db('rake db:test:dump_load', args)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
+
desc "drop, create, migrate all in one --> parallel:prepare[num_cpus]"
|
30
|
+
task :prepare, :count do |t, args|
|
31
|
+
ParallelizedSpecs.execute_parallel_db('rake db:drop db:create db:migrate RAILS_ENV=test', args)
|
32
|
+
end
|
33
|
+
|
29
34
|
# when dumping/resetting takes too long
|
30
35
|
desc "update test databases via db:migrate --> parallel:migrate[num_cpus]"
|
31
36
|
task :migrate, :count do |t, args|
|
@@ -40,7 +45,7 @@ namespace :parallel do
|
|
40
45
|
|
41
46
|
desc "run spec in parallel with parallel:spec[num_cpus]"
|
42
47
|
task 'spec', :count, :pattern, :options, :arguments do |t, args|
|
43
|
-
count, pattern
|
48
|
+
count, pattern = ParallelizedSpecs.parse_rake_args(args)
|
44
49
|
opts = {:count => count, :pattern => pattern, :root => Rails.root, :files => args[:arguments]}
|
45
50
|
ParallelizedSpecs.execute_parallel_specs(opts)
|
46
51
|
end
|
data/parallelized_specs.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "parallelized_specs"
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.9"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jake Sorce, Bryan Madsen"]
|
12
|
-
s.date = "2012-05-
|
12
|
+
s.date = "2012-05-07"
|
13
13
|
s.email = "jake@instructure.com"
|
14
14
|
s.files = [
|
15
15
|
"Gemfile",
|
@@ -31,6 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
"lib/parallelized_specs/tasks.rb",
|
32
32
|
"lib/tasks/parallelized_specs.rake",
|
33
33
|
"parallelized_specs.gemspec",
|
34
|
+
"spec/integration_spec.rb",
|
34
35
|
"spec/parallelized_specs/spec_failure_logger_spec.rb",
|
35
36
|
"spec/parallelized_specs/spec_runtime_logger_spec.rb",
|
36
37
|
"spec/parallelized_specs/spec_summary_logger_spec.rb",
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'CLI' do
|
4
|
+
before do
|
5
|
+
`rm -rf #{folder}`
|
6
|
+
end
|
7
|
+
|
8
|
+
after do
|
9
|
+
`rm -rf #{folder}`
|
10
|
+
end
|
11
|
+
|
12
|
+
def folder
|
13
|
+
"/tmp/parallel_tests_tests"
|
14
|
+
end
|
15
|
+
|
16
|
+
def write(file, content)
|
17
|
+
path = "#{folder}/#{file}"
|
18
|
+
`mkdir -p #{File.dirname(path)}` unless File.exist?(File.dirname(path))
|
19
|
+
File.open(path, 'w'){|f| f.write content }
|
20
|
+
path
|
21
|
+
end
|
22
|
+
|
23
|
+
def bin_folder
|
24
|
+
"#{File.expand_path(File.dirname(__FILE__))}/../bin"
|
25
|
+
end
|
26
|
+
|
27
|
+
def executable
|
28
|
+
"#{bin_folder}/parallel_test"
|
29
|
+
end
|
30
|
+
|
31
|
+
def run_tests(options={})
|
32
|
+
`cd #{folder} && #{executable} --chunk-timeout 999 -t #{options[:type] || 'spec'} -n #{options[:processes]||2} #{options[:add]} 2>&1`
|
33
|
+
end
|
34
|
+
|
35
|
+
it "runs tests in parallel" do
|
36
|
+
write 'spec/xxx_spec.rb', 'describe("it"){it("should"){puts "TEST1"}}'
|
37
|
+
write 'spec/xxx2_spec.rb', 'describe("it"){it("should"){puts "TEST2"}}'
|
38
|
+
result = run_tests
|
39
|
+
|
40
|
+
# test ran and gave their puts
|
41
|
+
result.should include('TEST1')
|
42
|
+
result.should include('TEST2')
|
43
|
+
|
44
|
+
# all results present
|
45
|
+
result.scan('1 example, 0 failure').size.should == 2 # 2 results
|
46
|
+
result.scan('2 examples, 0 failures').size.should == 1 # 1 summary
|
47
|
+
result.scan(/Finished in \d+\.\d+ seconds/).size.should == 2
|
48
|
+
result.scan(/Took \d+\.\d+ seconds/).size.should == 1 # parallel summary
|
49
|
+
$?.success?.should == true
|
50
|
+
end
|
51
|
+
|
52
|
+
it "does not run any tests if there are none" do
|
53
|
+
write 'spec/xxx.rb', 'xxx'
|
54
|
+
result = run_tests
|
55
|
+
result.should include('No examples found')
|
56
|
+
result.should include('Took')
|
57
|
+
end
|
58
|
+
|
59
|
+
it "fails when tests fail" do
|
60
|
+
write 'spec/xxx_spec.rb', 'describe("it"){it("should"){puts "TEST1"}}'
|
61
|
+
write 'spec/xxx2_spec.rb', 'describe("it"){it("should"){1.should == 2}}'
|
62
|
+
result = run_tests
|
63
|
+
|
64
|
+
result.scan('1 example, 1 failure').size.should == 1
|
65
|
+
result.scan('1 example, 0 failure').size.should == 1
|
66
|
+
result.scan('2 examples, 1 failure').size.should == 1
|
67
|
+
$?.success?.should == false
|
68
|
+
end
|
69
|
+
|
70
|
+
it "can exec given commands with ENV['TEST_ENV_NUM']" do
|
71
|
+
result = `#{executable} -e 'ruby -e "print ENV[:TEST_ENV_NUMBER.to_s].to_i"' -n 4`
|
72
|
+
result.gsub('"','').split('').sort.should == %w[0 2 3 4]
|
73
|
+
end
|
74
|
+
|
75
|
+
it "can exec given command non-parallel" do
|
76
|
+
result = `#{executable} -e 'ruby -e "sleep(rand(10)/100.0); puts ENV[:TEST_ENV_NUMBER.to_s].inspect"' -n 4 --non-parallel`
|
77
|
+
result.split("\n").should == %w["" "2" "3" "4"]
|
78
|
+
end
|
79
|
+
|
80
|
+
it "exists with success if all sub-processes returned success" do
|
81
|
+
system("#{executable} -e 'cat /dev/null' -n 4").should == true
|
82
|
+
end
|
83
|
+
|
84
|
+
it "exists with failure if any sub-processes returned failure" do
|
85
|
+
system("#{executable} -e 'test -e xxxx' -n 4").should == false
|
86
|
+
end
|
87
|
+
|
88
|
+
it "can run through parallel_spec / parallel_cucumber" do
|
89
|
+
version = `#{executable} -v`
|
90
|
+
`#{bin_folder}/parallel_spec -v`.should == version
|
91
|
+
`#{bin_folder}/parallel_cucumber -v`.should == version
|
92
|
+
end
|
93
|
+
|
94
|
+
it "runs faster with more processes" do
|
95
|
+
2.times{|i|
|
96
|
+
write "spec/xxx#{i}_spec.rb", 'describe("it"){it("should"){sleep 5}}; $stderr.puts ENV["TEST_ENV_NUMBER"]'
|
97
|
+
}
|
98
|
+
t = Time.now
|
99
|
+
run_tests(:processes => 2)
|
100
|
+
expected = 10
|
101
|
+
(Time.now - t).should <= expected
|
102
|
+
end
|
103
|
+
|
104
|
+
it "can can with given files" do
|
105
|
+
write "spec/x1_spec.rb", "puts '111'"
|
106
|
+
write "spec/x2_spec.rb", "puts '222'"
|
107
|
+
write "spec/x3_spec.rb", "puts '333'"
|
108
|
+
result = run_tests(:add => 'spec/x1_spec.rb spec/x3_spec.rb')
|
109
|
+
result.should include('111')
|
110
|
+
result.should include('333')
|
111
|
+
result.should_not include('222')
|
112
|
+
end
|
113
|
+
|
114
|
+
it "can run with test-options" do
|
115
|
+
write "spec/x1_spec.rb", ""
|
116
|
+
write "spec/x2_spec.rb", ""
|
117
|
+
result = run_tests(:add => "--test-options ' --version'", :processes => 2)
|
118
|
+
result.should =~ /\d+\.\d+\.\d+.*\d+\.\d+\.\d+/m # prints version twice
|
119
|
+
end
|
120
|
+
|
121
|
+
it "runs with test::unit" do
|
122
|
+
write "test/x1_test.rb", "require 'test/unit'; class XTest < Test::Unit::TestCase; def test_xxx; end; end"
|
123
|
+
result = run_tests(:type => :test)
|
124
|
+
result.should include('1 test')
|
125
|
+
$?.success?.should == true
|
126
|
+
end
|
127
|
+
|
128
|
+
it "passes test options to test::unit" do
|
129
|
+
write "test/x1_test.rb", "require 'test/unit'; class XTest < Test::Unit::TestCase; def test_xxx; end; end"
|
130
|
+
result = run_tests(:type => :test, :add => '--test-options "-v"')
|
131
|
+
result.should include('test_xxx') # verbose output of every test
|
132
|
+
end
|
133
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parallelized_specs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 9
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 9
|
10
|
+
version: 0.1.9
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jake Sorce, Bryan Madsen
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-05-
|
18
|
+
date: 2012-05-07 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: parallel
|
@@ -59,6 +59,7 @@ files:
|
|
59
59
|
- lib/parallelized_specs/tasks.rb
|
60
60
|
- lib/tasks/parallelized_specs.rake
|
61
61
|
- parallelized_specs.gemspec
|
62
|
+
- spec/integration_spec.rb
|
62
63
|
- spec/parallelized_specs/spec_failure_logger_spec.rb
|
63
64
|
- spec/parallelized_specs/spec_runtime_logger_spec.rb
|
64
65
|
- spec/parallelized_specs/spec_summary_logger_spec.rb
|