【问题标题】:How to override env variables in Laravel Dusk如何在 Laravel Dusk 中覆盖环境变量
【发布时间】:2020-02-15 10:47:51
【问题描述】:

不幸的是,config(['key' => 'newValue']) 在 Dusk 设置中不起作用(用于覆盖配置值),大概是因为它会改变系统的配置运行测试而不是无头的体验为执行流程而打开的浏览器。

有时我看不出需要临时更改某个 Dusk 测试的 env 值。

例如临时设置QUEUE_DRIVER=sync,通常是“黄昏连接”,但在一项特定测试中,我需要检查数据库中“作业”表中的值。

在升级到 Laravel >=5.8(以及更新版本的 DotEnv)之前,我能够使用在 $this->browse(... 之前的 Dusk 测试中调用的这个函数:

/**
 * Overrides any .env variables for Dusk tests. https://laracasts.com/discuss/channels/testing/how-to-change-env-variable-config-in-dusk-test 
 * The changes exist only for that one test because of tearDown.
 * Remember that you need to be using `php artisan dusk` instead of `phpunit`.
 * https://stackoverflow.com/questions/54407784/laravel-dusk-how-to-change-config-values-before-each-test-for-the-browser#comment103224655_54407784
 *
 * @param array $variables
 */
protected function overrideDuskEnv($variables = []) {
    $path = self::DOT_ENV;
    if (file_exists($path)) {
        $contentToPrepend = '';
        foreach ($variables as $key => $value) {// Convert all new parameters to expected format
            $contentToPrepend .= $key . '="' . $value . '"' . PHP_EOL;
        }
        $originalFileContents = $this->envContents;
        $comment = '# ==============================================' . PHP_EOL . '# VARIABLES ABOVE THIS LINE are from "' . __FUNCTION__ . '" function in DuskTestCase ( https://laracasts.com/discuss/channels/testing/how-to-change-env-variable-config-in-dusk-test )' . PHP_EOL;
        file_put_contents($path, $contentToPrepend . $comment . $originalFileContents); //"If they are appended, it doesn't seem to take priority."
    } else {
        throw new \Exception('Could not find env file to override!');
    }
}

我可以这样称呼它:$this->overrideDuskEnv(['QUEUE_DRIVER' => 'sync']);

但在最近的 Laravel 版本中,环境变量是不可变的(请参阅 "Read-Only env Helper")。

我怎样才能实现我的目标,Dusk 在大多数测试中使用.env.dusk.local,但对于某些测试可能会略有不同?

【问题讨论】:

    标签: laravel laravel-dusk laravel-6 phpdotenv


    【解决方案1】:

    在为这个问题苦苦挣扎了 10 多个小时后,我终于有了一个解决方案。

    /**
     * @param array $variables
     */
    protected function overrideDuskEnv($variables = []) {
        $path = self::DOT_ENV;
        if (file_exists($path)) {
            $contentToAppend = '';
            foreach ($variables as $key => $value) {// Convert all new parameters to expected format
                $contentToAppend .= $key . '="' . $value . '"' . PHP_EOL;
            }
            $originalFileContents = $this->envContents;
            $comment = '# ==============================================' . PHP_EOL . '# VARIABLES BELOW THIS LINE are from "' . __FUNCTION__ . '" function in DuskTestCase ( https://laracasts.com/discuss/channels/testing/how-to-change-env-variable-config-in-dusk-test )' . PHP_EOL;
            $this->baseCommand->consoleOutput('Appending to ' . $path . ': ' . $contentToAppend);
            file_put_contents($path, $originalFileContents . $comment . $contentToAppend); //It used to be the case that "If they are appended [rather than prepended], it doesn't seem to take priority", but after the DotEnv upgrade in Laravel 5.8, it seems prepending doesn't work and appending does.
        } else {
            throw new \Exception('Could not find env file to override!');
        }
    }
    

    然后在我的 Dusk 测试类的setUp() 函数中,我调用:

        $this->overrideDuskEnv([
            'SIGNUP_FORM_POST_PATH' => \App\Helpers\Routes::SIGNUP,
            'QUEUE_DRIVER' => \App\Helpers\ConfigConstants::DUSK_CONNECTION
        ]);
    

    然后在$this->browse(function (Browser $browser)... 关闭之后和断言之前的每个测试函数中,我调用:

    config(['queue.default' => \App\Helpers\ConfigConstants::DUSK_CONNECTION]); //this does not affect the headless browser but IS probably necessary here so that assertQueued knows to pull from the queue that the headless browser was using.
    

    使用 Dusk 需要理解的棘手部分是运行测试的控制台进程的环境变量(以及配置数组)不同于那些被无头浏览器使用的环境变量(模拟什么真正的用户会体验到)。

    顺便说一句,我对 this one 这样的方法充满希望,但结果证明它们完全是浪费时间,因为 DuskCommand is already calling overload 使 env 变量可变。

    【讨论】:

      【解决方案2】:

      有关在黄昏测试期间覆盖 config([]) 的记录方法,请参见此处:

      https://gist.github.com/wrabit/e01df16858505c395b7b0d271112a023

      【讨论】:

        【解决方案3】:

        您还可以为所有黄昏测试使用单独的环境。 这里的 laravel 文档中也提到了 https://laravel.com/docs/8.x/dusk#environment-handling

        【讨论】:

          【解决方案4】:

          这有点简单,但如果你输入任何错误的条目,它就会爆裂。

          public function store(Request $request) {
              foreach ($request->all() as $key => $value) {
                  $_ENV[$key] = $value;
              }
              $x = '';
              unset($_ENV['_token']);
              foreach ($_ENV as $key => $value) {
                  $x .= $key . "=" . $value . "\n";
              }
              base_path('.env');
              file_put_contents(base_path('.env'), $x);
              return redirect()->back();
          }
          

          使用

          <form class="grid gap-2" action="{{ route('admin.enviroment.store') }}" method="post">
              <div>
                  <x-label for="GOOGLE_TAG"  :value="__('GOOGLE_TAG')" />
                  <x-input id='GOOGLE_TAG' name="GOOGLE_TAG" :value="__($_ENV['GOOGLE_TAG'])" class="w-full rounded-md dark:bg-gray-700" type="text" required  />
              </div>
              @csrf
              <x-button class="ml-auto dark:bg-blue-900/90">
                  {{ __('Update GOOGLE TAG') }}
              </x-button>
          </form>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-03-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-09-15
            相关资源
            最近更新 更多