如何使用phpunit为某些测试套件注入env变量


How to inject an env variable just for certain testsuite using phpunit?

phpunit.xml中可以定义环境变量:

<php>
    <env name="ENVIRONMENT" value="test"/>
    <env name="FOO" value="BAR"/>
</php>

现在,我想拥有多个测试套件,而不仅仅是一个。我喜欢为每个FOO设置不同的值,所以我想我可以这样做:

<testsuites>
    <testsuite name="First">
        <directory>unit</directory>
        <directory>Functional</directory>
        <php>
            <env name="FOO" value="NARF"/>
        </php>
    </testsuite>
    <testsuite name="Second">
        <directory>unit</directory>
        <directory>Functional</directory>
        <php>
            <env name="FOO" value="NARF"/>
        </php>
    </testsuite>
</testsuites>

似乎不可能将 php 嵌套在测试套件块中。所以我目前被困在为某个测试套件注入特定变量的困境中。

我看到的唯一另一个明确的选项是为每种情况定义多个phpunit.xml文件,但这会导致我喜欢避免的大量代码重复。

有没有另一种方法可以将 env 变量注入 phpunit 测试套件?

您可以使用软件包 phpunit-globals,它允许您修改特定测试类或方法的 $_ENV(和 $_SERVER)变量。

使用以下命令将其安装为开发依赖项:

composer require --dev zalas/phpunit-globals

之后,您可以执行以下操作:

/**
 * @env FOO=bar
 */
class ExampleTest extends TestCase
{
    /**
     * @env APP_ENV=foo
     */
    public function test_global_variables()
    {
        $this->assertSame('bar', $_ENV['FOO']);
        $this->assertSame('foo', $_ENV['APP_ENV']);
    }
}

phpunit.xml 中定义的环境变量是默认值。您也可以从 shell 传递它们:

FOO=bar phpunit

这对您没有多大帮助,因为您需要单独运行测试套件,将 env 变量传递给每次运行。

我认为一个不错的选择是为每个测试套件(FOO_FIRST、FOO_SECOND等)以不同的方式调用这些变量。

这是一个老问题,但是使用当前版本的 PHPUnit (8+),您可以在测试中毫无问题地设置环境变量。因此,与其拥有多个具有相同测试和不同环境的测试套件,不如拥有一个测试套件,其中包含针对不同环境的相同测试和数据提供程序 - 例如这样。

class ExampleTest extends TestCase
    public function envValueProvider(): array
    {
        return [
            [
                'foo',
            ],
            [
                'bar',
            ],
        ];
    }
    /**
     * @dataProvider envValueProvider
     */
    public function testSomeCode(string $value): void
    {
        putenv('FOO=' . $value);
        somecode();
        self::assertSomething();
    }