ergebnis / environment-variables
Provides an abstraction for environment variables.
Installs: 2 779
Dependents: 0
Suggesters: 0
Security: 0
Stars: 39
Watchers: 3
Forks: 2
Open Issues: 0
Requires
- php: ~8.1.0 || ~8.2.0 || ~8.3.0
Requires (Dev)
- ergebnis/composer-normalize: ^2.39.0
- ergebnis/data-provider: ^3.1.0
- ergebnis/license: ^2.3.0
- ergebnis/php-cs-fixer-config: ^6.12.0
- ergebnis/phpunit-slow-test-detector: ^2.4.0
- infection/infection: ~0.27.8
- phpunit/phpunit: ^10.4.2
- psalm/plugin-phpunit: ~0.18.4
- rector/rector: ~0.18.11
- vimeo/psalm: ^5.16.0
README
This project provides a composer
package with an abstraction of environment variables.
Installation
Run
composer require ergebnis/environment-variables
Usage
This package provides the interface Ergebnis\Environment\Variables
along with the following production implementations:
This package also provides the following test implementations:
Ergebnis\Environment\FakeVariables
Ergebnis\Environment\ReadOnlyVariables
Ergebnis\Environment\TestVariables
Production Implementation
Ergebnis\Environment\SystemVariables
If you want to read, set, and unset environment variables in an object-oriented way in a production environment, you can use Ergebnis\Environment\SystemVariables
:
<?php declare(strict_types=1); use Ergebnis\Environment; final class BuildEnvironment { private Environment\Variables $environmentVariables; public function __construct(Environment\Variables $environmentVariables) { $this->environmentVariables = $environmentVariables; } public function isGitHubActions(): bool { return $this->environmentVariables->has('GITHUB_ACTIONS') && 'true' === $this->environmentVariables->get('GITHUB_ACTIONS'); } public function isTravisCi(): bool { return $this->environmentVariables->has('TRAVIS') && 'true' === $this->environmentVariables->get('TRAVIS'); } }
Test Implementation
Ergebnis\Environment\FakeVariables
If you want to read, set, and unset environment variables in an object-oriented way in a test environment, but do not actually want to modify system environment variables, you can use Ergebnis\Environment\FakeVariables
as a test-double:
<?php declare(strict_types=1); use Ergebnis\Environment; use PHPUnit\Framework; final class BuildEnvironmentTest extends Framework\TestCase { public function testIsGitHubActionsReturnsFalseWhenNoneOfTheExpectedEnvironmentVariablesAreAvailable(): void { $environmentVariables = Environment\FakeVariables::empty(); $buildEnvironment = new BuildEnvironment($environmentVariables); self::assertFalse($buildEnvironment->isGitHubActions()); } public function testIsGitHubActionsReturnsFalseWhenValueOfGitHubActionsEnvironmentVariableIsNotTrue(): void { $environmentVariables = Environment\FakeVariables::fromArray([ 'GITHUB_ACTIONS' => 'false', ]); $buildEnvironment = new BuildEnvironment($environmentVariables); self::assertFalse($buildEnvironment->isGitHubActions()); } public function testIsGitHubActionsReturnsTrueWhenValueOfGitHubActionsEnvironmentVariableIsTrue(): void { $environmentVariables = Environment\FakeVariables::fromArray([ 'GITHUB_ACTIONS' => 'true', ]); $buildEnvironment = new BuildEnvironment($environmentVariables); self::assertTrue($buildEnvironment->isGitHubActions()); } }
Ergebnis\Environment\ReadOnlyVariables
If you want to read environment variables in an object-oriented way in a test environment, but neither actually want to modify system environment variables, nor allow modification by the system under test, you can use Ergebnis\Environment\ReadOnlyVariables
as a test-double:
<?php declare(strict_types=1); use Ergebnis\Environment; use PHPUnit\Framework; final class BuildEnvironmentTest extends Framework\TestCase { public function testIsGitHubActionsReturnsFalseWhenNoneOfTheExpectedEnvironmentVariablesAreAvailable(): void { $environmentVariables = Environment\ReadOnlyVariables::empty(); $buildEnvironment = new BuildEnvironment($environmentVariables); self::assertFalse($buildEnvironment->isGitHubActions()); } public function testIsGitHubActionsReturnsFalseWhenValueOfGitHubActionsEnvironmentVariableIsNotTrue(): void { $environmentVariables = Environment\ReadOnlyVariables::fromArray([ 'GITHUB_ACTIONS' => 'false', ]); $buildEnvironment = new BuildEnvironment($environmentVariables); self::assertFalse($buildEnvironment->isGitHubActions()); } public function testIsGitHubActionsReturnsTrueWhenValueOfGitHubActionsEnvironmentVariableIsTrue(): void { $environmentVariables = Environment\ReadOnlyVariables::fromArray([ 'GITHUB_ACTIONS' => 'true', ]); $buildEnvironment = new BuildEnvironment($environmentVariables); self::assertTrue($buildEnvironment->isGitHubActions()); } }
💡 The ReadOnlyVariables
implementation will throw a ShouldNotBeUsed
exception when the system under tests uses any of the following methods:
set()
unset()
Ergebnis\Environment\TestVariables
If your tests depend on environment variables, you have the following challenges:
- when you modify environment variables in a test, you want to restore environment variables that have existed before the test run to their original values
- when you modify environment variables in a test that has not been backed up before, and forget to restore it, it might affect other tests
To solve this problem, you can add the @backupGlobals
annotation to your test cases when using phpunit/phpunit
, or use Ergebnis\Environment\TestVariables
:
<?php declare(strict_types=1); use Ergebnis\Environment; use PHPUnit\Framework; final class FooTest extends Framework\TestCase { private static Environment\TestVariables $environmentVariables; protected function setUp() : void { // will back up environment variables FOO, BAR, and BAZ self::$environmentVariables = Environment\TestVariables::backup( 'FOO', 'BAR', 'BAZ' ); } protected function tearDown() : void { // will restore backed-up environment variables FOO, BAR, and BAZ to their initial state self::$environmentVariables->restore(); } public function testSomethingThatDependsOnEnvironmentVariableFooToBeSet(): void { self::$environmentVariables->set( 'FOO', '9000' ); // ... } public function testSomethingThatDependsOnEnvironmentVariableFooToBeUnset(): void { self::$environmentVariables->unset('FOO'); // ... } public function testSomethingThatDependsOnEnvironmentVariableQuxToBeSet(): void { // will throw exception because the environment variable QUX has not been backed up self::$environmentVariables->set( 'QUX', '9000' ); // ... } public function testSomethingThatDependsOnEnvironmentVariableQuxToBeUnset(): void { // will throw exception because the environment variable QUX has not been backed up self::$environmentVariables->unset('QUX'); } }
Changelog
The maintainers of this project record notable changes to this project in a changelog.
Contributing
The maintainers of this project suggest following the contribution guide.
Code of Conduct
The maintainers of this project ask contributors to follow the code of conduct.
General Support Policy
The maintainers of this project provide limited support.
You can support the maintenance of this project by sponsoring @localheinz or requesting an invoice for services related to this project.
PHP Version Support Policy
This project supports PHP versions with active and security support.
The maintainers of this project add support for a PHP version following its initial release and drop support for a PHP version when it has reached the end of security support.
Security Policy
This project has a security policy.
License
This project uses the MIT license.
Social
Follow @localheinz and @ergebnis on Twitter.