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.