moxiesoft_parallel_tests 0.4.13 → 0.6.18
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.
- 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
|