I wanted to run my acceptance tests against the live site, without breaking it. For that I needed to force Codeception to use a separate database.
This thread was really helpful getting me started. I ended up using a cookie to trigger the testing environment. It was quite a hassle, so I documented the procedure for future me. In case it helps anyone else, I'll share it here. I've gone step-by-step because it helps doofuses like me.
Create a new user profile in Firefox. I called my profile codeception. Open Firefox with this profile and install Firebug, then go to your site and use Firebug to set a cookie.
I had trouble getting Firebug to set a long-lasting cookie, so I opened about:config and changed extensions.firebug.cookies.defaultExpireTime to 1000000000 -- that's one billion seconds, or about 32 years.
Set the cookie from Firebug's cookie panel > Cookies > Create cookie. I called the cookie codeception and gave it a value of super-secret-password. You will need to do this on each of the subdomains where you want to run the tests (e.g. yourdomain, dev.yourdomain, stage.yourdomain...).
At this point you might want to uninstall Firebug from your new profile and restart Firefox, as this will reduce file sizes a lot. Find and open your profile folder. Now close Firefox.
For Codeception to use this profile, it must be zipped and base-64 encoded. Zip the contents of the folder, not the folder itself. Then run a base-64 encoding tool on it (e.g. this one). Afterwards, you should have a file like abc1xy2z.codeception.zip.b64.
Copy this file to your Laravel app; you can also rename the file. Mine was app/tests/_data/browsers/firefox/profile.zip.b64. Now configure your acceptance.suite.yml. You will need Codeception 2.0.7 or later for this to work:
class_name: WebGuy
modules:
enabled: [WebDriver, Db]
config:
WebDriver:
url: 'http://yourdomain.com'
browser: firefox
capabilities:
firefox_profile: 'app/tests/_data/browsers/firefox/profile.zip.b64'
At this point you have set up Codeception to launch a different Firefox profile, which contains a special cookie. Now in your Laravel environment detection, you can use this to trigger the acceptance testing environment:
// bootstrap/start.php
$env = $app->detectEnvironment(function()
{
// Use ENV files, ignored in Git, for reliable and safe detection
if (file_exists(__DIR__ . '/../.env_name.php'))
{
$env = include(__DIR__ . '/../.env_name.php');
}
else
{
$env = 'staging'; // The least dangerous option!
}
// Check for a cookie to tell if we're running acceptance tests
if ( isset($_COOKIE['codeception'])
&& $_COOKIE['codeception'] === 'super-secret-password' )
{
$env = 'acceptance';
}
return $env;
});
Now Codeception will run in the acceptance environment. You can provide a different database name (e.g. testing) and credentials for this environment. Of course it's important not to use your production database credentials, especially when configuring the Db module in codeception.yml for direct database access.
One thing I haven't shown here is my whole acceptance.suite.yml setup. To make this useful, you need to create a new environment for each site you want to test. You can then run the tests from your local machine, with codecept run acceptance --env=environment_name. This is covered in the Codeception documentation, but if anyone wants an example, just ask.