parallel_tests 1.0.9 → 1.1.0

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/Readme.md +7 -3
  3. data/bin/parallel_cucumber +5 -1
  4. data/bin/parallel_rspec +5 -1
  5. data/bin/parallel_spinach +5 -1
  6. data/bin/parallel_test +5 -2
  7. data/lib/parallel_tests.rb +0 -1
  8. metadata +3 -51
  9. data/.gitignore +0 -4
  10. data/.rspec +0 -2
  11. data/.travis.yml +0 -10
  12. data/Gemfile +0 -9
  13. data/Gemfile.lock +0 -53
  14. data/Rakefile +0 -10
  15. data/ReadmeRails2.md +0 -48
  16. data/lib/parallel_tests/cli.rb +0 -206
  17. data/lib/parallel_tests/cucumber/failures_logger.rb +0 -25
  18. data/lib/parallel_tests/cucumber/runner.rb +0 -37
  19. data/lib/parallel_tests/cucumber/scenario_line_logger.rb +0 -51
  20. data/lib/parallel_tests/cucumber/scenarios.rb +0 -34
  21. data/lib/parallel_tests/gherkin/io.rb +0 -41
  22. data/lib/parallel_tests/gherkin/listener.rb +0 -87
  23. data/lib/parallel_tests/gherkin/runner.rb +0 -116
  24. data/lib/parallel_tests/gherkin/runtime_logger.rb +0 -28
  25. data/lib/parallel_tests/grouper.rb +0 -73
  26. data/lib/parallel_tests/railtie.rb +0 -8
  27. data/lib/parallel_tests/rspec/failures_logger.rb +0 -54
  28. data/lib/parallel_tests/rspec/logger_base.rb +0 -55
  29. data/lib/parallel_tests/rspec/runner.rb +0 -73
  30. data/lib/parallel_tests/rspec/runtime_logger.rb +0 -59
  31. data/lib/parallel_tests/rspec/summary_logger.rb +0 -19
  32. data/lib/parallel_tests/spinach/runner.rb +0 -19
  33. data/lib/parallel_tests/tasks.rb +0 -157
  34. data/lib/parallel_tests/test/runner.rb +0 -186
  35. data/lib/parallel_tests/test/runtime_logger.rb +0 -98
  36. data/lib/parallel_tests/version.rb +0 -3
  37. data/parallel_tests.gemspec +0 -14
  38. data/spec/integration_spec.rb +0 -437
  39. data/spec/parallel_tests/cli_spec.rb +0 -149
  40. data/spec/parallel_tests/cucumber/failure_logger_spec.rb +0 -43
  41. data/spec/parallel_tests/cucumber/runner_spec.rb +0 -25
  42. data/spec/parallel_tests/cucumber/scenarios_spec.rb +0 -69
  43. data/spec/parallel_tests/gherkin/listener_spec.rb +0 -96
  44. data/spec/parallel_tests/gherkin/runner_behaviour.rb +0 -216
  45. data/spec/parallel_tests/grouper_spec.rb +0 -61
  46. data/spec/parallel_tests/rspec/failures_logger_spec.rb +0 -82
  47. data/spec/parallel_tests/rspec/logger_base_spec.rb +0 -35
  48. data/spec/parallel_tests/rspec/runner_spec.rb +0 -201
  49. data/spec/parallel_tests/rspec/runtime_logger_spec.rb +0 -131
  50. data/spec/parallel_tests/rspec/summary_logger_spec.rb +0 -37
  51. data/spec/parallel_tests/spinach/runner_spec.rb +0 -12
  52. data/spec/parallel_tests/tasks_spec.rb +0 -178
  53. data/spec/parallel_tests/test/runner_spec.rb +0 -407
  54. data/spec/parallel_tests/test/runtime_logger_spec.rb +0 -112
  55. data/spec/parallel_tests_spec.rb +0 -137
  56. data/spec/spec_helper.rb +0 -182
@@ -1,186 +0,0 @@
1
- require 'parallel_tests'
2
-
3
- module ParallelTests
4
- module Test
5
- class Runner
6
- NAME = 'Test'
7
-
8
- class << self
9
- # --- usually overwritten by other runners
10
-
11
- def name
12
- NAME
13
- end
14
-
15
- def runtime_log
16
- 'tmp/parallel_runtime_test.log'
17
- end
18
-
19
- def test_suffix
20
- /_(test|spec).rb$/
21
- end
22
-
23
- def test_file_name
24
- "test"
25
- end
26
-
27
- def run_tests(test_files, process_number, num_processes, options)
28
- require_list = test_files.map { |filename| %{"#{File.expand_path filename}"} }.join(",")
29
- cmd = "#{executable} -Itest -e '[#{require_list}].each {|f| require f }' -- #{options[:test_options]}"
30
- execute_command(cmd, process_number, num_processes, options)
31
- end
32
-
33
- def line_is_result?(line)
34
- line.gsub!(/[.F*]/,'')
35
- line =~ /\d+ failure/
36
- end
37
-
38
- # --- usually used by other runners
39
-
40
- # finds all tests and partitions them into groups
41
- def tests_in_groups(tests, num_groups, options={})
42
- tests = find_tests(tests, options)
43
-
44
- tests = if options[:group_by] == :found
45
- tests.map { |t| [t, 1] }
46
- elsif options[:group_by] == :filesize
47
- with_filesize_info(tests)
48
- else
49
- with_runtime_info(tests, options)
50
- end
51
- Grouper.in_even_groups_by_size(tests, num_groups, options)
52
- end
53
-
54
- def execute_command(cmd, process_number, num_processes, options)
55
- env = (options[:env] || {}).merge(
56
- "TEST_ENV_NUMBER" => test_env_number(process_number),
57
- "PARALLEL_TEST_GROUPS" => num_processes
58
- )
59
- cmd = "nice #{cmd}" if options[:nice]
60
- cmd = "#{cmd} 2>&1" if options[:combine_stderr]
61
-
62
- execute_command_and_capture_output(env, cmd, options[:serialize_stdout])
63
- end
64
-
65
- def execute_command_and_capture_output(env, cmd, silence)
66
- # make processes descriptive / visible in ps -ef
67
- separator = (WINDOWS ? ' & ' : ';')
68
- exports = env.map do |k,v|
69
- if WINDOWS
70
- "(SET \"#{k}=#{v}\")"
71
- else
72
- "#{k}=#{v};export #{k}"
73
- end
74
- end.join(separator)
75
- cmd = "#{exports}#{separator}#{cmd}"
76
-
77
- output = open("|#{cmd}", "r") { |output| capture_output(output, silence) }
78
- exitstatus = $?.exitstatus
79
-
80
- {:stdout => output, :exit_status => exitstatus}
81
- end
82
-
83
- def find_results(test_output)
84
- test_output.split("\n").map {|line|
85
- line.gsub!(/\e\[\d+m/,'')
86
- next unless line_is_result?(line)
87
- line
88
- }.compact
89
- end
90
-
91
- def test_env_number(process_number)
92
- process_number == 0 ? '' : process_number + 1
93
- end
94
-
95
- def summarize_results(results)
96
- sums = sum_up_results(results)
97
- sums.sort.map{|word, number| "#{number} #{word}#{'s' if number != 1}" }.join(', ')
98
- end
99
-
100
- protected
101
-
102
- def executable
103
- ENV['PARALLEL_TESTS_EXECUTABLE'] || determine_executable
104
- end
105
-
106
- def determine_executable
107
- "ruby"
108
- end
109
-
110
- def sum_up_results(results)
111
- results = results.join(' ').gsub(/s\b/,'') # combine and singularize results
112
- counts = results.scan(/(\d+) (\w+)/)
113
- counts.inject(Hash.new(0)) do |sum, (number, word)|
114
- sum[word] += number.to_i
115
- sum
116
- end
117
- end
118
-
119
- # read output of the process and print it in chunks
120
- def capture_output(out, silence)
121
- result = ""
122
- loop do
123
- begin
124
- read = out.readpartial(1000000) # read whatever chunk we can get
125
- if RUBY_VERSION >= "1.9" && Encoding.default_internal
126
- read = read.force_encoding(Encoding.default_internal)
127
- end
128
- result << read
129
- unless silence
130
- $stdout.print read
131
- $stdout.flush
132
- end
133
- end
134
- end rescue EOFError
135
- result
136
- end
137
-
138
- def with_runtime_info(tests, options = {})
139
- log = options[:runtime_log] || runtime_log
140
- lines = File.read(log).split("\n") rescue []
141
-
142
- # use recorded test runtime if we got enough data
143
- if lines.size * 1.5 > tests.size
144
- puts "Using recorded test runtime: #{log}"
145
- times = Hash.new(1)
146
- lines.each do |line|
147
- test, time = line.split(":")
148
- next unless test and time
149
- times[File.expand_path(test)] = time.to_f
150
- end
151
- tests.sort.map{|test| [test, times[File.expand_path(test)]] }
152
- else # use file sizes
153
- with_filesize_info(tests)
154
- end
155
- end
156
-
157
- def with_filesize_info(tests)
158
- # use filesize to group files
159
- tests.sort.map { |test| [test, File.stat(test).size] }
160
- end
161
-
162
- def find_tests(tests, options = {})
163
- (tests || []).map do |file_or_folder|
164
- if File.directory?(file_or_folder)
165
- files = files_in_folder(file_or_folder, options)
166
- files.grep(test_suffix).grep(options[:pattern]||//)
167
- else
168
- file_or_folder
169
- end
170
- end.flatten.uniq
171
- end
172
-
173
- def files_in_folder(folder, options={})
174
- pattern = if options[:symlinks] == false # not nil or true
175
- "**/*"
176
- else
177
- # follow one symlink and direct children
178
- # http://stackoverflow.com/questions/357754/can-i-traverse-symlinked-directories-in-ruby-with-a-glob
179
- "**{,/*/**}/*"
180
- end
181
- Dir[File.join(folder, pattern)].uniq
182
- end
183
- end
184
- end
185
- end
186
- end
@@ -1,98 +0,0 @@
1
- require 'parallel_tests'
2
- require 'parallel_tests/test/runner'
3
-
4
- module ParallelTests
5
- module Test
6
- class RuntimeLogger
7
- @@has_started = false
8
-
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
12
-
13
- if !@@has_started # make empty log file
14
- File.open(logfile, 'w'){}
15
- @@has_started = true
16
- end
17
-
18
- locked_appending_to(logfile) do |file|
19
- file.puts(message(test, start_time, end_time))
20
- end
21
- end
22
-
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
30
-
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/"
35
-
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
49
- end
50
- result
51
- end
52
-
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]}
57
-
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
65
-
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
74
- end
75
- end
76
-
77
- def logfile
78
- ParallelTests::Test::Runner.runtime_log
79
- end
80
- end
81
- end
82
- end
83
- end
84
-
85
- require 'test/unit/testsuite'
86
- class ::Test::Unit::TestSuite
87
- alias :run_without_timing :run unless defined? @@timing_installed
88
-
89
- def run(result, &progress_block)
90
- first_test = self.tests.first
91
- start_time = ParallelTests.now
92
- run_without_timing(result, &progress_block)
93
- end_time = ParallelTests.now
94
- ParallelTests::Test::RuntimeLogger.log(first_test, start_time, end_time)
95
- end
96
-
97
- @@timing_installed = true
98
- end
@@ -1,3 +0,0 @@
1
- module ParallelTests
2
- VERSION = Version = '1.0.9'
3
- end
@@ -1,14 +0,0 @@
1
- $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
2
- name = "parallel_tests"
3
- require "#{name}/version"
4
-
5
- Gem::Specification.new name, ParallelTests::VERSION do |s|
6
- s.summary = "Run Test::Unit / RSpec / Cucumber / Spinach in parallel"
7
- s.authors = ["Michael Grosser"]
8
- s.email = "michael@grosser.it"
9
- s.homepage = "http://github.com/grosser/#{name}"
10
- s.files = `git ls-files`.split("\n")
11
- s.license = "MIT"
12
- s.executables = ["parallel_spinach", "parallel_cucumber", "parallel_rspec", "parallel_test"]
13
- s.add_runtime_dependency "parallel"
14
- end
@@ -1,437 +0,0 @@
1
- #encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- describe 'CLI' do
6
- before do
7
- `rm -rf #{folder}`
8
- end
9
-
10
- after do
11
- `rm -rf #{folder}`
12
- end
13
-
14
- def folder
15
- "/tmp/parallel_tests_tests"
16
- end
17
-
18
- def write(file, content)
19
- path = "#{folder}/#{file}"
20
- ensure_folder File.dirname(path)
21
- File.open(path, 'w'){|f| f.write content }
22
- path
23
- end
24
-
25
- def read(file)
26
- File.read "#{folder}/#{file}"
27
- end
28
-
29
- def bin_folder
30
- "#{File.expand_path(File.dirname(__FILE__))}/../bin"
31
- end
32
-
33
- def executable(options={})
34
- "#{bin_folder}/parallel_#{options[:type] || 'test'}"
35
- end
36
-
37
- def ensure_folder(folder)
38
- `mkdir -p #{folder}` unless File.exist?(folder)
39
- end
40
-
41
- def run_tests(test_folder, options={})
42
- ensure_folder folder
43
- processes = "-n #{options[:processes]||2}" unless options[:processes] == false
44
- command = "cd #{folder} && #{options[:export]} #{executable(options)} #{test_folder} #{processes} #{options[:add]} 2>&1"
45
- result = `#{command}`
46
- raise "FAILED #{command}\n#{result}" if $?.success? == !!options[:fail]
47
- result
48
- end
49
-
50
- it "runs tests in parallel" do
51
- write 'spec/xxx_spec.rb', 'describe("it"){it("should"){puts "TEST1"}}'
52
- write 'spec/xxx2_spec.rb', 'describe("it"){it("should"){puts "TEST2"}}'
53
- result = run_tests "spec", :type => 'rspec'
54
-
55
- # test ran and gave their puts
56
- result.should include('TEST1')
57
- result.should include('TEST2')
58
-
59
- # all results present
60
- result.scan('1 example, 0 failure').size.should == 2 # 2 results
61
- result.scan('2 examples, 0 failures').size.should == 1 # 1 summary
62
- result.scan(/Finished in \d+\.\d+ seconds/).size.should == 2
63
- result.scan(/Took \d+\.\d+ seconds/).size.should == 1 # parallel summary
64
- end
65
-
66
- it "runs tests which outputs accented characters" do
67
- write "spec/xxx_spec.rb", "#encoding: utf-8\ndescribe('it'){it('should'){puts 'Byłem tu'}}"
68
- result = run_tests "spec", :type => 'rspec'
69
- # test ran and gave their puts
70
- result.should include('Byłem tu')
71
- end
72
-
73
- it "respects default encoding when reading child stdout", :encoding => true do
74
- write 'test/xxx_test.rb', <<-EOF
75
- # encoding: utf-8
76
- require 'test/unit'
77
- class XTest < Test::Unit::TestCase
78
- def test_unicode
79
- raise '¯\\_(ツ)_/¯'
80
- end
81
- end
82
- EOF
83
- # Need to tell Ruby to default to utf-8 to simulate environments where
84
- # this is set. (Otherwise, it defaults to nil and the undefined conversion
85
- # issue doesn't come up.)
86
- result = run_tests('test', :fail => true,
87
- :export => 'RUBYOPT=-Eutf-8:utf-8')
88
- result.should include('¯\_(ツ)_/¯')
89
- end
90
-
91
- it "does not run any tests if there are none" do
92
- write 'spec/xxx_spec.rb', '1'
93
- result = run_tests "spec", :type => 'rspec'
94
- result.should include('No examples found')
95
- result.should include('Took')
96
- end
97
-
98
- it "fails when tests fail" do
99
- write 'spec/xxx_spec.rb', 'describe("it"){it("should"){puts "TEST1"}}'
100
- write 'spec/xxx2_spec.rb', 'describe("it"){it("should"){1.should == 2}}'
101
- result = run_tests "spec", :fail => true, :type => 'rspec'
102
-
103
- result.scan('1 example, 1 failure').size.should == 1
104
- result.scan('1 example, 0 failure').size.should == 1
105
- result.scan('2 examples, 1 failure').size.should == 1
106
- end
107
-
108
- it "can serialize stdout" do
109
- write 'spec/xxx_spec.rb', '5.times{describe("it"){it("should"){sleep 0.01; puts "TEST1"}}}'
110
- write 'spec/xxx2_spec.rb', 'sleep 0.01; 5.times{describe("it"){it("should"){sleep 0.01; puts "TEST2"}}}'
111
- result = run_tests "spec", :type => 'rspec', :add => "--serialize-stdout"
112
-
113
- result.should_not =~ /TEST1.*TEST2.*TEST1/m
114
- result.should_not =~ /TEST2.*TEST1.*TEST2/m
115
- end
116
-
117
- it "can serialize stdout and stderr" do
118
- write 'spec/xxx_spec.rb', '5.times{describe("it"){it("should"){sleep 0.01; $stderr.puts "errTEST1"; puts "TEST1"}}}'
119
- write 'spec/xxx2_spec.rb', 'sleep 0.01; 5.times{describe("it"){it("should"){sleep 0.01; $stderr.puts "errTEST2"; puts "TEST2"}}}'
120
- result = run_tests "spec", :type => 'rspec', :add => "--serialize-stdout --combine-stderr"
121
-
122
- result.should_not =~ /TEST1.*TEST2.*TEST1/m
123
- result.should_not =~ /TEST2.*TEST1.*TEST2/m
124
- end
125
-
126
- context "with given commands" do
127
- it "can exec given commands with ENV['TEST_ENV_NUM']" do
128
- result = `#{executable} -e 'ruby -e "print ENV[:TEST_ENV_NUMBER.to_s].to_i"' -n 4`
129
- result.gsub('"','').split('').sort.should == %w[0 2 3 4]
130
- end
131
-
132
- it "can exec given command non-parallel" do
133
- result = `#{executable} -e 'ruby -e "sleep(rand(10)/100.0); puts ENV[:TEST_ENV_NUMBER.to_s].inspect"' -n 4 --non-parallel`
134
- result.split("\n").should == %w["" "2" "3" "4"]
135
- end
136
-
137
- it "can serialize stdout" do
138
- result = `#{executable} -e 'ruby -e "5.times{sleep 0.01;puts ENV[:TEST_ENV_NUMBER.to_s].to_i;STDOUT.flush}"' -n 2 --serialize-stdout`
139
- result.should_not =~ /0.*2.*0/m
140
- result.should_not =~ /2.*0.*2/m
141
- end
142
-
143
- it "exists with success if all sub-processes returned success" do
144
- system("#{executable} -e 'cat /dev/null' -n 4").should == true
145
- end
146
-
147
- it "exists with failure if any sub-processes returned failure" do
148
- system("#{executable} -e 'test -e xxxx' -n 4").should == false
149
- end
150
- end
151
-
152
- it "runs through parallel_rspec" do
153
- version = `#{executable} -v`
154
- `#{bin_folder}/parallel_rspec -v`.should == version
155
- end
156
-
157
- it "runs through parallel_cucumber" do
158
- version = `#{executable} -v`
159
- `#{bin_folder}/parallel_cucumber -v`.should == version
160
- end
161
-
162
- it "runs through parallel_spinach" do
163
- version = `#{executable} -v`
164
- `#{bin_folder}/parallel_spinach -v`.should == version
165
- end
166
-
167
- it "runs with --group-by found" do
168
- # it only tests that it does not blow up, as it did before fixing...
169
- write "spec/x1_spec.rb", "puts '111'"
170
- run_tests "spec", :type => 'rspec', :add => '--group-by found'
171
- end
172
-
173
- it "runs faster with more processes" do
174
- pending if RUBY_PLATFORM == "java" # just too slow ...
175
- 2.times{|i|
176
- write "spec/xxx#{i}_spec.rb", 'describe("it"){it("should"){sleep 5}}; $stderr.puts ENV["TEST_ENV_NUMBER"]'
177
- }
178
- t = Time.now
179
- run_tests("spec", :processes => 2, :type => 'rspec')
180
- expected = 10
181
- (Time.now - t).should <= expected
182
- end
183
-
184
- it "can run with given files" do
185
- write "spec/x1_spec.rb", "puts '111'"
186
- write "spec/x2_spec.rb", "puts '222'"
187
- write "spec/x3_spec.rb", "puts '333'"
188
- result = run_tests "spec/x1_spec.rb spec/x3_spec.rb", :type => 'rspec'
189
- result.should include('111')
190
- result.should include('333')
191
- result.should_not include('222')
192
- end
193
-
194
- it "runs successfully without any files" do
195
- results = run_tests "", :type => 'rspec'
196
- results.should include("2 processes for 0 specs")
197
- results.should include("Took")
198
- end
199
-
200
- it "can run with test-options" do
201
- write "spec/x1_spec.rb", "111"
202
- write "spec/x2_spec.rb", "111"
203
- result = run_tests "spec",
204
- :add => "--test-options ' --version'",
205
- :processes => 2,
206
- :type => 'rspec'
207
- result.should =~ /\d+\.\d+\.\d+.*\d+\.\d+\.\d+/m # prints version twice
208
- end
209
-
210
- it "runs with PARALLEL_TEST_PROCESSORS processes" do
211
- processes = 5
212
- processes.times{|i|
213
- write "spec/x#{i}_spec.rb", "puts %{ENV-\#{ENV['TEST_ENV_NUMBER']}-}"
214
- }
215
- result = run_tests "spec",
216
- :export => "PARALLEL_TEST_PROCESSORS=#{processes}",
217
- :processes => processes,
218
- :type => 'rspec'
219
- result.scan(/ENV-.?-/).should =~ ["ENV--", "ENV-2-", "ENV-3-", "ENV-4-", "ENV-5-"]
220
- end
221
-
222
- it "filters test by given pattern and relative paths" do
223
- write "spec/x_spec.rb", "puts 'XXX'"
224
- write "spec/y_spec.rb", "puts 'YYY'"
225
- write "spec/z_spec.rb", "puts 'ZZZ'"
226
- result = run_tests "spec", :add => "-p '^spec/(x|z)'", :type => "rspec"
227
- result.should include('XXX')
228
- result.should_not include('YYY')
229
- result.should include('ZZZ')
230
- end
231
-
232
- it "can wait_for_other_processes_to_finish" do
233
- pending if RUBY_PLATFORM == "java" # just too slow ...
234
- write "test/a_test.rb", "require 'parallel_tests'; sleep 0.5 ; ParallelTests.wait_for_other_processes_to_finish; puts 'a'"
235
- write "test/b_test.rb", "sleep 1; puts 'b'"
236
- write "test/c_test.rb", "sleep 1.5; puts 'c'"
237
- write "test/d_test.rb", "sleep 2; puts 'd'"
238
- run_tests("test", :processes => 4).should include("b\nc\nd\na\n")
239
- end
240
-
241
- it "can run only a single group" do
242
- pending if RUBY_PLATFORM == "java" # just too slow ...
243
- write "test/long_test.rb", "puts 'this is a long test'"
244
- write "test/short_test.rb", "puts 'short test'"
245
-
246
- group_1_result = run_tests("test", :processes => 2, :add => '--only-group 1')
247
- group_1_result.should include("this is a long test")
248
- group_1_result.should_not include("short test")
249
-
250
- group_2_result = run_tests("test", :processes => 2, :add => '--only-group 2')
251
- group_2_result.should_not include("this is a long test")
252
- group_2_result.should include("short test")
253
- end
254
-
255
- context "Test::Unit" do
256
- it "runs" do
257
- write "test/x1_test.rb", "require 'test/unit'; class XTest < Test::Unit::TestCase; def test_xxx; end; end"
258
- result = run_tests("test")
259
- result.should include('1 test')
260
- end
261
-
262
- it "passes test options" do
263
- write "test/x1_test.rb", "require 'test/unit'; class XTest < Test::Unit::TestCase; def test_xxx; end; end"
264
- result = run_tests("test", :add => '--test-options "-v"')
265
- result.should include('test_xxx') # verbose output of every test
266
- end
267
-
268
- it "runs successfully without any files" do
269
- results = run_tests("")
270
- results.should include("2 processes for 0 tests")
271
- results.should include("Took")
272
- end
273
- end
274
-
275
- context "Cucumber" do
276
- before do
277
- write "features/steps/a.rb", "
278
- Given('I print TEST_ENV_NUMBER'){ puts \"YOUR TEST ENV IS \#{ENV['TEST_ENV_NUMBER']}!\" }
279
- And('I sleep a bit'){ sleep 0.2 }
280
- And('I pass'){ true }
281
- And('I fail'){ fail }
282
- "
283
- end
284
-
285
- it "runs tests which outputs accented characters" do
286
- write "features/good1.feature", "Feature: xxx\n Scenario: xxx\n Given I print accented characters"
287
- write "features/steps/a.rb", "#encoding: utf-8\nGiven('I print accented characters'){ puts \"I tu też\" }"
288
- result = run_tests "features", :type => "cucumber", :add => '--pattern good'
289
- result.should include('I tu też')
290
- end
291
-
292
- it "passes TEST_ENV_NUMBER when running with pattern (issue #86)" do
293
- write "features/good1.feature", "Feature: xxx\n Scenario: xxx\n Given I print TEST_ENV_NUMBER"
294
- write "features/good2.feature", "Feature: xxx\n Scenario: xxx\n Given I print TEST_ENV_NUMBER"
295
- write "features/b.feature", "Feature: xxx\n Scenario: xxx\n Given I FAIL"
296
- write "features/steps/a.rb", "Given('I print TEST_ENV_NUMBER'){ puts \"YOUR TEST ENV IS \#{ENV['TEST_ENV_NUMBER']}!\" }"
297
-
298
- result = run_tests "features", :type => "cucumber", :add => '--pattern good'
299
-
300
- result.should include('YOUR TEST ENV IS 2!')
301
- result.should include('YOUR TEST ENV IS !')
302
- result.should_not include('I FAIL')
303
- end
304
-
305
- it "writes a runtime log" do
306
- pending "TODO find out why this fails" if RUBY_PLATFORM == "java"
307
-
308
- log = "tmp/parallel_runtime_cucumber.log"
309
- write(log, "x")
310
- 2.times{|i|
311
- # needs sleep so that runtime loggers dont overwrite each other initially
312
- write "features/good#{i}.feature", "Feature: xxx\n Scenario: xxx\n Given I print TEST_ENV_NUMBER\n And I sleep a bit"
313
- }
314
- run_tests "features", :type => "cucumber"
315
- read(log).gsub(/\.\d+/,'').split("\n").should =~ [
316
- "features/good0.feature:0",
317
- "features/good1.feature:0"
318
- ]
319
- end
320
-
321
- it "runs each feature once when there are more processes then features (issue #89)" do
322
- 2.times{|i|
323
- write "features/good#{i}.feature", "Feature: xxx\n Scenario: xxx\n Given I print TEST_ENV_NUMBER"
324
- }
325
- result = run_tests "features", :type => "cucumber", :add => '-n 3'
326
- result.scan(/YOUR TEST ENV IS \d?!/).sort.should == ["YOUR TEST ENV IS !", "YOUR TEST ENV IS 2!"]
327
- end
328
-
329
- it "runs successfully without any files" do
330
- results = run_tests("", :type => "cucumber")
331
- results.should include("2 processes for 0 features")
332
- results.should include("Took")
333
- end
334
-
335
- it "collates failing scenarios" do
336
- write "features/pass.feature", "Feature: xxx\n Scenario: xxx\n Given I pass"
337
- write "features/fail1.feature", "Feature: xxx\n Scenario: xxx\n Given I fail"
338
- write "features/fail2.feature", "Feature: xxx\n Scenario: xxx\n Given I fail"
339
- results = run_tests "features", :processes => 3, :type => "cucumber", :fail => true
340
-
341
- results.should include """
342
- Failing Scenarios:
343
- cucumber features/fail2.feature:2 # Scenario: xxx
344
- cucumber features/fail1.feature:2 # Scenario: xxx
345
-
346
- 3 scenarios (2 failed, 1 passed)
347
- 3 steps (2 failed, 1 passed)
348
- """
349
- end
350
-
351
- it "groups by scenario" do
352
- write "features/long.feature", <<-EOS
353
- Feature: xxx
354
- Scenario: xxx
355
- Given I print TEST_ENV_NUMBER
356
-
357
- Scenario: xxx
358
- Given I print TEST_ENV_NUMBER
359
-
360
- Scenario Outline: xxx
361
- Given I print TEST_ENV_NUMBER
362
-
363
- Examples:
364
- | num |
365
- | one |
366
- | two |
367
- EOS
368
- result = run_tests "features", :type => "cucumber", :add => "--group-by scenarios"
369
- result.should include("2 processes for 4 scenarios")
370
- end
371
-
372
- it "groups by step" do
373
- write "features/good1.feature", "Feature: xxx\n Scenario: xxx\n Given I print TEST_ENV_NUMBER"
374
- write "features/good2.feature", "Feature: xxx\n Scenario: xxx\n Given I print TEST_ENV_NUMBER"
375
-
376
- result = run_tests "features", :type => "cucumber", :add => '--group-by steps'
377
-
378
- result.should include("2 processes for 2 features")
379
- end
380
- end
381
-
382
- context "Spinach", :fails_on_ruby_187 => true do
383
- before do
384
- 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"
385
- end
386
-
387
- it "runs tests which outputs accented characters" do
388
- write "features/good1.feature", "Feature: a\n Scenario: xxx\n Given I print accented characters"
389
- 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"
390
- result = run_tests "features", :type => "spinach", :add => 'features/good1.feature'#, :add => '--pattern good'
391
- result.should include('I tu też')
392
- end
393
-
394
- it "passes TEST_ENV_NUMBER when running with pattern (issue #86)" do
395
- write "features/good1.feature", "Feature: a\n Scenario: xxx\n Given I print TEST_ENV_NUMBER"
396
- write "features/good2.feature", "Feature: a\n Scenario: xxx\n Given I print TEST_ENV_NUMBER"
397
- write "features/b.feature", "Feature: b\n Scenario: xxx\n Given I FAIL" #Expect this not to be run
398
- 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"
399
-
400
- result = run_tests "features", :type => "spinach", :add => '--pattern good'
401
-
402
- result.should include('YOUR TEST ENV IS 2!')
403
- result.should include('YOUR TEST ENV IS !')
404
- result.should_not include('I FAIL')
405
- end
406
-
407
- it "writes a runtime log" do
408
- pending 'not yet implemented -- custom runtime logging'
409
- log = "tmp/parallel_runtime_spinach.log"
410
- write(log, "x")
411
-
412
- 2.times{|i|
413
- # needs sleep so that runtime loggers dont overwrite each other initially
414
- write "features/good#{i}.feature", "Feature: A\n Scenario: xxx\n Given I print TEST_ENV_NUMBER\n And I sleep a bit"
415
- }
416
- result = run_tests "features", :type => "spinach"
417
- read(log).gsub(/\.\d+/,'').split("\n").should =~ [
418
- "features/good0.feature:0",
419
- "features/good1.feature:0"
420
- ]
421
- end
422
-
423
- it "runs each feature once when there are more processes then features (issue #89)" do
424
- 2.times{|i|
425
- write "features/good#{i}.feature", "Feature: A\n Scenario: xxx\n Given I print TEST_ENV_NUMBER\n"
426
- }
427
- result = run_tests "features", :type => "spinach", :add => '-n 3'
428
- result.scan(/YOUR TEST ENV IS \d?!/).sort.should == ["YOUR TEST ENV IS !", "YOUR TEST ENV IS 2!"]
429
- end
430
-
431
- it "runs successfully without any files" do
432
- results = run_tests("", :type => "spinach")
433
- results.should include("2 processes for 0 features")
434
- results.should include("Took")
435
- end
436
- end
437
- end