Skip to content

Fix parallel Testbench bootstrap and test profiling - #513

Merged
binaryfire merged 3 commits into
0.4from
fix/testbench-parallel-profiling
Aug 15, 2026
Merged

Fix parallel Testbench bootstrap and test profiling#513
binaryfire merged 3 commits into
0.4from
fix/testbench-parallel-profiling

Conversation

@binaryfire

Copy link
Copy Markdown
Collaborator

This PR fixes two problems in the parallel test tooling and makes the profiler reusable by packages that run ParaTest directly.

Testbench parallel bootstrap

Parallel package workers created their application without Testbench's configured extra attributes. Settings such as dont-discover, configured providers, and configured bootstrappers could therefore behave differently from a normal Testbench application.

The default parallel application resolver now:

  • bootstraps Testbench configuration when the runtime has not already been initialized;
  • passes configured extra attributes into application creation;
  • keeps the parallel testing provider registered when package discovery is disabled;
  • preserves an existing runtime clone instead of bootstrapping over it; and
  • leaves custom application resolvers untouched.

The regression coverage exercises the real default resolver in subprocesses. It covers configured providers and bootstrappers, discovery exclusions, process callbacks, runtime reuse, and custom resolvers.

Accurate parallel profiling

The previous slow-test extension ran inside PHPUnit workers. ParaTest did not reliably surface those worker warnings in the parent process, so a run could finish without showing the slow tests it found.

composer test:profile now runs ParaTest with an owned temporary JUnit report, then prints every test that meets the displayed threshold, sorted from slowest to fastest. The JUnit duration includes setup, execution, and teardown. The package-level --profile timer now starts at PHPUnit preparation as well, so both profiling paths measure the same lifecycle.

The profiler streams ParaTest output while the suite runs and preserves ParaTest's exit status for test and runner failures. A failed runner remains the primary failure even if its report is absent or incomplete. A successful run that fails to produce a readable report is rejected, and the temporary report is removed on every exit path.

Shared package binary

The profiler now ships as the hypervel-test-profile Composer binary in hypervel/testing. Components uses the same executable as installed package consumers, avoiding separate implementations that can drift.

The binary:

  • accepts normal ParaTest options, filters, files, and directories;
  • reserves --log-junit for its owned report;
  • resolves test paths from the project root so the project PHPUnit configuration is used consistently;
  • disables the Composer process timeout for complete suites;
  • reports how to install brianium/paratest when the optional parallel-test dependency is missing; and
  • preserves terminal behavior when TTY support is available.

The obsolete slow-test extension and subscribers are removed from the default PHPUnit configuration. Documentation now explains the direct package command, its root-relative paths, and its reserved report option. The extensionless executable remains covered by formatting and static analysis, while downloaded top-level binaries remain excluded.

Validation

The changes were checked with the full Components verification workflow, the Testbench package-mode and dogfood suites, focused profiler and subprocess coverage, static analysis, and formatting. The shared executable was also run through generated Composer proxies in package repositories with forwarded filters, paths, and process counts.

Build the default parallel test application with Testbench's configured extra attributes so package discovery exclusions and other bootstrap metadata match the normal Testbench lifecycle. Keep the bootstrap confined to the default resolver and preserve an already initialized runtime.

Ensure the parallel testing provider is present exactly once without disturbing configured providers. Add subprocess coverage for custom resolvers, bootstrapper configuration, provider discovery exclusions, callback ordering and counts, and runtime reuse across the worker lifecycle.
Replace the PHPUnit slow-test extension, whose warnings are lost under ParaTest, with a raw ParaTest profiler that owns a temporary JUnit report and lists every test above a documented lifecycle-duration threshold. Preserve the child runner's output and exit status, distinguish runner failures from profiler failures, clean reports on every path, and match terminal behavior.

Measure package --profile durations from PHPUnit preparation so setup and teardown costs are included consistently. Add regressions for ordering, thresholds, setup timing, successful and failing suites, missing reports, report cleanup, and real multi-worker Testbench execution.

Include the executable profiler in formatting and static analysis, remove the obsolete extension and subscribers, wire composer test:profile to the new script, and remove stale plan references to the deleted mechanism.
Move the ParaTest profiler into hypervel/testing as a Composer binary so package repositories can use one maintained implementation. Keep the Components script timeout disabled and preserve project-root configuration resolution when the binary is invoked through Composer's generated proxy.

Preserve failing runner exit codes when reports are absent or malformed, reject unusable reports from successful runs, and provide an actionable error when the optional ParaTest dependency is missing. Keep the extensionless executable covered by formatting and static analysis while excluding only the repository's downloaded top-level binaries.

Document the reserved JUnit option and root-relative paths, and cover the complete report-status matrix, missing dependency behavior, cleanup, forwarded arguments, and full test lifecycle timing.
@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ac69afdc-8a6b-4ca9-9e4a-a429b3c38eaf

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@binaryfire
binaryfire merged commit 6c55138 into 0.4 Aug 15, 2026
37 of 38 checks passed
@binaryfire
binaryfire deleted the fix/testbench-parallel-profiling branch August 15, 2026 07:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant