Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

wpmedia-phpunit binary breaks @runInSeparateProcess tests

Abierto
#51 3 comentarios 0 reacciones 1 asignado Ver en GitHub

@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

bug Made by AI

🤖 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 disabled data sets
    • Via composer test-unit (runs wpmedia-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

PHPUnit instrumentation evidence:

  • Instrumenting vendor/phpunit/phpunit/src/Util/PHP/Template/TestCaseMethod.tpl with 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 configured bootstrap require.

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:

  1. wpmedia-phpunit and src/BootstrapManager.php are added to get_included_files() when loaded into the parent process.
  2. For @runInSeparateProcess tests, PHPUnit serializes the parent's included-files list into each child and re-requires them (PHPUnit\Util\GlobalState::getIncludedFilesAsString()).
  3. The child re-requires wpmedia-phpunit.
  4. Because that script begins with a #!/usr/bin/env php shebang and, when included, self-executes (it calls BootstrapManager::setupConstants() and BootstrapManager::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.
  5. That corrupts the serialized child result the parent reads back → Test was run in child process and ended unexpectedly.
  6. 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

  • @runInSeparateProcess is common in WordPress plugin tests (e.g. tests that define() constants such as WP_DEBUG / WP_DEBUG_LOG). Affected consumers cannot use the README-recommended wpmedia-phpunit binary and must fall back to direct phpunit.
  • Dogfooding/README inconsistency worth noting: the README recommends "test-unit": "wpmedia-phpunit unit", but this library's own composer.json scripts invoke vendor/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

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de wp-media/phpunit

Todos los issues de wp-media/phpunit

Issues similares

Más issues de PHP

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.