wpmedia-phpunit binary breaks @runInSeparateProcess tests
Đánh giá
Issue này chưa được đánh giá.
Mô tả
🤖 AI-generated — created with Claude Code, reviewed by @Tabrisrp. Discovered while migrating wp-media/mcp-oauth to wp-media/phpunit v3.2.
Summary
The wpmedia-phpunit binary is incompatible with PHPUnit's @runInSeparateProcess isolation: all @runInSeparateProcess tests fail when run through the binary, while identical tests pass under a direct vendor/bin/phpunit invocation with the same arguments.
Steps to reproduce / Evidence
Reproduction in a consumer plugin (wp-media/mcp-oauth):
- A test class with 9
@runInSeparateProcess+@preserveGlobalState disableddata sets- Via
composer test-unit(runswpmedia-phpunit unit): 0/9 pass (Test was run in child process and ended unexpectedly) - Via direct
vendor/bin/phpunit --testsuite unit --colors=always --configuration Tests/Unit/phpunit.xml.dist: 9/9 pass - Same effective arguments; identical test code
- Via
PHPUnit instrumentation evidence:
- Instrumenting
vendor/phpunit/phpunit/src/Util/PHP/Template/TestCaseMethod.tplwith counters showed the isolated child dies inside the{included_files}block: the included-file count grows from 58 → 142 in the passing (direct) run, whereas the binary-run child never survives that block to reach the configuredbootstraprequire.
Root cause
The binary (wpmedia-phpunit at repo root) and src/BootstrapManager.php bootstrap PHPUnit by require-ing vendor/bin/phpunit into the currently running PHP process (see BootstrapManager::runTestSuite(), the require_once "{$root}/bin/phpunit" line).
The failure chain:
wpmedia-phpunitandsrc/BootstrapManager.phpare added toget_included_files()when loaded into the parent process.- For
@runInSeparateProcesstests, PHPUnit serializes the parent's included-files list into each child and re-requires them (PHPUnit\Util\GlobalState::getIncludedFilesAsString()). - The child re-
requireswpmedia-phpunit. - Because that script begins with a
#!/usr/bin/env phpshebang and, when included, self-executes (it callsBootstrapManager::setupConstants()andBootstrapManager::runTestSuite()at the top level), re-including it in the child re-runs the whole bootstrap manager and emits the shebang line to the child's STDOUT. - That corrupts the serialized child result the parent reads back →
Test was run in child process and ended unexpectedly. - Every isolated data set fails.
A direct vendor/bin/phpunit run passes because its included files are all inert library files — harmless to re-require.
Proposed fix
Two options; the second is recommended as the robust, long-term solution.
Option 1 — Minimal / targeted
In BootstrapManager, before running the suite, register the binary entrypoints into PHPUnit's isolation exclusion list so they are not re-required in isolated children:
$GLOBALS['__PHPUNIT_ISOLATION_EXCLUDE_LIST'][] = realpath( $wpmedia_phpunit_binary_path );
$GLOBALS['__PHPUNIT_ISOLATION_EXCLUDE_LIST'][] = realpath( __DIR__ . '/BootstrapManager.php' );
PHPUnit already honors this list in vendor/phpunit/phpunit/src/Util/GlobalState.php (getIncludedFilesAsString() skips listed files). Composer's bin-proxy already populates it for the real phpunit entry; the binary's own entrypoints simply need to be added.
- Pros: minimal change; reuses PHPUnit's existing mechanism.
- Cons: does not address the structural issue of loading PHPUnit into-process.
Option 2 — Structural / robust (recommended)
Run PHPUnit as a genuine subprocess (proc_open/passthru) instead of require-ing it into the runner process, so the binary and BootstrapManager never enter the test process's included-files set at all. This mirrors how native phpunit runs.
- Pros: eliminates the root cause; robust against future PHPUnit versions and other edge cases.
- Cons: larger refactor; requires careful subprocess lifecycle/error handling.
Impact
@runInSeparateProcessis common in WordPress plugin tests (e.g. tests thatdefine()constants such asWP_DEBUG/WP_DEBUG_LOG). Affected consumers cannot use the README-recommendedwpmedia-phpunitbinary and must fall back to direct phpunit.- Dogfooding/README inconsistency worth noting: the README recommends
"test-unit": "wpmedia-phpunit unit", but this library's owncomposer.jsonscripts invokevendor/bin/phpunit --configuration ...directly — i.e. they sidestep the binary and therefore this bug.
Additional notes
Minor related papercut: BootstrapManager::getConfigArgv() hardcodes --colors=always, which emits raw ANSI escape codes when output is piped to a non-TTY (CI logs / file capture). Consider --colors=auto or making it overridable.
- Ngôn ngữ chính
- PHP
- Star
- 4
- Fork
- 2
- Merge trung bình
- 3 ngày 7 giờ
- Pull request đã merge (30 ngày)
- 5
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của wp-media/phpunit
-
enhancement Made by AI
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 68/100
-
enhancement Made by AI
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 74/100
-
Improve the library to include classes that could be common to all plugins.Có thể làm lại được @hellofromahmed đã nhận 782 ngày trước và không có pull request nào đang mở. Đang mở
-
AdminOnly causes a Notice: Undefined offset in wordpress-develop vars.Có thể làm lại được @hellofromtonya đã nhận 2453 ngày trước và không có pull request nào đang mở. Đang mở
Tất cả issue của wp-media/phpunit
Issue tương tự
-
jira-created
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 2 ngày
-
enhancement
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 78/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
grokability/snipe-it#19996 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Add a dark themeĐang mởgood first issue laravel-appointment-reminders
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100