Retargeted to 2.0 under ADR-010 (2.0 carries the features; 2.1 carries the deletions).
Problem
Under Rails' default parallelize(workers: N), the HTML report is not written and the [snap_diff] summary line is not printed. Minitest skips after_run hooks in forked children (allow_fork = false, minitest.rb:64; guard next if !Minitest.allow_fork && Process.pid != pid at :79), so the workers holding the results never finalize, and the parent that does finalize recorded nothing.
Measured with a real harness (8 classes × 8 tests, committed baselines, the real gem from namer through reporter), 10/10 runs: report=NO, ledger_pids=5 — four workers hold 16 records each and never finalize.
Pass/fail is correct throughout (failures marshal back over DRb) and every on-disk artifact survives. Only the HTML index and the summary line are lost.
docs/reporters.md now documents a manual workaround (#252), but boilerplate in every consuming app is the wrong shape: nobody pastes it, and the failure is silent. ActiveSupport.test_parallelization_threshold defaults to 50, so a suite silently starts losing its report the day someone adds the 51st test.
The seams already exist
Verified against activesupport 8.1.3.1 — both run inside the worker:
ActiveSupport::Testing::Parallelization.after_fork_hook — parallelization.rb:22, invoked at worker.rb:24
ActiveSupport::Testing::Parallelization.run_cleanup_hook — parallelization.rb:30, invoked at worker.rb:31
Checklist
Out of scope
Separate-process runners (parallel_tests, RSpec, CI sharding), where each process finalizes correctly and the last writer wins. Different problem; the current docs describe it accurately.
Retargeted to 2.0 under ADR-010 (2.0 carries the features; 2.1 carries the deletions).
Problem
Under Rails' default
parallelize(workers: N), the HTML report is not written and the[snap_diff]summary line is not printed. Minitest skipsafter_runhooks in forked children (allow_fork = false,minitest.rb:64; guardnext if !Minitest.allow_fork && Process.pid != pidat:79), so the workers holding the results never finalize, and the parent that does finalize recorded nothing.Measured with a real harness (8 classes × 8 tests, committed baselines, the real gem from namer through reporter), 10/10 runs:
report=NO,ledger_pids=5— four workers hold 16 records each and never finalize.Pass/fail is correct throughout (failures marshal back over DRb) and every on-disk artifact survives. Only the HTML index and the summary line are lost.
docs/reporters.mdnow documents a manual workaround (#252), but boilerplate in every consuming app is the wrong shape: nobody pastes it, and the failure is silent.ActiveSupport.test_parallelization_thresholddefaults to 50, so a suite silently starts losing its report the day someone adds the 51st test.The seams already exist
Verified against activesupport 8.1.3.1 — both run inside the worker:
ActiveSupport::Testing::Parallelization.after_fork_hook—parallelization.rb:22, invoked atworker.rb:24ActiveSupport::Testing::Parallelization.run_cleanup_hook—parallelization.rb:30, invoked atworker.rb:31Checklist
after_fork_hook— give each worker a record sink keyed by pidrun_cleanup_hook— flush that worker's records before it exitsMinitest.after_runmerges the fragments into one report at the documented path, then removes themActiveSupport::Testing::Parallelizationis defined; the gem must keep working without Railsparallelize(with: :threads)(verified correct — same failures and counts as serial, only entry order differs)save_pathas the per-worker lever.config.screenshot_areaderives from it (config.rb:143-148), so a per-workersave_pathpoints every comparison at an empty baseline directory and records everything as new. The per-worker path must be the report output path onlydocs/reporters.md— the manual workaround becomes a fallback, not the answerOut of scope
Separate-process runners (
parallel_tests, RSpec, CI sharding), where each process finalizes correctly and the last writer wins. Different problem; the current docs describe it accurately.