Environment specific variables in Laravel's testing environment
!Warning: This post is over a year old. I don't always update old posts with new information, so some of this information may be out of date.
In Laravel, it's easy to set environment variables that are specific to your testing environment. Just edit your phpunit.xml
file and set them as entries in the <php>
block:
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="TWILIO_FROM_NUMBER" value="+15005550006"/>
</php>
But what if you find yourself needing to exclude these values from version control?
My example
I'm getting back to work on PulledOver, which uses Twilio as its foundation. I wanted to write some tests for my TwilioClient class, which directly connects to Twilio's API, so I was using Twilio's Test Credentials to send fake calls to the API and examine their responses.
But that means I have a Twilio SID and Token that I'm not supposed to expose to the public, right? I even asked around on Twitter:
#geek
When you’re working with @twilio Test credentials, does it matter if you commit them to version control? Would be easier if I could…
— Matt Stauffer (@stauffermatt) November 3, 2015
I got quite a few responses, and one from the CEO of Twilio (!):
@stauffermatt @twilio Best not to check them in. We may rate-limit API requests w/ test credentials, and if the whole world is using yours..
— Jeff Lawson (@jeffiel) November 3, 2015
OK, so I need to exclude them. But how? I scratched my head a few times, dropped a question in the company Slack, and went to sleep. I woke up this morning and the ever-resourceful Keith Damiani had an answer for me: use Dotenv (which Laravel uses to load .env
) to load a .env.test
file in Laravel's TestCase base class. DUH. Here's how you do it:
Implementing .env.test
in Laravel
First, create a .env.test.example
file and fill it with placeholders for whichever keys you want:
TWILIO_ACCOUNT_SID=fillmein
TWILIO_ACCOUNT_TOKEN=fillmein
Next, copy .env.test.example
to .env.test
and fill in the actual values.
Add .env.test
to your .gitignore
file.
Finally, add these line to tests/TestCase.php
's createApplication
method, just below $app = require __DIR__.'/../bootstrap/app.php';
:
Note: Dotenv has changed their syntax multiple times recently, so I'll show three different versions here:
// Old Dotenv
if (file_exists(dirname(__DIR__) . '/.env.test')) {
Dotenv::load(dirname(__DIR__), '.env.test');
}
// Medium-old Dotenv
if (file_exists(dirname(__DIR__) . '/.env.test')) {
(new \Dotenv\Dotenv(dirname(__DIR__), '.env.test'))->load();
}
// New Dotenv
if (file_exists(dirname(__DIR__) . '/.env.test')) {
(\Dotenv\Dotenv::createImmutable(dirname(__DIR__), '.env.test'))->load();
}
That's it! Your .env.test
environment variables are now pulled into any test you run that extends TestCase
, but those values are safely kept out of version control.
Comments? I'm @stauffermatt on Twitter
Tags: testing • laravel • dotenv