December 22, 2018 by Glenn
One of my legacy applications uses a mix of Phinx to handle my database migrations and Codeception to handle my acceptance testing suite. However I primarily develop in Laravel and have gotten a bit spoiled by their easy testing setup. When I run my test suite in Laravel it refreshes my testing database with the latest migrations. I wanted to acheive the same thing with Codeception.
Codeception gives you the option out of the box to refresh your testing database when you run your test suite using a sql dump. This is convenient but I didn't want to have to create a new dump every time I updated my migrations, I'd rather it just work.
It took me awhile but after enough digging I found all the information necessary to do this between the docs on both sites, and it's actually fairly easy. So I figured I'd compile the info here for anyone interested.
Firstly, we want to add a new connection to our enviornments
array in our phinx.yml
file. I call the connection testing
and supply it with the credentials for my testing database.
Phinx accepts either a phinx.yml
file or a phinx.php
file. I go the php route so that I can make use of Dotenv
for environment variables. You can use whichever format works for you.
<?php
require 'vendor/autoload.php';
$dotenv = new Dotenv\Dotenv(__DIR__);
$dotenv->load();
return [
'paths' => [
'migrations' => '%%PHINX_CONFIG_DIR%%/db/migrations',
'seeds' => '%%PHINX_CONFIG_DIR%%/db/seeds',
],
'environments' => [
'default_database' => getenv('APP_ENV'),
'default_migration_table' => 'phinxlog',
'local' => [
'adapter' => 'mysql',
'host' => getenv('DB_HOST'),
'name' => getenv('DB_DATABASE'),
'user' => getenv('DB_USERNAME'),
'pass' => getenv('DB_PASSWORD'),
'port' => 3306,
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
],
'testing' => [
'adapter' => 'mysql',
'host' => getenv('DB_TESTING_HOST'),
'name' => getenv('DB_TESTING_DATABASE'),
'user' => getenv('DB_TESTING_USERNAME'),
'pass' => getenv('DB_TESTING_PASSWORD'),
'port' => 3306,
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
]
],
];
In the enviornments
array you would probably want to add in another array for production as well. But for the sake of this post all we really need is our testing connection.
Next you'll want to open up and modify your tests/_support/Helper/Acceptance.php
file.
<?php
namespace Helper;
use Phinx\Console\PhinxApplication;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\NullOutput;
class Acceptance extends \Codeception\Module
{
public function _before($settings = [])
{
$app = new PhinxApplication();
$app->setAutoExit(false);
$app->run(new StringInput('rollback -e testing -t 0'), new NullOutput());
$app->run(new StringInput('migrate -e testing'), new NullOutput());
$app->run(new StringInput('seed -e testing'), new NullOutput());
}
}
The -e testing
is the important thing to note here, as it instructs Phinx to use our testing environment we setup. Also noteworthy is the -t 0
flag at the end of the rollback command, this tells Phinx to rollback all of your database migrations and start from scratch.
That's pretty much it. Simple right?