如何在Laravel Dusk中覆盖环境变量 [英] How to override env variables in Laravel Dusk

查看:123
本文介绍了如何在Laravel Dusk中覆盖环境变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Unfortunately config(['key' => 'newValue']) doesn't work in a Dusk setup (for overriding a config value), presumably because it would change the config of the system running the test rather than the experience of the headless browser that gets opened to execute the flow.

有时我看不到有必要暂时为某个Dusk测试更改环境值.

And sometimes I can see no way around needing to temporarily change an env value for a certain Dusk test.

例如通常在通常是黄昏连接"时临时设置QUEUE_DRIVER=sync,但是在一个特定测试中,我需要检查数据库中'jobs'表中的值.

E.g. temporarily set QUEUE_DRIVER=sync when usually it is 'dusk-connection', but in one particular test, I need to check for values in the 'jobs' tables in the DB.

在升级到Laravel> = 5.8(因此是DotEnv的较新版本)之前,我能够在$this->browse(...之前的Dusk测试中使用此函数:

Before upgrading to Laravel >=5.8 (and therefore newer versions of DotEnv), I was able to use this function called within a Dusk test before $this->browse(...:

/**
 * 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版本中,环境变量是不可变的(请参见只读的env帮助器").

But in more recent Laravel versions, environment variables are immutable (see "Read-Only env Helper").

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

How can I achieve my goal, where Dusk uses .env.dusk.local for most tests but then for certain tests may differ slightly?

推荐答案

最后解决此问题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()函数中,我调用:

Then in my setUp() function in my Dusk test class, I call:

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

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

Then in each test function after the closing of $this->browse(function (Browser $browser)... and before assertions, I call:

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理解的一个棘手的部分是,控制台程序运行环境变量(以及配置数组)的过程与无头浏览器使用的那些变量进行模拟测试.真正的用户会体验到.)

The tricky part to understand with Dusk is that the environment variables (and therefore the config arrays) of the console process running the tests differ from those that get used by the headless browser (simulating what a real user would experience).

顺便说一句,我对

By the way, I had been so hopeful about approaches like this one, but they turned out to be complete wastes of time because DuskCommand is already calling overload to make the env variables mutable.

这篇关于如何在Laravel Dusk中覆盖环境变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆