parallel_tests 1.0.9 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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