Codeception / Codeception/Codeception

Environment variables not loaded into `putenv` via ParamsLoader

Open
#6,776 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
PHP
Stars
4.9k
Forks
1.3k
PR merge metrics
No merged PRs in 30d

Description

#### What are you trying to achieve?

I am writing tests for a Craft 4 project using `codeception/codeception` and `codeception/module-yii2` and found an issue while running functional tests where environment variables are unavailable when an internal request is made.

My project uses `symfony/dotenv` to handle loading of environment variables.

In my Craft config files I use environment variables to alter functionality, eg a `config/site.php`:

```
amOnPage('/account/login');
}
}
```

The value of `$myEnvVar` should always be what I set in the environment variable.

#### What do you get instead?

When I breakpoint my config file and Codeception first starts the `$myEnvVar` is whatever I provided in the `.env` however after the functional test starts and an internal request is made this `$myEnvVar` is now null.

After much debugging I found the issue was a combination of the Codeception Yii2 connector class resetting the `$_SERVER` where the `.env` files were loaded (see: https://github.com/Codeception/module-yii2/blob/master/src/Codeception/Lib/Connector/Yii2.php#L288), Craft's `App::env()` function not using the `$_ENV` array as a fallback (see: https://github.com/craftcms/cms/blob/5.x/src/helpers/App.php#L121) and the ParamsLoader not enabling `usePutenv` (see https://github.com/Codeception/Codeception/blob/5.1/src/Codeception/Lib/ParamsLoader.php#L166).

The workaround was to load the environment variables in my own Codeception bootstrap file and enable `usePutenv` for Dotenv:

```
$symfonyDotEnv = new SymfonyDotenv();
$symfonyDotEnv->usePutenv(true);
$values = $symfonyDotEnv->parse(self::getFileContents($file), $file);
$symfonyDotEnv->populate($values);
```

If I bypassed my own bootstrap file and altered the Codeception ParamsLoader to the above the functional tests worked as expected because the variables were kept in PHP's `putenv` and unaffected by the Yii2 connector reseting `$_SERVER` variables.

Should the ParamsLoader be using `usePutenv(true)` by default or would it be possible to add an option in the `codeception.yml` to enable this behaviour as a workaround for frameworks that do not use the `$_ENV` for environment variables?

Alternatively it might be good to add a notice on the Codeception documentation advising developers that this could be an issue when implementing functional tests in some frameworks and how to work around it.

### Details

* Codeception version: 5.1.2
* PHP Version: 8.2
* Operating System: Debian Bookworm via `ddev`
* Installation type: Composer
* List of installed packages
```
codeception/codeception 5.1.2
codeception/lib-asserts 2.1.0
codeception/lib-innerbrowser 3.1.3
codeception/lib-web 1.0.6
codeception/module-asserts 3.0.0
codeception/module-phpbrowser 3.0.1
codeception/module-yii2 1.1.10
craftcms/cms 4.9.4
symfony/browser-kit 6.0.19
symfony/dotenv 5.4.39
yiisoft/yii2 2.0.48.1
```
* Suite configuration:

```yml
actor: Tester
paths:
tests: tests/codeception
log: tests/codeception/_output
data: tests/codeception/_data
support: tests/codeception/_support
output: tests/codeception/_output
envs: tests/codeception/_envs
bootstrap: _bootstrap.php
params:
- .env
- tests/codeception/.env
modules:
config:
\craft\test\Craft:
configFile: "tests/codeception/_craft/config/test.php"
entryUrl: "https://mytestsite.localhost/index.php"
projectConfig: {}
migrations: []
plugins: []
cleanup: true
transaction: true
fullMock: false
dbSetup: { clean: false, setupCraft: false }
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.