Skip to content

[PHPUnit-Bridge] Installing PHPUnit bridge has side-effect on local even if it's not used #52185

@VincentLanglet

Description

@VincentLanglet

Symfony version(s) affected

all

Description

I personally don't require the Phpunit-bridge and don't use it in my phpunit.xml.
I run my tests with vendor/bin/phpunit and the bootstrap file is

bootstrap="tests/bootstrap.php"

which contains

require dirname(__DIR__).'/vendor/autoload.php';

if (file_exists(dirname(__DIR__).'/config/bootstrap.php')) {
    require dirname(__DIR__).'/config/bootstrap.php';
} else {
    (new Dotenv())->bootEnv(dirname(__DIR__).'/.env');
}

if ($_SERVER['APP_DEBUG']) {
    umask(0);
}

But, a lot of my dependencies have this bridge as dev-dependencies so this lib is in my vendor in development mode.

The issue is that when I run my tests the phpunit-bridge/bootstrap file is executed:
I tried to throw an exception in this bootstrap file to know when it's loaded, it's done this way:

/var/www/wg-app/vendor/symfony/phpunit-bridge/bootstrap.php:16
Stack trace:
#0 /var/www/wg-app/vendor/composer/autoload_real.php(41): require()
#1 /var/www/wg-app/vendor/composer/autoload_real.php(45): {closure}('92c8763cd6170fc...', '/var/www/wg-app...')
#2 /var/www/wg-app/vendor/autoload.php(25): ComposerAutoloaderInit25a424351a9b80b8bf375de5dee47df7::getLoader()
#3 /var/www/wg-app/vendor/phpunit/phpunit/phpunit(97): require('/var/www/wg-app...')
#4 {main}

In this bootstrap file there is the code

setlocale(\LC_ALL, 'C');

which change the local.
Because of this I don't have a test environment which reproduce the same behavior than my local or prod environnement.

How to reproduce

  • Install phpunit,
  • run setlocale(\LC_ALL, 0); in a test
  • Install phpunit-bridge without using it (install doctrine/common for instance)
  • run setlocale(\LC_ALL, 0); in a test
  • the value won't be the same

Possible Solution

I kinda disagree with @nicolas-grekas on symfony/symfony-docs#11087 (comment) => test should be context dependent if your local/prod are. But that's another debate.

At least, phpunit-bridge shouldn't have any side effects on test if it's not used by the developer.

After some tries, I discover that was the goal of

// Detect if we're loaded by an actual run of phpunit
if (!defined('PHPUNIT_COMPOSER_INSTALL') && !class_exists(\PHPUnit\TextUI\Command::class, false)) {
    return;
}

(The early return is executed when command/kernel is booted in developement mode)

But IMHO we should also pass in this early return when phpunit is used without using the bridge.
Not sure the best way to detect this.

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions