moxiesoft_parallel_tests 0.4.13 → 0.6.18
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -2
- data/Gemfile.lock +26 -18
- data/Rakefile +3 -3
- data/Readme.md +105 -21
- data/VERSION +1 -1
- data/bin/parallel_test +21 -18
- data/lib/parallel_cucumber.rb +10 -3
- data/lib/parallel_specs/spec_runtime_logger.rb +16 -31
- data/lib/parallel_specs.rb +20 -16
- data/lib/parallel_tests/grouper.rb +34 -16
- data/lib/parallel_tests/tasks.rb +9 -9
- data/lib/parallel_tests.rb +83 -39
- data/parallel_tests.gemspec +64 -0
- data/spec/integration_spec.rb +77 -30
- data/spec/parallel_cucumber_spec.rb +10 -10
- data/spec/parallel_specs_spec.rb +49 -25
- data/spec/parallel_tests_spec.rb +100 -13
- data/spec/spec_helper.rb +48 -9
- metadata +30 -40
- data/moxiesoft_parallel_tests.gemspec +0 -65
data/lib/parallel_tests.rb
CHANGED
@@ -5,18 +5,23 @@ require 'parallel_tests/railtie'
|
|
5
5
|
class ParallelTests
|
6
6
|
VERSION = File.read( File.join(File.dirname(__FILE__),'..','VERSION') ).strip
|
7
7
|
|
8
|
-
# parallel:spec[
|
8
|
+
# parallel:spec[:count, :pattern, :options]
|
9
9
|
def self.parse_rake_args(args)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
10
|
+
# order as given by user
|
11
|
+
args = [args[:count], args[:pattern], args[:options]]
|
12
|
+
|
13
|
+
# count given or empty ?
|
14
|
+
# parallel:spec[2,models,options]
|
15
|
+
# parallel:spec[,models,options]
|
16
|
+
count = args.shift if args.first.to_s =~ /^\d*$/
|
17
|
+
num_processes = count.to_i unless count.to_s.empty?
|
18
|
+
num_processes ||= ENV['PARALLEL_TEST_PROCESSORS'].to_i if ENV['PARALLEL_TEST_PROCESSORS']
|
19
|
+
num_processes ||= Parallel.processor_count
|
20
|
+
|
21
|
+
pattern = args.shift
|
22
|
+
options = args.shift
|
23
|
+
|
24
|
+
[num_processes.to_i, pattern.to_s, options.to_s]
|
20
25
|
end
|
21
26
|
|
22
27
|
# finds all tests and partitions them into groups
|
@@ -24,34 +29,29 @@ class ParallelTests
|
|
24
29
|
if root.nil?
|
25
30
|
root = ['unit', 'functional', 'integration'].collect { |dir| File.join(Dir.pwd, 'test', dir) }
|
26
31
|
end
|
27
|
-
|
32
|
+
tests = find_tests(root, options)
|
28
33
|
if options[:no_sort] == true
|
29
|
-
Grouper.in_groups(
|
34
|
+
Grouper.in_groups(tests, num_groups)
|
30
35
|
else
|
31
|
-
|
36
|
+
tests = with_runtime_info(tests)
|
37
|
+
Grouper.in_even_groups_by_size(tests, num_groups, options)
|
32
38
|
end
|
33
39
|
end
|
34
40
|
|
35
41
|
def self.run_tests(test_files, process_number, options)
|
36
|
-
require_list = test_files.map { |filename| "
|
37
|
-
cmd = "ruby -Itest
|
38
|
-
execute_command(cmd, process_number)
|
42
|
+
require_list = test_files.map { |filename| %{"#{File.expand_path filename}"} }.join(",")
|
43
|
+
cmd = "ruby -Itest -e '[#{require_list}].each {|f| require f }' -- #{options[:test_options]}"
|
44
|
+
execute_command(cmd, process_number, options)
|
39
45
|
end
|
40
46
|
|
41
|
-
def self.execute_command(cmd, process_number)
|
47
|
+
def self.execute_command(cmd, process_number, options)
|
42
48
|
cmd = "TEST_ENV_NUMBER=#{test_env_number(process_number)} ; export TEST_ENV_NUMBER; #{cmd}"
|
43
49
|
print "starting #{cmd}"
|
44
50
|
f = open("|#{cmd}", 'r')
|
45
|
-
|
46
|
-
while char = f.getc
|
47
|
-
char = (char.is_a?(Fixnum) ? char.chr : char) # 1.8 <-> 1.9
|
48
|
-
all << char
|
49
|
-
print char
|
50
|
-
STDOUT.flush
|
51
|
-
end
|
51
|
+
output = fetch_output(f, options)
|
52
52
|
f.close
|
53
53
|
print "finished #{cmd}"
|
54
|
-
{:stdout =>
|
54
|
+
{:stdout => output, :exit_status => $?.exitstatus}
|
55
55
|
end
|
56
56
|
|
57
57
|
def self.find_results(test_output)
|
@@ -66,11 +66,54 @@ class ParallelTests
|
|
66
66
|
process_number == 0 ? '' : process_number + 1
|
67
67
|
end
|
68
68
|
|
69
|
+
def self.runtime_log
|
70
|
+
'tmp/parallel_runtime_test.log'
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.summarize_results(results)
|
74
|
+
results = results.join(' ').gsub(/s\b/,'') # combine and singularize results
|
75
|
+
counts = results.scan(/(\d+) (\w+)/)
|
76
|
+
sums = counts.inject(Hash.new(0)) do |sum, (number, word)|
|
77
|
+
sum[word] += number.to_i
|
78
|
+
sum
|
79
|
+
end
|
80
|
+
sums.sort.map{|word, number| "#{number} #{word}#{'s' if number != 1}" }.join(', ')
|
81
|
+
end
|
82
|
+
|
69
83
|
protected
|
70
84
|
|
85
|
+
# read output of the process and print in in chucks
|
86
|
+
def self.fetch_output(process, options)
|
87
|
+
all = ''
|
88
|
+
buffer = ''
|
89
|
+
timeout = options[:chunk_timeout] || 0.2
|
90
|
+
flushed = Time.now.to_f
|
91
|
+
|
92
|
+
while char = process.getc
|
93
|
+
char = (char.is_a?(Fixnum) ? char.chr : char) # 1.8 <-> 1.9
|
94
|
+
all << char
|
95
|
+
|
96
|
+
# print in chunks so large blocks stay together
|
97
|
+
now = Time.now.to_f
|
98
|
+
buffer << char
|
99
|
+
if flushed + timeout < now
|
100
|
+
print buffer
|
101
|
+
STDOUT.flush
|
102
|
+
buffer = ''
|
103
|
+
flushed = now
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# print the remainder
|
108
|
+
print buffer
|
109
|
+
STDOUT.flush
|
110
|
+
|
111
|
+
all
|
112
|
+
end
|
113
|
+
|
71
114
|
# copied from http://github.com/carlhuda/bundler Bundler::SharedHelpers#find_gemfile
|
72
115
|
def self.bundler_enabled?
|
73
|
-
return true if Object.const_defined?(:Bundler)
|
116
|
+
return true if Object.const_defined?(:Bundler)
|
74
117
|
|
75
118
|
previous = nil
|
76
119
|
current = File.expand_path(Dir.pwd)
|
@@ -92,17 +135,17 @@ class ParallelTests
|
|
92
135
|
"_test.rb"
|
93
136
|
end
|
94
137
|
|
95
|
-
def self.
|
96
|
-
|
97
|
-
runtime_file = File.join(root,'..','tmp','parallel_profile.log')
|
98
|
-
lines = File.read(runtime_file).split("\n") rescue []
|
138
|
+
def self.with_runtime_info(tests)
|
139
|
+
lines = File.read(runtime_log).split("\n") rescue []
|
99
140
|
|
100
141
|
# use recorded test runtime if we got enough data
|
101
142
|
if lines.size * 1.5 > tests.size
|
143
|
+
puts "Using recorded test runtime"
|
102
144
|
times = Hash.new(1)
|
103
145
|
lines.each do |line|
|
104
146
|
test, time = line.split(":")
|
105
|
-
|
147
|
+
next unless test and time
|
148
|
+
times[File.expand_path(test)] = time.to_f
|
106
149
|
end
|
107
150
|
tests.sort.map{|test| [test, times[test]] }
|
108
151
|
else # use file sizes
|
@@ -110,15 +153,16 @@ class ParallelTests
|
|
110
153
|
end
|
111
154
|
end
|
112
155
|
|
113
|
-
def self.find_tests(root)
|
156
|
+
def self.find_tests(root, options={})
|
114
157
|
if root.is_a?(Array)
|
115
|
-
|
116
|
-
root.collect { |dir| find_tests(dir) }.flatten
|
117
|
-
else
|
118
|
-
root
|
119
|
-
end
|
158
|
+
root
|
120
159
|
else
|
121
|
-
|
160
|
+
# follow one symlink and direct children
|
161
|
+
# http://stackoverflow.com/questions/357754/can-i-traverse-symlinked-directories-in-ruby-with-a-glob
|
162
|
+
files = Dir["#{root}/**{,/*/**}/*#{test_suffix}"].uniq
|
163
|
+
files = files.map{|f| f.sub(root+'/','') }
|
164
|
+
files = files.grep(/#{options[:pattern]}/)
|
165
|
+
files.map{|f| "#{root}/#{f}" }
|
122
166
|
end
|
123
167
|
end
|
124
168
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "parallel_tests"
|
8
|
+
s.version = "0.6.18"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Michael Grosser"]
|
12
|
+
s.date = "2012-02-08"
|
13
|
+
s.email = "grosser.michael@gmail.com"
|
14
|
+
s.executables = ["parallel_cucumber", "parallel_spec", "parallel_test"]
|
15
|
+
s.files = [
|
16
|
+
"Gemfile",
|
17
|
+
"Gemfile.lock",
|
18
|
+
"Rakefile",
|
19
|
+
"Readme.md",
|
20
|
+
"VERSION",
|
21
|
+
"bin/parallel_cucumber",
|
22
|
+
"bin/parallel_spec",
|
23
|
+
"bin/parallel_test",
|
24
|
+
"lib/parallel_cucumber.rb",
|
25
|
+
"lib/parallel_cucumber/runtime_logger.rb",
|
26
|
+
"lib/parallel_specs.rb",
|
27
|
+
"lib/parallel_specs/spec_failures_logger.rb",
|
28
|
+
"lib/parallel_specs/spec_logger_base.rb",
|
29
|
+
"lib/parallel_specs/spec_runtime_logger.rb",
|
30
|
+
"lib/parallel_specs/spec_summary_logger.rb",
|
31
|
+
"lib/parallel_tests.rb",
|
32
|
+
"lib/parallel_tests/grouper.rb",
|
33
|
+
"lib/parallel_tests/railtie.rb",
|
34
|
+
"lib/parallel_tests/runtime_logger.rb",
|
35
|
+
"lib/parallel_tests/tasks.rb",
|
36
|
+
"lib/tasks/parallel_tests.rake",
|
37
|
+
"parallel_tests.gemspec",
|
38
|
+
"spec/integration_spec.rb",
|
39
|
+
"spec/parallel_cucumber_spec.rb",
|
40
|
+
"spec/parallel_specs/spec_failure_logger_spec.rb",
|
41
|
+
"spec/parallel_specs/spec_runtime_logger_spec.rb",
|
42
|
+
"spec/parallel_specs/spec_summary_logger_spec.rb",
|
43
|
+
"spec/parallel_specs_spec.rb",
|
44
|
+
"spec/parallel_tests/runtime_logger_spec.rb",
|
45
|
+
"spec/parallel_tests_spec.rb",
|
46
|
+
"spec/spec_helper.rb"
|
47
|
+
]
|
48
|
+
s.homepage = "http://github.com/grosser/parallel_tests"
|
49
|
+
s.require_paths = ["lib"]
|
50
|
+
s.rubygems_version = "1.8.10"
|
51
|
+
s.summary = "Run tests / specs / features in parallel"
|
52
|
+
|
53
|
+
if s.respond_to? :specification_version then
|
54
|
+
s.specification_version = 3
|
55
|
+
|
56
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
57
|
+
s.add_runtime_dependency(%q<parallel>, [">= 0"])
|
58
|
+
else
|
59
|
+
s.add_dependency(%q<parallel>, [">= 0"])
|
60
|
+
end
|
61
|
+
else
|
62
|
+
s.add_dependency(%q<parallel>, [">= 0"])
|
63
|
+
end
|
64
|
+
end
|
data/spec/integration_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'CLI' do
|
4
4
|
before do
|
@@ -14,7 +14,7 @@ describe 'CLI' do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def write(file, content)
|
17
|
-
path = "#{folder}
|
17
|
+
path = "#{folder}/#{file}"
|
18
18
|
`mkdir -p #{File.dirname(path)}` unless File.exist?(File.dirname(path))
|
19
19
|
File.open(path, 'w'){|f| f.write content }
|
20
20
|
path
|
@@ -28,39 +28,48 @@ describe 'CLI' do
|
|
28
28
|
"#{bin_folder}/parallel_test"
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
32
|
-
`cd #{folder} && #{executable} -t spec -n #{options[:processes]||2} #{options[:add]} 2>&1`
|
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
33
|
end
|
34
34
|
|
35
35
|
it "runs tests in parallel" do
|
36
|
-
write 'xxx_spec.rb', 'describe("it"){it("should"){puts "TEST1"}}'
|
37
|
-
write 'xxx2_spec.rb', 'describe("it"){it("should"){puts "TEST2"}}'
|
38
|
-
result =
|
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
39
|
|
40
40
|
# test ran and gave their puts
|
41
41
|
result.should include('TEST1')
|
42
42
|
result.should include('TEST2')
|
43
43
|
|
44
44
|
# all results present
|
45
|
-
result.scan('1 example, 0 failure').size.should ==
|
45
|
+
result.scan('1 example, 0 failure').size.should == 2 # 2 results
|
46
|
+
result.scan('2 examples, 0 failures').size.should == 1 # 1 summary
|
46
47
|
result.scan(/Finished in \d+\.\d+ seconds/).size.should == 2
|
47
48
|
result.scan(/Took \d+\.\d+ seconds/).size.should == 1 # parallel summary
|
48
49
|
$?.success?.should == true
|
49
50
|
end
|
50
51
|
|
52
|
+
it "does not run any tests if there are none" do
|
53
|
+
write 'spec/xxx_spec.rb', '1'
|
54
|
+
result = run_tests
|
55
|
+
result.should include('No examples found')
|
56
|
+
result.should include('Took')
|
57
|
+
end
|
58
|
+
|
51
59
|
it "fails when tests fail" do
|
52
|
-
write 'xxx_spec.rb', 'describe("it"){it("should"){puts "TEST1"}}'
|
53
|
-
write 'xxx2_spec.rb', 'describe("it"){it("should"){1.should == 2}}'
|
54
|
-
result =
|
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
|
55
63
|
|
56
|
-
result.scan('1 example, 1 failure').size.should ==
|
57
|
-
result.scan('1 example, 0 failure').size.should ==
|
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
|
58
67
|
$?.success?.should == false
|
59
68
|
end
|
60
69
|
|
61
70
|
it "can exec given commands with ENV['TEST_ENV_NUM']" do
|
62
|
-
result = `#{executable} -e 'ruby -e "
|
63
|
-
result.
|
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]
|
64
73
|
end
|
65
74
|
|
66
75
|
it "can exec given command non-parallel" do
|
@@ -83,32 +92,70 @@ describe 'CLI' do
|
|
83
92
|
end
|
84
93
|
|
85
94
|
it "runs faster with more processes" do
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
write 'xxx4_spec.rb', 'describe("it"){it("should"){sleep 2}}'
|
90
|
-
write 'xxx5_spec.rb', 'describe("it"){it("should"){sleep 2}}'
|
91
|
-
write 'xxx6_spec.rb', 'describe("it"){it("should"){sleep 2}}'
|
95
|
+
2.times{|i|
|
96
|
+
write "spec/xxx#{i}_spec.rb", 'describe("it"){it("should"){sleep 5}}; $stderr.puts ENV["TEST_ENV_NUMBER"]'
|
97
|
+
}
|
92
98
|
t = Time.now
|
93
|
-
|
99
|
+
run_tests(:processes => 2)
|
94
100
|
expected = 10
|
95
101
|
(Time.now - t).should <= expected
|
96
102
|
end
|
97
103
|
|
98
104
|
it "can can with given files" do
|
99
|
-
write "x1_spec.rb", "puts '111'"
|
100
|
-
write "x2_spec.rb", "puts '222'"
|
101
|
-
write "x3_spec.rb", "puts '333'"
|
102
|
-
result =
|
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')
|
103
109
|
result.should include('111')
|
104
110
|
result.should include('333')
|
105
111
|
result.should_not include('222')
|
106
112
|
end
|
107
113
|
|
108
114
|
it "can run with test-options" do
|
109
|
-
write "x1_spec.rb", ""
|
110
|
-
write "x2_spec.rb", ""
|
111
|
-
result =
|
115
|
+
write "spec/x1_spec.rb", "111"
|
116
|
+
write "spec/x2_spec.rb", "111"
|
117
|
+
result = run_tests(:add => "--test-options ' --version'", :processes => 2)
|
112
118
|
result.should =~ /\d+\.\d+\.\d+.*\d+\.\d+\.\d+/m # prints version twice
|
113
119
|
end
|
114
|
-
|
120
|
+
|
121
|
+
context "Test::Unit" do
|
122
|
+
it "runs" do
|
123
|
+
write "test/x1_test.rb", "require 'test/unit'; class XTest < Test::Unit::TestCase; def test_xxx; end; end"
|
124
|
+
result = run_tests(:type => :test)
|
125
|
+
result.should include('1 test')
|
126
|
+
$?.success?.should == true
|
127
|
+
end
|
128
|
+
|
129
|
+
it "passes test options" do
|
130
|
+
write "test/x1_test.rb", "require 'test/unit'; class XTest < Test::Unit::TestCase; def test_xxx; end; end"
|
131
|
+
result = run_tests(:type => :test, :add => '--test-options "-v"')
|
132
|
+
result.should include('test_xxx') # verbose output of every test
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context "Cucumber" do
|
137
|
+
it "passes TEST_ENV_NUMBER when running with pattern (issue #86)" do
|
138
|
+
write "features/good1.feature", "Feature: xxx\n Scenario: xxx\n Given I print TEST_ENV_NUMBER"
|
139
|
+
write "features/good2.feature", "Feature: xxx\n Scenario: xxx\n Given I print TEST_ENV_NUMBER"
|
140
|
+
write "features/b.feature", "Feature: xxx\n Scenario: xxx\n Given I FAIL"
|
141
|
+
write "features/steps/a.rb", "Given('I print TEST_ENV_NUMBER'){ puts \"YOUR TEST ENV IS \#{ENV['TEST_ENV_NUMBER']}!\" }"
|
142
|
+
|
143
|
+
result = run_tests :type => 'features', :add => '--pattern good'
|
144
|
+
$?.success?.should == true
|
145
|
+
|
146
|
+
result.should include('YOUR TEST ENV IS 2!')
|
147
|
+
result.should include('YOUR TEST ENV IS !')
|
148
|
+
result.should_not include('I FAIL')
|
149
|
+
end
|
150
|
+
|
151
|
+
it "runs each feature once when there are more processes then features (issue #89)" do
|
152
|
+
write "features/steps/a.rb", "Given('I print TEST_ENV_NUMBER'){ puts \"YOUR TEST ENV IS \#{ENV['TEST_ENV_NUMBER']}!\" }"
|
153
|
+
2.times{|i|
|
154
|
+
write "features/good#{i}.feature", "Feature: xxx\n Scenario: xxx\n Given I print TEST_ENV_NUMBER"
|
155
|
+
}
|
156
|
+
result = run_tests :type => 'features', :add => '-n 3'
|
157
|
+
$?.success?.should == true
|
158
|
+
result.scan(/YOUR TEST ENV IS \d?!/).sort.should == ["YOUR TEST ENV IS !", "YOUR TEST ENV IS 2!"]
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ParallelCucumber do
|
4
4
|
test_tests_in_groups(ParallelCucumber, 'features', ".feature")
|
@@ -12,41 +12,41 @@ describe ParallelCucumber do
|
|
12
12
|
|
13
13
|
it "uses TEST_ENV_NUMBER=blank when called for process 0" do
|
14
14
|
ParallelCucumber.should_receive(:open).with{|x,y| x=~/TEST_ENV_NUMBER= /}.and_return mocked_process
|
15
|
-
ParallelCucumber.run_tests(['xxx'],0,
|
15
|
+
ParallelCucumber.run_tests(['xxx'],0,{})
|
16
16
|
end
|
17
17
|
|
18
18
|
it "uses TEST_ENV_NUMBER=2 when called for process 1" do
|
19
19
|
ParallelCucumber.should_receive(:open).with{|x,y| x=~/TEST_ENV_NUMBER=2/}.and_return mocked_process
|
20
|
-
ParallelCucumber.run_tests(['xxx'],1,
|
20
|
+
ParallelCucumber.run_tests(['xxx'],1,{})
|
21
21
|
end
|
22
22
|
|
23
23
|
it "returns the output" do
|
24
24
|
io = open('spec/spec_helper.rb')
|
25
25
|
ParallelCucumber.stub!(:print)
|
26
26
|
ParallelCucumber.should_receive(:open).and_return io
|
27
|
-
ParallelCucumber.run_tests(['xxx'],1,
|
27
|
+
ParallelCucumber.run_tests(['xxx'],1,{})[:stdout].should =~ /\$LOAD_PATH << File/
|
28
28
|
end
|
29
29
|
|
30
30
|
it "runs bundle exec cucumber when on bundler 0.9" do
|
31
31
|
ParallelCucumber.stub!(:bundler_enabled?).and_return true
|
32
32
|
ParallelCucumber.should_receive(:open).with{|x,y| x =~ %r{bundle exec cucumber}}.and_return mocked_process
|
33
|
-
ParallelCucumber.run_tests(['xxx'],1,
|
33
|
+
ParallelCucumber.run_tests(['xxx'],1,{})
|
34
34
|
end
|
35
35
|
|
36
36
|
it "runs script/cucumber when script/cucumber is found" do
|
37
37
|
ParallelCucumber.should_receive(:open).with{|x,y| x =~ %r{script/cucumber}}.and_return mocked_process
|
38
|
-
ParallelCucumber.run_tests(['xxx'],1,
|
38
|
+
ParallelCucumber.run_tests(['xxx'],1,{})
|
39
39
|
end
|
40
40
|
|
41
41
|
it "runs cucumber by default" do
|
42
42
|
File.stub!(:file?).with('script/cucumber').and_return false
|
43
43
|
ParallelCucumber.should_receive(:open).with{|x,y| x !~ %r{(script/cucumber)|(bundle exec cucumber)}}.and_return mocked_process
|
44
|
-
ParallelCucumber.run_tests(['xxx'],1,
|
44
|
+
ParallelCucumber.run_tests(['xxx'],1,{})
|
45
45
|
end
|
46
46
|
|
47
47
|
it "uses options passed in" do
|
48
|
-
ParallelCucumber.should_receive(:open).with{|x,y| x =~ %r{script/cucumber -p default}}.and_return mocked_process
|
49
|
-
ParallelCucumber.run_tests(['xxx'],1
|
48
|
+
ParallelCucumber.should_receive(:open).with{|x,y| x =~ %r{script/cucumber .* -p default}}.and_return mocked_process
|
49
|
+
ParallelCucumber.run_tests(['xxx'],1,:test_options => '-p default')
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -69,4 +69,4 @@ EOF
|
|
69
69
|
ParallelCucumber.find_results(output).should == ["7 scenarios (3 failed, 4 passed)", "33 steps (3 failed, 2 skipped, 28 passed)", "4 scenarios (4 passed)", "40 steps (40 passed)"]
|
70
70
|
end
|
71
71
|
end
|
72
|
-
end
|
72
|
+
end
|
data/spec/parallel_specs_spec.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'parallel_specs/spec_runtime_logger'
|
3
|
+
require 'parallel_specs/spec_summary_logger'
|
4
|
+
require 'parallel_specs/spec_failures_logger'
|
2
5
|
|
3
6
|
describe ParallelSpecs do
|
4
7
|
test_tests_in_groups(ParallelSpecs, 'spec', '_spec.rb')
|
@@ -8,29 +11,44 @@ describe ParallelSpecs do
|
|
8
11
|
File.stub!(:file?).with('script/spec').and_return false
|
9
12
|
File.stub!(:file?).with('spec/spec.opts').and_return false
|
10
13
|
File.stub!(:file?).with('spec/parallel_spec.opts').and_return false
|
14
|
+
File.stub!(:file?).with('.rspec_parallel').and_return false
|
11
15
|
ParallelSpecs.stub!(:bundler_enabled?).and_return false
|
12
16
|
end
|
13
17
|
|
14
18
|
it "uses TEST_ENV_NUMBER=blank when called for process 0" do
|
15
19
|
ParallelSpecs.should_receive(:open).with{|x,y|x=~/TEST_ENV_NUMBER= /}.and_return mocked_process
|
16
|
-
ParallelSpecs.run_tests(['xxx'],0,
|
20
|
+
ParallelSpecs.run_tests(['xxx'],0,{})
|
17
21
|
end
|
18
22
|
|
19
23
|
it "uses TEST_ENV_NUMBER=2 when called for process 1" do
|
20
24
|
ParallelSpecs.should_receive(:open).with{|x,y| x=~/TEST_ENV_NUMBER=2/}.and_return mocked_process
|
21
|
-
ParallelSpecs.run_tests(['xxx'],1,
|
25
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
22
26
|
end
|
23
27
|
|
24
28
|
it "runs with color when called from cmdline" do
|
25
|
-
ParallelSpecs.should_receive(:open).with{|x,y| x=~/
|
29
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x=~/ --tty /}.and_return mocked_process
|
26
30
|
$stdout.should_receive(:tty?).and_return true
|
27
|
-
ParallelSpecs.run_tests(['xxx'],1,
|
31
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
28
32
|
end
|
29
33
|
|
30
34
|
it "runs without color when not called from cmdline" do
|
31
|
-
ParallelSpecs.should_receive(:open).with{|x,y| x !~ /
|
35
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x !~ / --tty /}.and_return mocked_process
|
32
36
|
$stdout.should_receive(:tty?).and_return false
|
33
|
-
ParallelSpecs.run_tests(['xxx'],1,
|
37
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
38
|
+
end
|
39
|
+
|
40
|
+
it "runs with color for rspec 1 when called for the cmdline" do
|
41
|
+
File.should_receive(:file?).with('script/spec').and_return true
|
42
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x=~/ RSPEC_COLOR=1 /}.and_return mocked_process
|
43
|
+
$stdout.should_receive(:tty?).and_return true
|
44
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
45
|
+
end
|
46
|
+
|
47
|
+
it "runs without color for rspec 1 when not called for the cmdline" do
|
48
|
+
File.should_receive(:file?).with('script/spec').and_return true
|
49
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x !~ / RSPEC_COLOR=1 /}.and_return mocked_process
|
50
|
+
$stdout.should_receive(:tty?).and_return false
|
51
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
34
52
|
end
|
35
53
|
|
36
54
|
it "run bundle exec spec when on bundler rspec 1" do
|
@@ -38,7 +56,7 @@ describe ParallelSpecs do
|
|
38
56
|
ParallelSpecs.stub!(:bundler_enabled?).and_return true
|
39
57
|
ParallelSpecs.stub!(:run).with("bundle show rspec").and_return "/foo/bar/rspec-1.0.2"
|
40
58
|
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{bundle exec spec}}.and_return mocked_process
|
41
|
-
ParallelSpecs.run_tests(['xxx'],1,
|
59
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
42
60
|
end
|
43
61
|
|
44
62
|
it "run bundle exec rspec when on bundler rspec 2" do
|
@@ -46,39 +64,46 @@ describe ParallelSpecs do
|
|
46
64
|
ParallelSpecs.stub!(:bundler_enabled?).and_return true
|
47
65
|
ParallelSpecs.stub!(:run).with("bundle show rspec").and_return "/foo/bar/rspec-2.0.2"
|
48
66
|
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{bundle exec rspec}}.and_return mocked_process
|
49
|
-
ParallelSpecs.run_tests(['xxx'],1,
|
67
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
50
68
|
end
|
51
69
|
|
52
70
|
it "runs script/spec when script/spec can be found" do
|
53
71
|
File.should_receive(:file?).with('script/spec').and_return true
|
54
72
|
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{script/spec}}.and_return mocked_process
|
55
|
-
ParallelSpecs.run_tests(['xxx'],1,
|
73
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
56
74
|
end
|
57
75
|
|
58
76
|
it "runs spec when script/spec cannot be found" do
|
59
77
|
File.stub!(:file?).with('script/spec').and_return false
|
60
78
|
ParallelSpecs.should_receive(:open).with{|x,y| x !~ %r{script/spec}}.and_return mocked_process
|
61
|
-
ParallelSpecs.run_tests(['xxx'],1,
|
79
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
62
80
|
end
|
63
81
|
|
64
82
|
it "uses no -O when no opts where found" do
|
65
83
|
File.stub!(:file?).with('spec/spec.opts').and_return false
|
66
84
|
ParallelSpecs.should_receive(:open).with{|x,y| x !~ %r{spec/spec.opts}}.and_return mocked_process
|
67
|
-
ParallelSpecs.run_tests(['xxx'],1,
|
85
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
68
86
|
end
|
69
87
|
|
70
88
|
it "uses -O spec/spec.opts when found (with script/spec)" do
|
71
89
|
File.stub!(:file?).with('script/spec').and_return true
|
72
90
|
File.stub!(:file?).with('spec/spec.opts').and_return true
|
73
|
-
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{script/spec\s
|
74
|
-
ParallelSpecs.run_tests(['xxx'],1,
|
91
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{script/spec\s+ -O spec/spec.opts}}.and_return mocked_process
|
92
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
75
93
|
end
|
76
94
|
|
77
95
|
it "uses -O spec/parallel_spec.opts when found (with script/spec)" do
|
78
96
|
File.stub!(:file?).with('script/spec').and_return true
|
79
97
|
File.should_receive(:file?).with('spec/parallel_spec.opts').and_return true
|
80
|
-
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{script/spec\s
|
81
|
-
ParallelSpecs.run_tests(['xxx'],1,
|
98
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{script/spec\s+ -O spec/parallel_spec.opts}}.and_return mocked_process
|
99
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
100
|
+
end
|
101
|
+
|
102
|
+
it "uses -O .rspec_parallel when found (with script/spec)" do
|
103
|
+
File.stub!(:file?).with('script/spec').and_return true
|
104
|
+
File.should_receive(:file?).with('.rspec_parallel').and_return true
|
105
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{script/spec\s+ -O .rspec_parallel}}.and_return mocked_process
|
106
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
82
107
|
end
|
83
108
|
|
84
109
|
it "uses -O spec/parallel_spec.opts with rspec1" do
|
@@ -88,30 +113,29 @@ describe ParallelSpecs do
|
|
88
113
|
ParallelSpecs.stub!(:run).with("bundle show rspec").and_return "/foo/bar/rspec-1.0.2"
|
89
114
|
|
90
115
|
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{spec\s+ -O spec/parallel_spec.opts}}.and_return mocked_process
|
91
|
-
ParallelSpecs.run_tests(['xxx'],1,
|
116
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
92
117
|
end
|
93
118
|
|
94
|
-
it "uses
|
119
|
+
it "uses -O spec/parallel_spec.opts with rspec2" do
|
95
120
|
File.should_receive(:file?).with('spec/parallel_spec.opts').and_return true
|
96
|
-
File.should_receive(:read).with('spec/parallel_spec.opts').and_return "--foo\n--bar\n"
|
97
121
|
|
98
122
|
ParallelSpecs.stub!(:bundler_enabled?).and_return true
|
99
|
-
ParallelSpecs.stub!(:run).with("bundle show rspec").and_return "/foo/bar/rspec-2.
|
123
|
+
ParallelSpecs.stub!(:run).with("bundle show rspec").and_return "/foo/bar/rspec-2.4.2"
|
100
124
|
|
101
|
-
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{rspec\s+ --
|
102
|
-
ParallelSpecs.run_tests(['xxx'],1,
|
125
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{rspec\s+ --color --tty -O spec/parallel_spec.opts}}.and_return mocked_process
|
126
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
103
127
|
end
|
104
128
|
|
105
129
|
it "uses options passed in" do
|
106
130
|
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{rspec -f n}}.and_return mocked_process
|
107
|
-
ParallelSpecs.run_tests(['xxx'],1,'-f n')
|
131
|
+
ParallelSpecs.run_tests(['xxx'],1, :test_options => '-f n')
|
108
132
|
end
|
109
133
|
|
110
134
|
it "returns the output" do
|
111
135
|
io = open('spec/spec_helper.rb')
|
112
136
|
ParallelSpecs.stub!(:print)
|
113
137
|
ParallelSpecs.should_receive(:open).and_return io
|
114
|
-
ParallelSpecs.run_tests(['xxx'],1,
|
138
|
+
ParallelSpecs.run_tests(['xxx'],1,{})[:stdout].should =~ /\$LOAD_PATH << File/
|
115
139
|
end
|
116
140
|
end
|
117
141
|
|
@@ -146,4 +170,4 @@ EOF
|
|
146
170
|
ParallelSpecs.find_results(output).should == ['0 examples, 0 failures, 0 pending','1 examples, 1 failures, 1 pending']
|
147
171
|
end
|
148
172
|
end
|
149
|
-
end
|
173
|
+
end
|