parallel_tests 0.13.3 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/Gemfile.lock +8 -2
- data/Rakefile +5 -1
- data/Readme.md +5 -2
- data/bin/parallel_spinach +5 -0
- data/lib/parallel_tests.rb +40 -38
- data/lib/parallel_tests/cli.rb +2 -2
- data/lib/parallel_tests/cucumber/failures_logger.rb +2 -2
- data/lib/parallel_tests/cucumber/runner.rb +5 -88
- data/lib/parallel_tests/{cucumber → gherkin}/io.rb +1 -1
- data/lib/parallel_tests/{cucumber/gherkin_listener.rb → gherkin/listener.rb} +2 -2
- data/lib/parallel_tests/gherkin/runner.rb +102 -0
- data/lib/parallel_tests/{cucumber → gherkin}/runtime_logger.rb +2 -2
- data/lib/parallel_tests/grouper.rb +41 -41
- data/lib/parallel_tests/rspec/failures_logger.rb +1 -1
- data/lib/parallel_tests/rspec/runner.rb +50 -48
- data/lib/parallel_tests/spinach/runner.rb +19 -0
- data/lib/parallel_tests/tasks.rb +7 -3
- data/lib/parallel_tests/test/runner.rb +125 -123
- data/lib/parallel_tests/test/runtime_logger.rb +57 -53
- data/lib/parallel_tests/version.rb +1 -1
- data/parallel_tests.gemspec +2 -2
- data/spec/integration_spec.rb +61 -0
- data/spec/parallel_tests/cucumber/failure_logger_spec.rb +1 -1
- data/spec/parallel_tests/cucumber/runner_spec.rb +5 -172
- data/spec/parallel_tests/{cucumber/gherkin_listener_spec.rb → gherkin/listener_spec.rb} +3 -3
- data/spec/parallel_tests/gherkin/runner_behaviour.rb +177 -0
- data/spec/parallel_tests/rspec/{failure_logger_spec.rb → failures_logger_spec.rb} +0 -0
- data/spec/parallel_tests/spinach/runner_spec.rb +12 -0
- data/spec/parallel_tests/test/runtime_logger_spec.rb +1 -1
- data/spec/parallel_tests_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -1
- metadata +16 -10
@@ -6,73 +6,77 @@ module ParallelTests
|
|
6
6
|
class RuntimeLogger
|
7
7
|
@@has_started = false
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
class << self
|
10
|
+
def log(test, start_time, end_time)
|
11
|
+
return if test.is_a? ::Test::Unit::TestSuite # don't log for suites-of-suites
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
if !@@has_started # make empty log file
|
14
|
+
File.open(logfile, 'w'){}
|
15
|
+
@@has_started = true
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
-
|
18
|
+
locked_appending_to(logfile) do |file|
|
19
|
+
file.puts(message(test, start_time, end_time))
|
20
|
+
end
|
19
21
|
end
|
20
|
-
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
private
|
24
|
+
|
25
|
+
def message(test, start_time, end_time)
|
26
|
+
delta = "%.2f" % (end_time.to_f-start_time.to_f)
|
27
|
+
filename = class_directory(test.class) + class_to_filename(test.class) + ".rb"
|
28
|
+
"#{filename}:#{delta}"
|
29
|
+
end
|
27
30
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
31
|
+
# Note: this is a best guess at conventional test directory structure, and may need
|
32
|
+
# tweaking / post-processing to match correctly for any given project
|
33
|
+
def class_directory(suspect)
|
34
|
+
result = "test/"
|
32
35
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
36
|
+
if defined?(Rails)
|
37
|
+
result += case suspect.superclass.name
|
38
|
+
when "ActionDispatch::IntegrationTest"
|
39
|
+
"integration/"
|
40
|
+
when "ActionDispatch::PerformanceTest"
|
41
|
+
"performance/"
|
42
|
+
when "ActionController::TestCase"
|
43
|
+
"functional/"
|
44
|
+
when "ActionView::TestCase"
|
45
|
+
"unit/helpers/"
|
46
|
+
else
|
47
|
+
"unit/"
|
48
|
+
end
|
45
49
|
end
|
50
|
+
result
|
46
51
|
end
|
47
|
-
result
|
48
|
-
end
|
49
52
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
53
|
+
# based on https://github.com/grosser/single_test/blob/master/lib/single_test.rb#L117
|
54
|
+
def class_to_filename(suspect)
|
55
|
+
word = suspect.to_s.dup
|
56
|
+
return word unless word.match /^[A-Z]/ and not word.match %r{/[a-z]}
|
54
57
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
58
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
59
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
60
|
+
word.gsub!(/\:\:/, '/')
|
61
|
+
word.tr!("-", "_")
|
62
|
+
word.downcase!
|
63
|
+
word
|
64
|
+
end
|
62
65
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
66
|
+
def locked_appending_to(file)
|
67
|
+
File.open(file, 'a') do |f|
|
68
|
+
begin
|
69
|
+
f.flock File::LOCK_EX
|
70
|
+
yield f
|
71
|
+
ensure
|
72
|
+
f.flock File::LOCK_UN
|
73
|
+
end
|
70
74
|
end
|
71
75
|
end
|
72
|
-
end
|
73
76
|
|
74
|
-
|
75
|
-
|
77
|
+
def logfile
|
78
|
+
ParallelTests::Test::Runner.runtime_log
|
79
|
+
end
|
76
80
|
end
|
77
81
|
end
|
78
82
|
end
|
data/parallel_tests.gemspec
CHANGED
@@ -3,12 +3,12 @@ name = "parallel_tests"
|
|
3
3
|
require "#{name}/version"
|
4
4
|
|
5
5
|
Gem::Specification.new name, ParallelTests::VERSION do |s|
|
6
|
-
s.summary = "Run Test::Unit / RSpec / Cucumber in parallel"
|
6
|
+
s.summary = "Run Test::Unit / RSpec / Cucumber / Spinach in parallel"
|
7
7
|
s.authors = ["Michael Grosser"]
|
8
8
|
s.email = "michael@grosser.it"
|
9
9
|
s.homepage = "http://github.com/grosser/#{name}"
|
10
10
|
s.files = `git ls-files`.split("\n")
|
11
11
|
s.license = "MIT"
|
12
|
-
s.executables = ["parallel_cucumber", "parallel_rspec", "parallel_test"]
|
12
|
+
s.executables = ["parallel_spinach", "parallel_cucumber", "parallel_rspec", "parallel_test"]
|
13
13
|
s.add_runtime_dependency "parallel"
|
14
14
|
end
|
data/spec/integration_spec.rb
CHANGED
@@ -132,6 +132,11 @@ describe 'CLI' do
|
|
132
132
|
`#{bin_folder}/parallel_cucumber -v`.should == version
|
133
133
|
end
|
134
134
|
|
135
|
+
it "runs through parallel_spinach" do
|
136
|
+
version = `#{executable} -v`
|
137
|
+
`#{bin_folder}/parallel_spinach -v`.should == version
|
138
|
+
end
|
139
|
+
|
135
140
|
it "runs with --group-by found" do
|
136
141
|
# it only tests that it does not blow up, as it did before fixing...
|
137
142
|
write "spec/x1_spec.rb", "puts '111'"
|
@@ -282,4 +287,60 @@ describe 'CLI' do
|
|
282
287
|
results.should include("Took")
|
283
288
|
end
|
284
289
|
end
|
290
|
+
|
291
|
+
context "Spinach", :fails_on_ruby_187 => true do
|
292
|
+
before do
|
293
|
+
write "features/steps/a.rb", "class A < Spinach::FeatureSteps\n Given 'I print TEST_ENV_NUMBER' do\n puts \"YOUR TEST ENV IS \#{ENV['TEST_ENV_NUMBER']}!\"\n end\n And 'I sleep a bit' do\n sleep 0.2\n end\nend"
|
294
|
+
end
|
295
|
+
|
296
|
+
it "runs tests which outputs accented characters" do
|
297
|
+
write "features/good1.feature", "Feature: a\n Scenario: xxx\n Given I print accented characters"
|
298
|
+
write "features/steps/a.rb", "#encoding: utf-8\nclass A < Spinach::FeatureSteps\nGiven 'I print accented characters' do\n puts \"I tu też\" \n end\nend"
|
299
|
+
result = run_tests "features", :type => "spinach", :add => 'features/good1.feature'#, :add => '--pattern good'
|
300
|
+
result.should include('I tu też')
|
301
|
+
end
|
302
|
+
|
303
|
+
it "passes TEST_ENV_NUMBER when running with pattern (issue #86)" do
|
304
|
+
write "features/good1.feature", "Feature: a\n Scenario: xxx\n Given I print TEST_ENV_NUMBER"
|
305
|
+
write "features/good2.feature", "Feature: a\n Scenario: xxx\n Given I print TEST_ENV_NUMBER"
|
306
|
+
write "features/b.feature", "Feature: b\n Scenario: xxx\n Given I FAIL" #Expect this not to be run
|
307
|
+
write "features/steps/a.rb", "class A < Spinach::FeatureSteps\nGiven('I print TEST_ENV_NUMBER'){ puts \"YOUR TEST ENV IS \#{ENV['TEST_ENV_NUMBER']}!\" }\nend"
|
308
|
+
|
309
|
+
result = run_tests "features", :type => "spinach", :add => '--pattern good'
|
310
|
+
|
311
|
+
result.should include('YOUR TEST ENV IS 2!')
|
312
|
+
result.should include('YOUR TEST ENV IS !')
|
313
|
+
result.should_not include('I FAIL')
|
314
|
+
end
|
315
|
+
|
316
|
+
it "writes a runtime log" do
|
317
|
+
pending 'not yet implemented -- custom runtime logging'
|
318
|
+
log = "tmp/parallel_runtime_spinach.log"
|
319
|
+
write(log, "x")
|
320
|
+
|
321
|
+
2.times{|i|
|
322
|
+
# needs sleep so that runtime loggers dont overwrite each other initially
|
323
|
+
write "features/good#{i}.feature", "Feature: A\n Scenario: xxx\n Given I print TEST_ENV_NUMBER\n And I sleep a bit"
|
324
|
+
}
|
325
|
+
result = run_tests "features", :type => "spinach"
|
326
|
+
read(log).gsub(/\.\d+/,'').split("\n").should =~ [
|
327
|
+
"features/good0.feature:0",
|
328
|
+
"features/good1.feature:0"
|
329
|
+
]
|
330
|
+
end
|
331
|
+
|
332
|
+
it "runs each feature once when there are more processes then features (issue #89)" do
|
333
|
+
2.times{|i|
|
334
|
+
write "features/good#{i}.feature", "Feature: A\n Scenario: xxx\n Given I print TEST_ENV_NUMBER\n"
|
335
|
+
}
|
336
|
+
result = run_tests "features", :type => "spinach", :add => '-n 3'
|
337
|
+
result.scan(/YOUR TEST ENV IS \d?!/).sort.should == ["YOUR TEST ENV IS !", "YOUR TEST ENV IS 2!"]
|
338
|
+
end
|
339
|
+
|
340
|
+
it "runs successfully without any files" do
|
341
|
+
results = run_tests("", :type => "spinach")
|
342
|
+
results.should include("2 processes for 0 features")
|
343
|
+
results.should include("Took")
|
344
|
+
end
|
345
|
+
end
|
285
346
|
end
|
@@ -1,179 +1,12 @@
|
|
1
1
|
require "spec_helper"
|
2
|
+
require "parallel_tests/gherkin/runner_behaviour"
|
2
3
|
require "parallel_tests/cucumber/runner"
|
3
4
|
|
4
|
-
describe ParallelTests::Cucumber do
|
5
|
+
describe ParallelTests::Cucumber::Runner do
|
5
6
|
test_tests_in_groups(ParallelTests::Cucumber::Runner, 'features', ".feature")
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
File.stub!(:file?).with('.bundle/environment.rb').and_return false
|
11
|
-
File.stub!(:file?).with('script/cucumber').and_return true
|
12
|
-
end
|
13
|
-
|
14
|
-
def call(*args)
|
15
|
-
ParallelTests::Cucumber::Runner.run_tests(*args)
|
16
|
-
end
|
17
|
-
|
18
|
-
def should_run_with(regex)
|
19
|
-
ParallelTests::Test::Runner.should_receive(:execute_command).with{|a,b,c,d| a =~ regex}
|
20
|
-
end
|
21
|
-
|
22
|
-
it "allows to override runner executable via PARALLEL_TESTS_EXECUTABLE" do
|
23
|
-
ENV['PARALLEL_TESTS_EXECUTABLE'] = 'script/custom_rspec'
|
24
|
-
should_run_with /script\/custom_rspec/
|
25
|
-
call(['xxx'],1,22,{})
|
26
|
-
ENV.delete('PARALLEL_TESTS_EXECUTABLE')
|
27
|
-
end
|
28
|
-
|
29
|
-
it "runs bundle exec cucumber when on bundler 0.9" do
|
30
|
-
ParallelTests.stub!(:bundler_enabled?).and_return true
|
31
|
-
should_run_with %r{bundle exec cucumber}
|
32
|
-
call(['xxx'],1,22,{})
|
33
|
-
end
|
34
|
-
|
35
|
-
it "runs script/cucumber when script/cucumber is found" do
|
36
|
-
should_run_with %r{script/cucumber}
|
37
|
-
call(['xxx'],1,22,{})
|
38
|
-
end
|
39
|
-
|
40
|
-
it "runs cucumber by default" do
|
41
|
-
File.stub!(:file?).with('script/cucumber').and_return false
|
42
|
-
should_run_with %r{^cucumber}
|
43
|
-
call(['xxx'],1,22,{})
|
44
|
-
end
|
45
|
-
|
46
|
-
it "uses bin/cucumber when present" do
|
47
|
-
File.stub(:exists?).with("bin/cucumber").and_return true
|
48
|
-
should_run_with %r{bin/cucumber}
|
49
|
-
call(['xxx'],1,22,{})
|
50
|
-
end
|
51
|
-
|
52
|
-
it "uses options passed in" do
|
53
|
-
should_run_with %r{script/cucumber .* -p default}
|
54
|
-
call(['xxx'],1,22,:test_options => '-p default')
|
55
|
-
end
|
56
|
-
|
57
|
-
it "sanitizes dangerous file names" do
|
58
|
-
should_run_with %r{xx\\ x}
|
59
|
-
call(['xx x'],1,22,{})
|
60
|
-
end
|
61
|
-
|
62
|
-
context "with parallel profile in config/cucumber.yml" do
|
63
|
-
before do
|
64
|
-
file_contents = 'parallel: -f progress'
|
65
|
-
Dir.stub(:glob).and_return ['config/cucumber.yml']
|
66
|
-
File.stub(:read).with('config/cucumber.yml').and_return file_contents
|
67
|
-
end
|
68
|
-
|
69
|
-
it "uses parallel profile" do
|
70
|
-
should_run_with %r{script/cucumber .* foo bar --profile parallel xxx}
|
71
|
-
call(['xxx'],1,22, :test_options => 'foo bar')
|
72
|
-
end
|
73
|
-
|
74
|
-
it "uses given profile via --profile" do
|
75
|
-
should_run_with %r{script/cucumber .* --profile foo xxx$}
|
76
|
-
call(['xxx'],1,22, :test_options => '--profile foo')
|
77
|
-
end
|
78
|
-
|
79
|
-
it "uses given profile via -p" do
|
80
|
-
should_run_with %r{script/cucumber .* -p foo xxx$}
|
81
|
-
call(['xxx'],1,22, :test_options => '-p foo')
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
it "does not use parallel profile if config/cucumber.yml does not contain it" do
|
86
|
-
file_contents = 'blob: -f progress'
|
87
|
-
should_run_with %r{script/cucumber .* foo bar}
|
88
|
-
Dir.should_receive(:glob).and_return ['config/cucumber.yml']
|
89
|
-
File.should_receive(:read).with('config/cucumber.yml').and_return file_contents
|
90
|
-
call(['xxx'],1,22,:test_options => 'foo bar')
|
91
|
-
end
|
92
|
-
|
93
|
-
it "does not use the parallel profile if config/cucumber.yml does not exist" do
|
94
|
-
should_run_with %r{script/cucumber} # TODO this test looks useless...
|
95
|
-
Dir.should_receive(:glob).and_return []
|
96
|
-
call(['xxx'],1,22,{})
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
describe :line_is_result? do
|
101
|
-
it "should match lines with only one scenario" do
|
102
|
-
line = "1 scenario (1 failed)"
|
103
|
-
ParallelTests::Cucumber::Runner.line_is_result?(line).should be_true
|
104
|
-
end
|
105
|
-
|
106
|
-
it "should match lines with multiple scenarios" do
|
107
|
-
line = "2 scenarios (1 failed, 1 passed)"
|
108
|
-
ParallelTests::Cucumber::Runner.line_is_result?(line).should be_true
|
109
|
-
end
|
110
|
-
|
111
|
-
it "should match lines with only one step" do
|
112
|
-
line = "1 step (1 failed)"
|
113
|
-
ParallelTests::Cucumber::Runner.line_is_result?(line).should be_true
|
114
|
-
end
|
115
|
-
|
116
|
-
it "should match lines with multiple steps" do
|
117
|
-
line = "5 steps (1 failed, 4 passed)"
|
118
|
-
ParallelTests::Cucumber::Runner.line_is_result?(line).should be_true
|
119
|
-
end
|
120
|
-
|
121
|
-
it "should not match other lines" do
|
122
|
-
line = ' And I should have "2" emails # features/step_definitions/user_steps.rb:25'
|
123
|
-
ParallelTests::Cucumber::Runner.line_is_result?(line).should be_false
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
describe :find_results do
|
128
|
-
it "finds multiple results in test output" do
|
129
|
-
output = <<EOF
|
130
|
-
And I should not see "/en/" # features/step_definitions/webrat_steps.rb:87
|
131
|
-
|
132
|
-
7 scenarios (3 failed, 4 passed)
|
133
|
-
33 steps (3 failed, 2 skipped, 28 passed)
|
134
|
-
/apps/rs/features/signup.feature:2
|
135
|
-
Given I am on "/" # features/step_definitions/common_steps.rb:12
|
136
|
-
When I click "register" # features/step_definitions/common_steps.rb:6
|
137
|
-
And I should have "2" emails # features/step_definitions/user_steps.rb:25
|
138
|
-
|
139
|
-
4 scenarios (4 passed)
|
140
|
-
40 steps (40 passed)
|
141
|
-
|
142
|
-
And I should not see "foo" # features/step_definitions/webrat_steps.rb:87
|
143
|
-
|
144
|
-
1 scenario (1 passed)
|
145
|
-
1 step (1 passed)
|
146
|
-
|
147
|
-
EOF
|
148
|
-
ParallelTests::Cucumber::Runner.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)", "1 scenario (1 passed)", "1 step (1 passed)"]
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
describe :summarize_results do
|
153
|
-
def call(*args)
|
154
|
-
ParallelTests::Cucumber::Runner.summarize_results(*args)
|
155
|
-
end
|
156
|
-
|
157
|
-
it "sums up results for scenarios and steps separately from each other" do
|
158
|
-
results = ["7 scenarios (3 failed, 4 passed)", "33 steps (3 failed, 2 skipped, 28 passed)", "4 scenarios (4 passed)",
|
159
|
-
"40 steps (40 passed)", "1 scenario (1 passed)", "1 step (1 passed)"]
|
160
|
-
call(results).should == "12 scenarios (3 failed, 9 passed)\n74 steps (3 failed, 2 skipped, 69 passed)"
|
161
|
-
end
|
162
|
-
|
163
|
-
it "adds same results with plurals" do
|
164
|
-
results = ["1 scenario (1 passed)", "2 steps (2 passed)",
|
165
|
-
"2 scenarios (2 passed)", "7 steps (7 passed)"]
|
166
|
-
call(results).should == "3 scenarios (3 passed)\n9 steps (9 passed)"
|
167
|
-
end
|
168
|
-
|
169
|
-
it "adds non-similar results" do
|
170
|
-
results = ["1 scenario (1 passed)", "1 step (1 passed)",
|
171
|
-
"2 scenarios (1 failed, 1 pending)", "2 steps (1 failed, 1 pending)"]
|
172
|
-
call(results).should == "3 scenarios (1 failed, 1 pending, 1 passed)\n3 steps (1 failed, 1 pending, 1 passed)"
|
173
|
-
end
|
174
|
-
|
175
|
-
it "does not pluralize 1" do
|
176
|
-
call(["1 scenario (1 passed)", "1 step (1 passed)"]).should == "1 scenario (1 passed)\n1 step (1 passed)"
|
177
|
-
end
|
8
|
+
it_should_behave_like 'gherkin runners' do
|
9
|
+
let(:runner_name) {'cucumber'}
|
10
|
+
let(:runner_class){ParallelTests::Cucumber::Runner}
|
178
11
|
end
|
179
12
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require 'parallel_tests/
|
1
|
+
require 'parallel_tests/gherkin/listener'
|
2
2
|
|
3
|
-
describe ParallelTests::
|
3
|
+
describe ParallelTests::Gherkin::Listener do
|
4
4
|
describe :collect do
|
5
5
|
before(:each) do
|
6
|
-
@listener = ParallelTests::
|
6
|
+
@listener = ParallelTests::Gherkin::Listener.new
|
7
7
|
@listener.uri("feature_file")
|
8
8
|
end
|
9
9
|
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "parallel_tests/gherkin/runner"
|
3
|
+
|
4
|
+
shared_examples_for 'gherkin runners' do
|
5
|
+
describe :run_tests do
|
6
|
+
before do
|
7
|
+
ParallelTests.stub!(:bundler_enabled?).and_return false
|
8
|
+
File.stub!(:file?).with('.bundle/environment.rb').and_return false
|
9
|
+
File.stub!(:file?).with("script/#{runner_name}").and_return true
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(*args)
|
13
|
+
runner_class().run_tests(*args)
|
14
|
+
end
|
15
|
+
|
16
|
+
def should_run_with(regex)
|
17
|
+
ParallelTests::Test::Runner.should_receive(:execute_command).with { |a, b, c, d| a =~ regex }
|
18
|
+
end
|
19
|
+
|
20
|
+
it "allows to override runner executable via PARALLEL_TESTS_EXECUTABLE" do
|
21
|
+
ENV['PARALLEL_TESTS_EXECUTABLE'] = 'script/custom_rspec'
|
22
|
+
should_run_with /script\/custom_rspec/
|
23
|
+
call(['xxx'], 1, 22, {})
|
24
|
+
ENV.delete('PARALLEL_TESTS_EXECUTABLE')
|
25
|
+
end
|
26
|
+
|
27
|
+
it "runs bundle exec {runner_name} when on bundler 0.9" do
|
28
|
+
ParallelTests.stub!(:bundler_enabled?).and_return true
|
29
|
+
should_run_with %r{bundle exec #{runner_name}}
|
30
|
+
call(['xxx'], 1, 22, {})
|
31
|
+
end
|
32
|
+
|
33
|
+
it "runs script/{runner_name} when script/{runner_name} is found" do
|
34
|
+
should_run_with %r{script/#{runner_name}}
|
35
|
+
call(['xxx'], 1, 22, {})
|
36
|
+
end
|
37
|
+
|
38
|
+
it "runs {runner_name} by default" do
|
39
|
+
File.stub!(:file?).with("script/#{runner_name}").and_return false
|
40
|
+
should_run_with %r{^#{runner_name}}
|
41
|
+
call(['xxx'], 1, 22, {})
|
42
|
+
end
|
43
|
+
|
44
|
+
it "uses bin/{runner_name} when present" do
|
45
|
+
File.stub(:exists?).with("bin/#{runner_name}").and_return true
|
46
|
+
should_run_with %r{bin/#{runner_name}}
|
47
|
+
call(['xxx'], 1, 22, {})
|
48
|
+
end
|
49
|
+
|
50
|
+
it "uses options passed in" do
|
51
|
+
should_run_with %r{script/#{runner_name} .* -p default}
|
52
|
+
call(['xxx'], 1, 22, :test_options => '-p default')
|
53
|
+
end
|
54
|
+
|
55
|
+
it "sanitizes dangerous file runner_names" do
|
56
|
+
should_run_with %r{xx\\ x}
|
57
|
+
call(['xx x'], 1, 22, {})
|
58
|
+
end
|
59
|
+
|
60
|
+
context "with parallel profile in config/{runner_name}.yml" do
|
61
|
+
before do
|
62
|
+
file_contents = 'parallel: -f progress'
|
63
|
+
Dir.stub(:glob).and_return ["config/#{runner_name}.yml"]
|
64
|
+
File.stub(:read).with("config/#{runner_name}.yml").and_return file_contents
|
65
|
+
end
|
66
|
+
|
67
|
+
it "uses parallel profile" do
|
68
|
+
should_run_with %r{script/#{runner_name} .* foo bar --profile parallel xxx}
|
69
|
+
call(['xxx'], 1, 22, :test_options => 'foo bar')
|
70
|
+
end
|
71
|
+
|
72
|
+
it "uses given profile via --profile" do
|
73
|
+
should_run_with %r{script/#{runner_name} .* --profile foo xxx$}
|
74
|
+
call(['xxx'], 1, 22, :test_options => '--profile foo')
|
75
|
+
end
|
76
|
+
|
77
|
+
it "uses given profile via -p" do
|
78
|
+
should_run_with %r{script/#{runner_name} .* -p foo xxx$}
|
79
|
+
call(['xxx'], 1, 22, :test_options => '-p foo')
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
it "does not use parallel profile if config/{runner_name}.yml does not contain it" do
|
84
|
+
file_contents = 'blob: -f progress'
|
85
|
+
should_run_with %r{script/#{runner_name} .* foo bar}
|
86
|
+
Dir.should_receive(:glob).and_return ["config/#{runner_name}.yml"]
|
87
|
+
File.should_receive(:read).with("config/#{runner_name}.yml").and_return file_contents
|
88
|
+
call(['xxx'], 1, 22, :test_options => 'foo bar')
|
89
|
+
end
|
90
|
+
|
91
|
+
it "does not use the parallel profile if config/{runner_name}.yml does not exist" do
|
92
|
+
should_run_with %r{script/#{runner_name}} # TODO this test looks useless...
|
93
|
+
Dir.should_receive(:glob).and_return []
|
94
|
+
call(['xxx'], 1, 22, {})
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe :line_is_result? do
|
99
|
+
it "should match lines with only one scenario" do
|
100
|
+
line = "1 scenario (1 failed)"
|
101
|
+
runner_class().line_is_result?(line).should be_true
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should match lines with multiple scenarios" do
|
105
|
+
line = "2 scenarios (1 failed, 1 passed)"
|
106
|
+
runner_class().line_is_result?(line).should be_true
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should match lines with only one step" do
|
110
|
+
line = "1 step (1 failed)"
|
111
|
+
runner_class().line_is_result?(line).should be_true
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should match lines with multiple steps" do
|
115
|
+
line = "5 steps (1 failed, 4 passed)"
|
116
|
+
runner_class().line_is_result?(line).should be_true
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should not match other lines" do
|
120
|
+
line = ' And I should have "2" emails # features/step_definitions/user_steps.rb:25'
|
121
|
+
runner_class().line_is_result?(line).should be_false
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe :find_results do
|
126
|
+
it "finds multiple results in test output" do
|
127
|
+
output = <<EOF
|
128
|
+
And I should not see "/en/" # features/step_definitions/webrat_steps.rb:87
|
129
|
+
|
130
|
+
7 scenarios (3 failed, 4 passed)
|
131
|
+
33 steps (3 failed, 2 skipped, 28 passed)
|
132
|
+
/apps/rs/features/signup.feature:2
|
133
|
+
Given I am on "/" # features/step_definitions/common_steps.rb:12
|
134
|
+
When I click "register" # features/step_definitions/common_steps.rb:6
|
135
|
+
And I should have "2" emails # features/step_definitions/user_steps.rb:25
|
136
|
+
|
137
|
+
4 scenarios (4 passed)
|
138
|
+
40 steps (40 passed)
|
139
|
+
|
140
|
+
And I should not see "foo" # features/step_definitions/webrat_steps.rb:87
|
141
|
+
|
142
|
+
1 scenario (1 passed)
|
143
|
+
1 step (1 passed)
|
144
|
+
|
145
|
+
EOF
|
146
|
+
runner_class().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)", "1 scenario (1 passed)", "1 step (1 passed)"]
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe :summarize_results do
|
151
|
+
def call(*args)
|
152
|
+
runner_class().summarize_results(*args)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "sums up results for scenarios and steps separately from each other" do
|
156
|
+
results = ["7 scenarios (3 failed, 4 passed)", "33 steps (3 failed, 2 skipped, 28 passed)", "4 scenarios (4 passed)",
|
157
|
+
"40 steps (40 passed)", "1 scenario (1 passed)", "1 step (1 passed)"]
|
158
|
+
call(results).should == "12 scenarios (3 failed, 9 passed)\n74 steps (3 failed, 2 skipped, 69 passed)"
|
159
|
+
end
|
160
|
+
|
161
|
+
it "adds same results with plurals" do
|
162
|
+
results = ["1 scenario (1 passed)", "2 steps (2 passed)",
|
163
|
+
"2 scenarios (2 passed)", "7 steps (7 passed)"]
|
164
|
+
call(results).should == "3 scenarios (3 passed)\n9 steps (9 passed)"
|
165
|
+
end
|
166
|
+
|
167
|
+
it "adds non-similar results" do
|
168
|
+
results = ["1 scenario (1 passed)", "1 step (1 passed)",
|
169
|
+
"2 scenarios (1 failed, 1 pending)", "2 steps (1 failed, 1 pending)"]
|
170
|
+
call(results).should == "3 scenarios (1 failed, 1 pending, 1 passed)\n3 steps (1 failed, 1 pending, 1 passed)"
|
171
|
+
end
|
172
|
+
|
173
|
+
it "does not pluralize 1" do
|
174
|
+
call(["1 scenario (1 passed)", "1 step (1 passed)"]).should == "1 scenario (1 passed)\n1 step (1 passed)"
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|