parallel_tests 5.1.0 → 5.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6c3298881c1895193a9ecea54a6d41578ea239a2f247f88bfd796cb59d6240b
4
- data.tar.gz: d4d5fc5bc795baa568a8ba3874f4d8a0e695cf72a35f10965215dbf961ac1f2f
3
+ metadata.gz: a7a2c5d683029ce50e608bd13d0d3d7490f3c3bcd29180a311383c9c4ae8c698
4
+ data.tar.gz: 6c779e00cf55b4bb34f740fb791b857b3ddeaaf42a5d595d207326184ddc0b91
5
5
  SHA512:
6
- metadata.gz: 1bdfe399bd6e3e3380853522202245562ccb6e1939ea42f25276475426ac61de386a24a1365d60467114badcac87cf5c56883028e55b5d6b39ccb531ffa9d3f7
7
- data.tar.gz: 93e6ddc6c20e98a86de94b5e6bd80dd0b1433a69cae9cfbcb8bf93f19aaa43e343b014c648435ca7a05f6ec81eb17c31ae332272fa45660445b068c3d9a2df78
6
+ metadata.gz: f363d5971f4a53180b4db97ec016b63a35e59dbf4d0416f71737e4b2e5e7c8c8aece067b45a80249123acf3c57761f6cf4daf12958ba00281e909122617e3eaf
7
+ data.tar.gz: 4524b05659ca8b2468023adbb1c28f41be9738230295ec630a8d8b85f74e804143a3ad3c42dddaa9a95cd0111a3530374ef0f101714ee849f402bbecdb2614cf
data/Readme.md CHANGED
@@ -129,7 +129,7 @@ Test groups will often run for different times, making the full test run as slow
129
129
 
130
130
  ### RSpec
131
131
 
132
- Rspec: Add to your `.rspec_parallel` (or `.rspec`) :
132
+ Rspec: Add to your `.rspec_parallel` (or `.rspec`), but can also be used via `--test-options='--format x'`:
133
133
 
134
134
  --format progress
135
135
  --format ParallelTests::RSpec::RuntimeLogger --out tmp/parallel_runtime_rspec.log
@@ -154,7 +154,7 @@ RSpec: SummaryLogger
154
154
 
155
155
  Log the test output without the different processes overwriting each other.
156
156
 
157
- Add the following to your `.rspec_parallel` (or `.rspec`) :
157
+ Add the following to your `.rspec_parallel` (or `.rspec`), but can also be used via `--test-options='--format x'`:
158
158
 
159
159
  --format progress
160
160
  --format ParallelTests::RSpec::SummaryLogger --out tmp/spec_summary.log
@@ -168,7 +168,7 @@ Produce pasteable command-line snippets for each failed example. For example:
168
168
  rspec /path/to/my_spec.rb:123 # should do something
169
169
  ```
170
170
 
171
- Add to `.rspec_parallel` or use as CLI flag:
171
+ Add the following to your `.rspec_parallel` (or `.rspec`), but can also be used via `--test-options='--format x'`:
172
172
 
173
173
  --format progress
174
174
  --format ParallelTests::RSpec::FailuresLogger --out tmp/failing_specs.log
@@ -188,7 +188,7 @@ Prints a single line for starting and finishing each example, to see what is cur
188
188
  [14402] [1] [PASSED] Bar bar
189
189
  ```
190
190
 
191
- Add to `.rspec_parallel` or use as CLI flag:
191
+ Add the following to your `.rspec_parallel` (or `.rspec`), but can also be used via `--test-options='--format x'`:
192
192
 
193
193
  --format ParallelTests::RSpec::VerboseLogger
194
194
 
@@ -206,6 +206,8 @@ Or add the formatter to the `parallel:` profile of your `cucumber.yml`:
206
206
 
207
207
  parallel: --format progress --format ParallelTests::Cucumber::FailuresLogger --out tmp/cucumber_failures.log
208
208
 
209
+ but can also be used via `--test-options='--format x'`:
210
+
209
211
  Note if your `cucumber.yml` default profile uses `<%= std_opts %>` you may need to insert this as follows `parallel: <%= std_opts %> --format progress...`
210
212
 
211
213
  To rerun failures:
@@ -237,7 +239,7 @@ Setup for non-rails
237
239
  `parallel_cucumber -n 2 -o '-p foo_profile --tags @only_this_tag or @only_that_tag --format summary'`
238
240
 
239
241
  Options are:
240
- <!-- copy output from bundle exec ./bin/parallel_test -h -->
242
+ <!-- rake readme -->
241
243
  -n PROCESSES How many processes to use, default: available CPUs
242
244
  -p, --pattern PATTERN run tests matching this regex pattern
243
245
  --exclude-pattern PATTERN exclude tests matching this regex pattern
@@ -256,7 +258,8 @@ Options are:
256
258
  --failure-exit-code INT Specify the exit code to use when tests fail
257
259
  --specify-groups SPECS Use 'specify-groups' if you want to specify multiple specs running in multiple
258
260
  processes in a specific formation. Commas indicate specs in the same process,
259
- pipes indicate specs in a new process. Cannot use with --single, --isolate, or
261
+ pipes indicate specs in a new process. If SPECS is a '-' the value for this
262
+ option is read from STDIN instead. Cannot use with --single, --isolate, or
260
263
  --isolate-n. Ex.
261
264
  $ parallel_tests -n 3 . --specify-groups '1_spec.rb,2_spec.rb|3_spec.rb'
262
265
  Process 1 will contain 1_spec.rb and 2_spec.rb
@@ -265,7 +268,10 @@ Options are:
265
268
  --only-group GROUP_INDEX[,GROUP_INDEX]
266
269
  Only run the given group numbers.
267
270
  Changes `--group-by` default to 'filesize'.
268
- -e, --exec COMMAND execute this code parallel and with ENV['TEST_ENV_NUMBER']
271
+ -e, --exec COMMAND execute COMMAND in parallel and with ENV['TEST_ENV_NUMBER']
272
+ --exec-args COMMAND execute COMMAND in parallel with test files as arguments, for example:
273
+ $ parallel_tests --exec-args echo
274
+ > echo spec/a_spec.rb spec/b_spec.rb
269
275
  -o, --test-options 'OPTIONS' execute test commands with those options
270
276
  -t, --type TYPE test(default) / rspec / cucumber / spinach
271
277
  --suffix PATTERN override built in test file pattern (should match suffix):
@@ -285,7 +291,9 @@ Options are:
285
291
  --unknown-runtime SECONDS Use given number as unknown runtime (otherwise use average time)
286
292
  --first-is-1 Use "1" as TEST_ENV_NUMBER to not reuse the default test environment
287
293
  --fail-fast Stop all groups when one group fails (best used with --test-options '--fail-fast' if supported
288
- --test-file-limit LIMIT Limit to this number of files per test run by batching (for windows set to ~100 to stay below 8192 max command limit, might have bugs from reusing test-env-number and summarizing partial results)
294
+ --test-file-limit LIMIT Limit to this number of files per test run by batching
295
+ (for windows set to ~100 to stay below 8192 max command limit, might have bugs from reusing test-env-number
296
+ and summarizing partial results)
289
297
  --verbose Print debug output
290
298
  --verbose-command Combines options --verbose-process-command and --verbose-rerun-command
291
299
  --verbose-process-command Print the command that will be executed by each process before it begins
@@ -293,21 +301,31 @@ Options are:
293
301
  --quiet Print only tests output
294
302
  -v, --version Show Version
295
303
  -h, --help Show this.
304
+ <!-- rake readme -->
305
+
306
+ You can run any command in parallel with `-e` / `--exec`
296
307
 
297
- You can run any kind of code in parallel with -e / --exec
308
+ ```bash
309
+ parallel_test -n 3 -e 'ruby -e "puts %[hello from process #{ENV[:TEST_ENV_NUMBER.to_s].inspect}]"'
310
+ hello from process "2"
311
+ hello from process ""
312
+ hello from process "3"
313
+ ```
298
314
 
299
- parallel_test -n 5 -e 'ruby -e "puts %[hello from process #{ENV[:TEST_ENV_NUMBER.to_s].inspect}]"'
300
- hello from process "2"
301
- hello from process ""
302
- hello from process "3"
303
- hello from process "5"
304
- hello from process "4"
315
+ and pass arguments to a command with `--exec-args`
305
316
 
306
- <table>
307
- <tr><td></td><td>1 Process</td><td>2 Processes</td><td>4 Processes</td></tr>
308
- <tr><td>RSpec spec-suite</td><td>18s</td><td>14s</td><td>10s</td></tr>
309
- <tr><td>Rails-ActionPack</td><td>88s</td><td>53s</td><td>44s</td></tr>
310
- </table>
317
+ ```bash
318
+ parallel_test -n 3 --exec-args echo
319
+ spec/a_spec.rb spec/b_spec.rb
320
+ spec/c_spec.rb spec/d_spec.rb
321
+ spec/e_spec.rb
322
+ ```
323
+
324
+ and run multiple commands by using `sh` and `--exec-args`
325
+
326
+ ```bash
327
+ parallel_test -n 3 --exec-args "sh -c \"echo 'hello world' && rspec \$@\" --"
328
+ ```
311
329
 
312
330
  TIPS
313
331
  ====
@@ -449,6 +467,7 @@ inspired by [pivotal labs](https://blog.pivotal.io/labs/labs/parallelize-your-rs
449
467
  - [Jay Dorsey](https://github.com/jaydorsey)
450
468
  - [hatsu](https://github.com/hatsu38)
451
469
  - [Mark Huk](https://github.com/vimutter)
470
+ - [Johannes Vetter](https://github.com/johvet)
452
471
 
453
472
  [Michael Grosser](http://grosser.it)<br/>
454
473
  michael@grosser.it<br/>
@@ -191,8 +191,9 @@ module ParallelTests
191
191
  end
192
192
 
193
193
  def parse_options!(argv)
194
- newline_padding = " " * 37
194
+ newline_padding = 37 # poor man's way of getting a decent table like layout for -h output on 120 char width terminal
195
195
  options = {}
196
+
196
197
  OptionParser.new do |opts|
197
198
  opts.banner = <<~BANNER
198
199
  Run all tests in parallel, giving each process ENV['TEST_ENV_NUMBER'] ('', '2', '3', ...)
@@ -205,12 +206,14 @@ module ParallelTests
205
206
 
206
207
  Options are:
207
208
  BANNER
209
+
208
210
  opts.on("-n PROCESSES", Integer, "How many processes to use, default: available CPUs") { |n| options[:count] = n }
209
211
  opts.on("-p", "--pattern PATTERN", "run tests matching this regex pattern") { |pattern| options[:pattern] = /#{pattern}/ }
210
212
  opts.on("--exclude-pattern", "--exclude-pattern PATTERN", "exclude tests matching this regex pattern") { |pattern| options[:exclude_pattern] = /#{pattern}/ }
213
+
211
214
  opts.on(
212
215
  "--group-by TYPE",
213
- <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
216
+ heredoc(<<~TEXT, newline_padding)
214
217
  group tests by:
215
218
  found - order of finding files
216
219
  steps - number of cucumber/spinach steps
@@ -220,6 +223,7 @@ module ParallelTests
220
223
  default - runtime when runtime log is filled otherwise filesize
221
224
  TEXT
222
225
  ) { |type| options[:group_by] = type.to_sym }
226
+
223
227
  opts.on("-m COUNT", "--multiply-processes COUNT", Float, "use given number as a multiplier of processes to run") do |m|
224
228
  options[:multiply_processes] = m
225
229
  end
@@ -251,10 +255,11 @@ module ParallelTests
251
255
 
252
256
  opts.on(
253
257
  "--specify-groups SPECS",
254
- <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
258
+ heredoc(<<~TEXT, newline_padding)
255
259
  Use 'specify-groups' if you want to specify multiple specs running in multiple
256
260
  processes in a specific formation. Commas indicate specs in the same process,
257
- pipes indicate specs in a new process. Cannot use with --single, --isolate, or
261
+ pipes indicate specs in a new process. If SPECS is a '-' the value for this
262
+ option is read from STDIN instead. Cannot use with --single, --isolate, or
258
263
  --isolate-n. Ex.
259
264
  $ parallel_tests -n 3 . --specify-groups '1_spec.rb,2_spec.rb|3_spec.rb'
260
265
  Process 1 will contain 1_spec.rb and 2_spec.rb
@@ -266,28 +271,40 @@ module ParallelTests
266
271
  opts.on(
267
272
  "--only-group GROUP_INDEX[,GROUP_INDEX]",
268
273
  Array,
269
- <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
274
+ heredoc(<<~TEXT, newline_padding)
270
275
  Only run the given group numbers.
271
276
  Changes `--group-by` default to 'filesize'.
272
277
  TEXT
273
278
  ) { |groups| options[:only_group] = groups.map(&:to_i) }
274
279
 
275
- opts.on("-e", "--exec COMMAND", "execute this code parallel and with ENV['TEST_ENV_NUMBER']") { |arg| options[:execute] = Shellwords.shellsplit(arg) }
280
+ opts.on("-e", "--exec COMMAND", "execute COMMAND in parallel and with ENV['TEST_ENV_NUMBER']") { |arg| options[:execute] = Shellwords.shellsplit(arg) }
281
+ opts.on(
282
+ "--exec-args COMMAND",
283
+ heredoc(<<~TEXT, newline_padding)
284
+ execute COMMAND in parallel with test files as arguments, for example:
285
+ $ parallel_tests --exec-args echo
286
+ > echo spec/a_spec.rb spec/b_spec.rb
287
+ TEXT
288
+ ) { |arg| options[:execute_args] = Shellwords.shellsplit(arg) }
289
+
276
290
  opts.on("-o", "--test-options 'OPTIONS'", "execute test commands with those options") { |arg| options[:test_options] = Shellwords.shellsplit(arg) }
291
+
277
292
  opts.on("-t", "--type TYPE", "test(default) / rspec / cucumber / spinach") do |type|
278
293
  @runner = load_runner(type)
279
294
  rescue NameError, LoadError => e
280
295
  puts "Runner for `#{type}` type has not been found! (#{e})"
281
296
  abort
282
297
  end
298
+
283
299
  opts.on(
284
300
  "--suffix PATTERN",
285
- <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
301
+ heredoc(<<~TEXT, newline_padding)
286
302
  override built in test file pattern (should match suffix):
287
303
  '_spec.rb$' - matches rspec files
288
304
  '_(test|spec).rb$' - matches test or spec files
289
305
  TEXT
290
306
  ) { |pattern| options[:suffix] = /#{pattern}/ }
307
+
291
308
  opts.on("--serialize-stdout", "Serialize stdout output, nothing will be written until everything is done") { options[:serialize_stdout] = true }
292
309
  opts.on("--prefix-output-with-test-env-number", "Prefixes test env number to the output when not using --serialize-stdout") { options[:prefix_output_with_test_env_number] = true }
293
310
  opts.on("--combine-stderr", "Combine stderr into stdout, useful in conjunction with --serialize-stdout") { options[:combine_stderr] = true }
@@ -301,7 +318,17 @@ module ParallelTests
301
318
  opts.on("--unknown-runtime SECONDS", Float, "Use given number as unknown runtime (otherwise use average time)") { |time| options[:unknown_runtime] = time }
302
319
  opts.on("--first-is-1", "Use \"1\" as TEST_ENV_NUMBER to not reuse the default test environment") { options[:first_is_1] = true }
303
320
  opts.on("--fail-fast", "Stop all groups when one group fails (best used with --test-options '--fail-fast' if supported") { options[:fail_fast] = true }
304
- opts.on("--test-file-limit LIMIT", Integer, "Limit to this number of files per test run by batching (for windows set to ~100 to stay below 8192 max command limit, might have bugs from reusing test-env-number and summarizing partial results)") { |limit| options[:test_file_limit] = limit }
321
+
322
+ opts.on(
323
+ "--test-file-limit LIMIT",
324
+ Integer,
325
+ heredoc(<<~TEXT, newline_padding)
326
+ Limit to this number of files per test run by batching
327
+ (for windows set to ~100 to stay below 8192 max command limit, might have bugs from reusing test-env-number
328
+ and summarizing partial results)
329
+ TEXT
330
+ ) { |limit| options[:test_file_limit] = limit }
331
+
305
332
  opts.on("--verbose", "Print debug output") { options[:verbose] = true }
306
333
  opts.on("--verbose-command", "Combines options --verbose-process-command and --verbose-rerun-command") { options.merge! verbose_process_command: true, verbose_rerun_command: true }
307
334
  opts.on("--verbose-process-command", "Print the command that will be executed by each process before it begins") { options[:verbose_process_command] = true }
@@ -451,5 +478,9 @@ module ParallelTests
451
478
  yield
452
479
  end
453
480
  end
481
+
482
+ def heredoc(text, newline_padding)
483
+ text.rstrip.gsub("\n", "\n#{' ' * newline_padding}")
484
+ end
454
485
  end
455
486
  end
@@ -18,11 +18,7 @@ module ParallelTests
18
18
  options[:env] ||= {}
19
19
  options[:env] = options[:env].merge({ 'AUTOTEST' => '1' }) if $stdout.tty?
20
20
 
21
- cmd = executable
22
- cmd += runtime_logging if File.directory?(File.dirname(runtime_log))
23
- cmd += combined_scenarios
24
- cmd += cucumber_opts(options[:test_options])
25
- execute_command(cmd, process_number, num_processes, options)
21
+ execute_command(build_command(combined_scenarios, options), process_number, num_processes, options)
26
22
  end
27
23
 
28
24
  def test_file_name
@@ -41,6 +37,15 @@ module ParallelTests
41
37
  line =~ /^\d+ (steps?|scenarios?)/
42
38
  end
43
39
 
40
+ def build_test_command(file_list, options)
41
+ [
42
+ *executable,
43
+ *(runtime_logging if File.directory?(File.dirname(runtime_log))),
44
+ *file_list,
45
+ *cucumber_opts(options[:test_options])
46
+ ]
47
+ end
48
+
44
49
  # cucumber has 2 result lines per test run, that cannot be added
45
50
  # 1 scenario (1 failed)
46
51
  # 1 step (1 failed)
@@ -48,8 +48,15 @@ module ParallelTests
48
48
 
49
49
  private
50
50
 
51
+ def specified_groups(options)
52
+ groups = options[:specify_groups]
53
+ return groups if groups != '-'
54
+
55
+ $stdin.read.chomp
56
+ end
57
+
51
58
  def specify_groups(items, num_groups, options, groups)
52
- specify_test_process_groups = options[:specify_groups].split('|')
59
+ specify_test_process_groups = specified_groups(options).split('|')
53
60
  if specify_test_process_groups.count > num_groups
54
61
  raise 'Number of processes separated by pipe must be less than or equal to the total number of processes'
55
62
  end
@@ -6,8 +6,7 @@ module ParallelTests
6
6
  class Runner < ParallelTests::Test::Runner
7
7
  class << self
8
8
  def run_tests(test_files, process_number, num_processes, options)
9
- cmd = [*executable, *options[:test_options], *color, *spec_opts, *test_files]
10
- execute_command(cmd, process_number, num_processes, options)
9
+ execute_command(build_command(test_files, options), process_number, num_processes, options)
11
10
  end
12
11
 
13
12
  def determine_executable
@@ -42,6 +41,10 @@ module ParallelTests
42
41
  line =~ /\d+ examples?, \d+ failures?/
43
42
  end
44
43
 
44
+ def build_test_command(file_list, options)
45
+ [*executable, *options[:test_options], *color, *spec_opts, *file_list]
46
+ end
47
+
45
48
  # remove old seed and add new seed
46
49
  # --seed 1234
47
50
  # --order rand
@@ -28,15 +28,7 @@ module ParallelTests
28
28
 
29
29
  def run_tests(test_files, process_number, num_processes, options)
30
30
  require_list = test_files.map { |file| file.gsub(" ", "\\ ") }.join(" ")
31
- cmd = [
32
- *executable,
33
- '-Itest',
34
- '-e',
35
- "%w[#{require_list}].each { |f| require %{./\#{f}} }",
36
- '--',
37
- *options[:test_options]
38
- ]
39
- execute_command(cmd, process_number, num_processes, options)
31
+ execute_command(build_command(require_list, options), process_number, num_processes, options)
40
32
  end
41
33
 
42
34
  # ignores other commands runner noise
@@ -168,6 +160,26 @@ module ParallelTests
168
160
  ["ruby"]
169
161
  end
170
162
 
163
+ def build_command(file_list, options)
164
+ if options[:execute_args]
165
+ options[:execute_args] + file_list
166
+ else
167
+ build_test_command(file_list, options)
168
+ end
169
+ end
170
+
171
+ # load all test files, to be overwritten by other runners
172
+ def build_test_command(file_list, options)
173
+ [
174
+ *executable,
175
+ '-Itest', # adding ./test directory to the load path for compatibility to common setups
176
+ '-e',
177
+ "%w[#{file_list}].each { |f| require %{./\#{f}} }", # using %w to keep things readable
178
+ '--',
179
+ *options[:test_options]
180
+ ]
181
+ end
182
+
171
183
  def sum_up_results(results)
172
184
  results = results.join(' ').gsub(/s\b/, '') # combine and singularize results
173
185
  counts = results.scan(/(\d+) (\w+)/)
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ParallelTests
3
- VERSION = '5.1.0'
3
+ VERSION = '5.3.0'
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parallel_tests
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.0
4
+ version: 5.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-09 00:00:00.000000000 Z
11
+ date: 2025-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parallel
@@ -69,9 +69,9 @@ licenses:
69
69
  - MIT
70
70
  metadata:
71
71
  bug_tracker_uri: https://github.com/grosser/parallel_tests/issues
72
- changelog_uri: https://github.com/grosser/parallel_tests/blob/v5.1.0/CHANGELOG.md
73
- documentation_uri: https://github.com/grosser/parallel_tests/blob/v5.1.0/Readme.md
74
- source_code_uri: https://github.com/grosser/parallel_tests/tree/v5.1.0
72
+ changelog_uri: https://github.com/grosser/parallel_tests/blob/v5.3.0/CHANGELOG.md
73
+ documentation_uri: https://github.com/grosser/parallel_tests/blob/v5.3.0/Readme.md
74
+ source_code_uri: https://github.com/grosser/parallel_tests/tree/v5.3.0
75
75
  wiki_uri: https://github.com/grosser/parallel_tests/wiki
76
76
  rubygems_mfa_required: 'true'
77
77
  post_install_message: