You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
using <server ... in phpunit.xml.dist file to define default settings for test suite
using $_SERVER in test suite to use the above-defined settings
Problem:
Inability to override the above settings during GitHub Actions builds because we can set environment variables (readable through $_ENV) and not server variables (readable through $_SERVER).
Solution
Do so Find & Replace in the phpunit.xml.dist on GitHub Actions instead of providing environment variables like DRIVER_URL and such, that don't override what phpunit.xml.dist defines.
Firstly, we shouldn't use $_ENV or $_SERVER, we should use getenv() instead.
Secondly, I'm sorry but I don't understand the solution - what do you want to replace? The linked PR doesn't make a lot of sense to me, since the browser will almost always by different.
Additionally, it's not clear to me why the PHPUnit XML should use <server> or <env> - that I cannot judge. My feeling is that using <env> allows overriding by cli env vars whereas <server> doesn't allow overriding?
Firstly, we shouldn't use $_ENV or $_SERVER, we should use getenv() instead.
I also like getenv better (not sure though how it is different from $_ENV). However, it will introduce a BC break for other drivers, because we need to replace $_SERVER usages in the driver-testsuite repo as well.
Secondly, I'm sorry but I don't understand the solution - what do you want to replace? The linked PR doesn't make a lot of sense to me, since the browser will almost always by different.
Replace <server name="WEB_FIXTURES_HOST" value="http://host.docker.internal:8002"/> with a host needed by a GitHub Actions.
Additionally, it's not clear to me why the PHPUnit XML should use <server> or <env> - that I cannot judge. ...
Because this is the only way to configure how test suite runs (e.g. what browser to use for testing, how to map paths inside Document Root and such stuff).
... My feeling is that using <env> allows overriding by cli env vars whereas <server> doesn't allow overriding?
According to PHPUnit documentation using <env.... will change $_ENV (and getenv result) unless such environment variable is provided externally.
Example 1:
I have <env name="WEB_FIXTURES_HOST" value="http://host.docker.internal:8002"/> in the PHPUnit config file
I run PHPUnit as vendor/bin/phpunit
the getenv / $_ENV would have WEB_FIXTURES_HOST key as http://host.docker.internal:8002
Example 2:
I have <env name="WEB_FIXTURES_HOST" value="http://host.docker.internal:8002"/> in the PHPUnit config file
I run PHPUnit as WEB_FIXTURES_HOST="my-custom-host:80" vendor/bin/phpunit
the getenv / $_ENV would have WEB_FIXTURES_HOST key as my-custom-host:80
If I had used <server instead of <env such a trick wouldn't have worked.
And we want example 2 to work, right? Then the phpunit xml should be using env, not server?
I also like getenv better (not sure though how it is different from $_ENV).
$_ENV is always case sensitive (because of normal PHP array access), but getenv is case-insensitive depending on OS. e.g. $_ENV['PATH'] breaks on Windows, but getenv('PATH') is more cross-platform.
getenv is also more convenient, because you don't have to use isset/empty($_ENV).
getenv is theoretically slower (because of function call), but the benefits are worth it.
Note also that getenv is not thread safe. This is not an issue for usages in the testsuite though. but it might be an issue in driver code (as we don't control how it is used)
@stof, I've checked what PHPUnit 9 actually does with <server> and <env> when the same variable also comes from the shell (ENV_TEST set to PHPUNIT_OVERRIDE in the XML and to ENV_OVERRIDE or nothing in the shell):
XML
Shell
getenv()
$_SERVER
$_ENV
<server> PHPUNIT_OVERRIDE
ENV_OVERRIDE
ENV_OVERRIDE
PHPUNIT_OVERRIDE
–
<server> PHPUNIT_OVERRIDE
none
false
PHPUNIT_OVERRIDE
–
<env> PHPUNIT_OVERRIDE
ENV_OVERRIDE
ENV_OVERRIDE
ENV_OVERRIDE
ENV_OVERRIDE
<env> PHPUNIT_OVERRIDE
none
PHPUNIT_OVERRIDE
unset
PHPUNIT_OVERRIDE
So env vars do reach $_SERVER as you said, but an active <server> in phpunit.xml.dist overwrites them (row 1). And <env> never writes $_SERVER, so switching the XML to <env> alone would break $_SERVER reads when nothing comes from the shell (row 4).
Reading getenv() first and falling back to $_SERVER gives the right value in all 4 cases: the shell/CI value wins, and the XML value is the default.
Proposed method for AbstractConfig in driver-testsuite (replacing direct $_SERVER reads there):
Defaults stay at the call site, e.g. $this->getEnvVar('WEB_FIXTURES_HOST') ?? 'http://localhost:8002', so PHPStan sees a string there. In drivers the browser default would then live only in their getBrowserName().
It doesn't break drivers still using <server> (rows 1-2), so they could move to <env> at their own pace. All drivers require mink/driver-testsuite as dev-master, so composer update brings the method in, and the only order requirement is to merge it in driver-testsuite before switching a driver's XML to <env>.
This way both developers version phpunit.xml and phunit.xml.dist of driver (with <env or <server) keeps working (and doesn't suddenly fail if use only getenv without $_SERVER fallback).
We then could update driver's own phpunit.xml.dist to always-enabled-<env instead of sometimes-enabled-<server when we want.
@stof, to get this moving, which option do you prefer?
A. Pure getenv(). driver-testsuite replaces $_SERVER reads with getenv(), and drivers switch <server> to <env> in phpunit.xml.dist. Local phpunit.xml files still using <server> stop working. Drivers' CI breaks between the driver-testsuite merge and each driver's .dist update, because dev-master is pulled right away.
B. Same end state, with a bridge.minkphp/driver-testsuite#118 reads getenv() first and falls back to $_SERVER, with an E_USER_DEPRECATED when the value only came from $_SERVER. Drivers switch to <env> at their own pace, and people with a local <server> config get a message telling them what to change. Once all drivers have switched, the fallback is removed, leaving pure getenv().
In both cases I'd document <env> usage in the driver-testsuite README.
Activity
uuf6429 commentedon Nov 5, 2024
Firstly, we shouldn't use
$_ENVor$_SERVER, we should usegetenv()instead.Secondly, I'm sorry but I don't understand the solution - what do you want to replace? The linked PR doesn't make a lot of sense to me, since the browser will almost always by different.
Additionally, it's not clear to me why the PHPUnit XML should use
<server>or<env>- that I cannot judge. My feeling is that using<env>allows overriding by cli env vars whereas<server>doesn't allow overriding?aik099 commentedon Nov 5, 2024
I also like
getenvbetter (not sure though how it is different from$_ENV). However, it will introduce a BC break for other drivers, because we need to replace$_SERVERusages in thedriver-testsuiterepo as well.Replace
<server name="WEB_FIXTURES_HOST" value="http://host.docker.internal:8002"/>with a host needed by a GitHub Actions.Because this is the only way to configure how test suite runs (e.g. what browser to use for testing, how to map paths inside Document Root and such stuff).
According to PHPUnit documentation using
<env....will change$_ENV(andgetenvresult) unless such environment variable is provided externally.Example 1:
<env name="WEB_FIXTURES_HOST" value="http://host.docker.internal:8002"/>in the PHPUnit config filevendor/bin/phpunitgetenv/$_ENVwould haveWEB_FIXTURES_HOSTkey ashttp://host.docker.internal:8002Example 2:
<env name="WEB_FIXTURES_HOST" value="http://host.docker.internal:8002"/>in the PHPUnit config fileWEB_FIXTURES_HOST="my-custom-host:80" vendor/bin/phpunitgetenv/$_ENVwould haveWEB_FIXTURES_HOSTkey asmy-custom-host:80If I had used
<serverinstead of<envsuch a trick wouldn't have worked.uuf6429 commentedon Nov 5, 2024
And we want example 2 to work, right? Then the phpunit xml should be using
env, notserver?$_ENVis always case sensitive (because of normal PHP array access), butgetenvis case-insensitive depending on OS. e.g.$_ENV['PATH']breaks on Windows, butgetenv('PATH')is more cross-platform.getenvis also more convenient, because you don't have to useisset/empty($_ENV).getenvis theoretically slower (because of function call), but the benefits are worth it.aik099 commentedon Nov 5, 2024
Yes, but to make it work all usages of
$_SERVERin the test suite (not only driver code) must be replaced at least with$_ENV.As I said above that would be a BC break for all other drivers using the same test suite.
stof commentedon Nov 5, 2024
env variables are readable through
$_SERVERin PHP. We are already relying on that in other drivers when needed: https://github.com/minkphp/MinkSelenium2Driver/blob/db44be5055cb1dfcd323c7b375ff7cf97c187de9/.github/workflows/tests.yml#L87And we do it also in the current driver:
webdriver-classic-driver/.github/workflows/ci.yml
Lines 118 to 122 in 61b12d0
Note also that
getenvis not thread safe. This is not an issue for usages in the testsuite though. but it might be an issue in driver code (as we don't control how it is used)aik099 commentedon Nov 5, 2024
This works only, when you don't have corresponding ENV var defined in PHPUnit config file:
webdriver-classic-driver/phpunit.xml.dist
Line 23 in 61b12d0
This way if we define default env var values in PHPUnit config file they can't overridden via the environment given to PHPUnit runner itself.
aik099 commentedon Oct 6, 2026
@stof, I've checked what PHPUnit 9 actually does with
<server>and<env>when the same variable also comes from the shell (ENV_TESTset toPHPUNIT_OVERRIDEin the XML and toENV_OVERRIDEor nothing in the shell):getenv()$_SERVER$_ENV<server>PHPUNIT_OVERRIDEENV_OVERRIDEENV_OVERRIDEPHPUNIT_OVERRIDE<server>PHPUNIT_OVERRIDEfalsePHPUNIT_OVERRIDE<env>PHPUNIT_OVERRIDEENV_OVERRIDEENV_OVERRIDEENV_OVERRIDEENV_OVERRIDE<env>PHPUNIT_OVERRIDEPHPUNIT_OVERRIDEPHPUNIT_OVERRIDESo env vars do reach
$_SERVERas you said, but an active<server>inphpunit.xml.distoverwrites them (row 1). And<env>never writes$_SERVER, so switching the XML to<env>alone would break$_SERVERreads when nothing comes from the shell (row 4).Reading
getenv()first and falling back to$_SERVERgives the right value in all 4 cases: the shell/CI value wins, and the XML value is the default.Proposed method for
AbstractConfigindriver-testsuite(replacing direct$_SERVERreads there):Defaults stay at the call site, e.g.
$this->getEnvVar('WEB_FIXTURES_HOST') ?? 'http://localhost:8002', so PHPStan sees astringthere. In drivers the browser default would then live only in theirgetBrowserName().It doesn't break drivers still using
<server>(rows 1-2), so they could move to<env>at their own pace. All drivers requiremink/driver-testsuiteasdev-master, socomposer updatebrings the method in, and the only order requirement is to merge it indriver-testsuitebefore switching a driver's XML to<env>.aik099 commentedon Oct 6, 2026
This way both developers version
phpunit.xmlandphunit.xml.distof driver (with<envor<server) keeps working (and doesn't suddenly fail if use onlygetenvwithout$_SERVERfallback).We then could update driver's own
phpunit.xml.distto always-enabled-<envinstead of sometimes-enabled-<serverwhen we want.aik099 commentedon Oct 24, 2026
@stof, to get this moving, which option do you prefer?
A. Pure
getenv(). driver-testsuite replaces$_SERVERreads withgetenv(), and drivers switch<server>to<env>inphpunit.xml.dist. Localphpunit.xmlfiles still using<server>stop working. Drivers' CI breaks between the driver-testsuite merge and each driver's.distupdate, becausedev-masteris pulled right away.B. Same end state, with a bridge. minkphp/driver-testsuite#118 reads
getenv()first and falls back to$_SERVER, with anE_USER_DEPRECATEDwhen the value only came from$_SERVER. Drivers switch to<env>at their own pace, and people with a local<server>config get a message telling them what to change. Once all drivers have switched, the fallback is removed, leaving puregetenv().In both cases I'd document
<env>usage in the driver-testsuite README.