【问题标题】:Why phpunit is not getting the correct APP_ENV as specified in phpunit.xml?为什么 phpunit 没有得到 phpunit.xml 中指定的正确 APP_ENV?
【发布时间】:2018-02-05 22:07:14
【问题描述】:

我正在使用 Laravel,这是我的 ./phpunit.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="bootstrap/autoload.php"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false">
    <testsuites>
        <testsuite name="FeatureTests">
            <directory suffix="Test.php">./tests/Feature</directory>
        </testsuite>

        <testsuite name="UnitTests">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">./app</directory>
        </whitelist>
    </filter>
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="QUEUE_DRIVER" value="sync"/>
        <env name="DB_CONNECTION" value="sqlite_testing" />
    </php>
</phpunit>

我正在使用以下命令触发我的一个测试套件:

./vendor/phpunit/phpunit/phpunit --testsuite UnitTests

在我的测试方法中,我有:

public function testAllMandatoryData()
{
   dump(env('APP_ENV'));
   ....
}

它显示“本地”,我期待 phpunit.xml 中指定的“测试”

         <env name="APP_ENV" value="testing"/>

编辑:附加细节 我在 Docker 容器中运行了这个 laravel 应用程序

在 docker-compose.yml 我设置了一些环境变量,例如:

environment:
  - APP_ENV=local
  - DB_HOST=192.168.0.22
  - DB_PORT=33306
  - DB_DATABASE=mydatabase
  - DB_USERNAME=homestead
  - DB_PASSWORD=homestead

我注意到 phpunit.xml 中的指令如下:

    <env name="APP_ENV" value="testing"/>

当名称已经在 docker-compose 中时无效。

相反,如果我添加一些未在 docker-compose.yml 中定义的内容,将在 phpunit 运行时正确设置,例如:

    <env name="DB_CONNECTION" value="sqlite_test"/>

结束编辑

我错过了什么?

谢谢

【问题讨论】:

标签: xml laravel docker phpunit


【解决方案1】:

使用

<env name="APP_ENV" value="testing" force="true"/>
<env name="CACHE_DRIVER" value="array" force="true"/>
<env name="SESSION_DRIVER" value="array" force="true"/>
<env name="QUEUE_DRIVER" value="sync" force="true"/>
<env name="DB_CONNECTION" value="sqlite_testing" force="true"/>

如果没有 force 参数,它将无法工作。看到这个问题: https://github.com/sebastianbergmann/phpunit/issues/2353 和合并后的 PR:https://github.com/sebastianbergmann/phpunit/pull/2723

【讨论】:

  • @koalaok 这应该是选择的答案,这样您仍然可以在 docker-compose 文件中使用这些环境参数
【解决方案2】:

我尝试用我找到的最佳选择来回答自己。

如果您在 docker-compose.yml 文件中设置 ENV 变量,您将无法使用 phpunit.xml 指令覆盖它们,例如:

  <env name="APP_ENV" value="testing"/>

那么您应该选择从 docker-compose.yml 中删除(如本例中的)APP_ENV 变量集

并依赖 .env Laravel 文件

APP_ENV=local

通过此设置,phpunit 将能够将 APP_ENV 覆盖为“测试”

我仍然不是 100% 确定需要这种安排,所有 docker 代理版本。我拥有的另一个 Docker 版本的主机表现不同。

【讨论】:

    【解决方案3】:

    请改用config('app.env')env() 值可能会被缓存,在这种情况下 php artisan config:clear 可能会有所帮助,尽管我在从命令行环境访问 env 值时也遇到了问题。

    更多信息herehere

    【讨论】:

    • 谢谢,但您的任何建议都不适合我。
    • 为什么不呢?如果您不向我们提供详细信息,任何人都无法提供帮助。
    • 添加了我目前发现的一些细节。
    • 使用 php artisan config:clear 为我工作,并允许我的测试针对测试数据库运行。它们应该是一种更好的测试方法,以使其始终连接到测试数据库,并且不会在不清除此配置的情况下覆盖主数据库。当我重新启动 docker setup 时,配置又回来了,所以每次我重新启动容器时都需要这样做。
    • 仅供参考:它将是 config('app.env');。 config 函数使用点表示法。 config('APP_ENV') 将始终为空。
    【解决方案4】:

    我遇到了同样的问题,.env 变量似乎覆盖了我的 phpunit.xml 中的变量,以下是一些可行的解决方案:

    1. 指定运行phpunit时使用哪个phpunit.xml文件,它可能使用了错误的文件。 vendor/bin/phpunit --configuration [path to your phpunit.xml]
    2. 清理配置缓存。 php artisan config:cache
    3. 如果您在 Docker 容器中,上述操作可能不适合您。我所做的是手动删除 bootstrap/cache 文件。

    希望对你有帮助!

    【讨论】:

    • 对于我的情况,我使用的是 laradock,所以我删除了我的本地引导程序/缓存运行测试并且它工作了
    【解决方案5】:

    我在使用 Docker 和 docker-compose 时遇到了同样的问题,事实上我的 docker-compose.yml 正在加载 Laravel 的 .env 文件。 所以,我通过创建一个 .env.docker 文件并设置(在 docker-compose.yml 中)来解决它:

      env_file:
        - .env.docker
    

    它就像一个魅力,PHPUnit 能够选择我的 .env.testing 文件 insted .env

    【讨论】:

      【解决方案6】:

      尝试通过运行命令php artisan config:clear 清除配置缓存。这是因为您可能在运行测试之前运行了命令php artisan config:cache,并且您的APP_ENV 被缓存为local

      【讨论】:

        【解决方案7】:

        我不得不求助于这个小技巧来让环境“测试”,我不得不把它放在TestCase.php

        protected function setUp(): void
        {
           parent::setUp();
           $this->app->detectEnvironment( function () {
              return 'testing';
           });
        }
        

        【讨论】:

          【解决方案8】:

          对于 docker 用户,我在 composer.json 文件中添加了一个新的 test 脚本:

          "test": [
                  "DB_CONNECTION=sqlite && DB_DATABASE=:memory: && APP_ENV=testing && phpunit --colors=always --no-coverage"
                  ],
          

          这个脚本只是覆盖了docker-compose.json中定义的环境变量

          【讨论】:

            猜你喜欢
            • 2014-05-22
            • 2013-08-19
            • 2017-10-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多