wpmedia-phpunit binary breaks @runInSeparateProcess tests
@remyperona ya está trabajando en esto.
Desde el 18/8/2026.
- #54 de @remyperona — cerrado sin fusionar
Evaluación
Este issue todavía no se ha evaluado.
Descripción
🤖 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.
- Lenguaje dominante
- PHP
- Estrellas
- 4
- Forks
- 2
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de wp-media/phpunit
-
HttpRequestTrait fatals on WordPress 7.2: $blocked_http_requests clashes with WP_UnitTestCase_BaseAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
-
enhancement Made by AI
Dificultad 3/5 1-2 días Aptitud para principiantes 68/100
-
enhancement Made by AI
Dificultad 3/5 1-2 días Aptitud para principiantes 74/100
-
Improve the library to include classes that could be common to all plugins.Quizá libre de nuevo @hellofromahmed la tomó hace 766 días y no hay ningún pull request abierto. Abierto
-
AdminOnly causes a Notice: Undefined offset in wordpress-develop vars.Quizá libre de nuevo @hellofromtonya la tomó hace 2437 días y no hay ningún pull request abierto. Abierto
Todos los issues de wp-media/phpunit
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
omegaup/omegaup#10353 · 1 comentario ·
Los mantenedores suelen responder en 5 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
-
Featured image not passed to checks in the Tasks column or publish blocksPosiblemente ocupada @roborourke la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
humanmade/publication-checklist#100 ·
Los mantenedores suelen responder en 1 día
-
bug customer-reported
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
MagnaCapax/PMSS#1072 ·
Los mantenedores suelen responder en 5 días