Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using two databases at the same time in codeception

How can I use two databases at the same time in codeception? My PHP app uses an SQLite database, but also connects with another app that uses a MySQL database.

At the moment I have this in my codeception.yml file:

modules:
  config:
    Db:
        dsn: 'sqlite:db.sqlite'
        dump: tests/_data/dump.sql
        populate: true
        cleanup: true

This way the database populates each time with test data and cleans itself automatically at the end of the tests. How can I add a MySQL database now that does the same?

Also, in case it's possible, in some tests I'm using the "seeInDatabase" function. How would I specify which database it has to look?

like image 631
Ivan Avatar asked Aug 27 '15 09:08

Ivan


2 Answers

We can actually accomplish this fairly easily by using Codeception Extension Classes. What we'll be doing with Extensions is as follows:

Hook into the "before test" and "after test" events with our Extension Reconfigure the Db module to point to our web service, re-initialize the module and execute Repeat for each web service To get started, we need to first enable the Db module in our Acceptance tests. Follow the instructions to setup the Db module. What's important here is that we set populate and cleanup to false and that dump points to a valid file. We set populate and cleanup to false because we don't want the Db module populating and cleaning up after each test. Well, we kind of do, but by default the Db module only communicates with one database where we need multiple.

Second, follow the instructions for creating a basic Codeception Extension. After you have setup your class, configured and included it in your bootstrap, you can use the following code as a guide:

class YourExtensionClass extends \Codeception\Platform\Extension {

// events to listen on
static $events = array(
'test.before' => 'beforeTest',
'test.after' => 'afterTest',
);

function beforeTest(\CodeCeption\Event\Test $e)
{
// get the test and groups
$test = $e->getTest();
$groups = $test->getScenario()->getGroups();

// only restore if annotated to do so
if (in_array('api', $groups)) {
// get the Db module
$db = $this->getModule('Db');

// re-initialize with web service one api config and execute
$webserviceOneConfig = $this->getWebServiceOneConfig($this->config);
$db->_reconfigure($webserviceOneConfig);
$db->_initialize();
$db->_before($test);

// re-initialize with web service two api config and execute
$webserviceTwoConfig = $this->getWebServiceTwoConfig($this->config);
$db->_reconfigure($webserviceTwoConfig);
$db->_initialize();
$db->_before($test);
}
}

function afterTest(\CodeCeption\Event\Test $e)
{
// get the test and groups
$test = $e->getTest();
$groups = $test->getScenario()->getGroups();

// only restore if annotated to do so
if (in_array('api', $groups)) {
// get the Db module
$db = $this->getModule('Db');

// re-initialize with web service one api config and execute
$webserviceOneConfig = $this->getWebServiceOneConfig($this->config);
$db->_reconfigure($webserviceOneConfig);
$db->_initialize();
$db->_after($test);

// re-initialize with web service two api config and execute
$webserviceTwoConfig = $this->getWebServiceTwoConfig($this->config);
$db->_reconfigure($webserviceTwoConfig);
$db->_initialize();
$db->_after($test);
}
}

private function getWebServiceOneConfig($config)
{
return array(
'dsn' => 'your first webservice db dsn',
'dump' => '/path/to/your/first/dump/file',
'populate' => true,
'cleanup' => true,
);
}

private function getWebServiceTwoConfig($config)
{
return array(
'dsn' => 'your second webservice db dsn',
'dump' => '/path/to/your/second/dump/file',
'populate' => true,
'cleanup' => true,
);
}

If have my extension setup to only fire if a given test is annotated properly, which is:

// in a Cest
/**
* @group api
*/
public function hereIsSomeTest(WebGuy $I)
{
...
}

// in a Cept
$scenario->group('api');
$I = new WebGuy($scenario);

I setup the extension to adhere to the "api" annotation so I didn't have to setup and tear down my API databases on every single test, only those that deal with data. However, you could very easily modify to suit your needs.

like image 44
kayleighsdaddy Avatar answered Nov 19 '22 18:11

kayleighsdaddy


Have a look at a module I have contributed to, called Codeception MultiDb.

like image 154
ϹοδεMεδιϲ Avatar answered Nov 19 '22 17:11

ϹοδεMεδιϲ