A less painful local testing set up in Codeception 01

Easier database fixture sharing.

Snapshotting databases

I’ve outlined my ideal flow to have a team easily share and use database based test fixtures in a previous post and am working to cover the pieces of that narrative.
I work in WordPress most of the time and am well aware of how one of its perks could make sharing a database fixture a pain.
The db:snapshot command embedded in the under development version of wp-browser has the objective of easing that difficulty.
A database fixture makes sharing a starting point for a test, like a combination of posts and taxonomies or a combination of options; very fast; WordPress is a stateless machine completely relying on the database to keep track of its state: this makes sharing said state a reliable way to share a common starting point.
Almost.
Hardcoded URLs make sharing the same database across WordPress installations a non straightforward procedure requiring, in its most basic solution, the use of a tool like wp-cli.
Embedding such a procedure in the testing tool that will consume the fixture and not requiring WP-CLI seemed like a good solution.

A command usage example

So how to share a database fixture?
I will make an example: the team uses Jenkins for CI and the domain Jenkins uses to run WordPress tests is http://jenkins.wp.dev and this domain is the one the team, for practical purposes, chooses as the “distribution domain”.
A developer of the team is assigned a ticket numbered 4455 that requires a complex database state to be reproduced; after setting up his/her local database to reproduce the issue (something that might not be done using WPDb built-in methods) the developer dumps the database initial state directing the command to create a dump of the database he uses locally for the tests, wp-tests, in the tests/_data/ticket-4455.sql (local version) and tests/_data/ticket-4455.dist.sql (distribution version) dump files

wpcept db:snapshot ticket-4455 wp-tests --local-url=http://wp-tests.dev --dist-url=http://jenkins.wp.dev

Once the repository .gitignore file is updated to ignore the tests/_data/ticket-4455.sql file and the tests are passing the modifications and the dump can be pushed to the common repository. If the database dump was to be used in a Codeception functional test then loading the dump for a specific test case class will require little code:

<?php

class Ticket4455Test extends \Codeception\TestCase\Test
{
    /**
     * @var \FunctionalTester
     */
    protected $tester;

    protected function _before()
    {
        // get the Db module
        /** @var \Codeception\Module\Db $db */
        $db =$this->getModule('Db');

        // get the db driver
        /** @var \Codeception\Lib\Driver\Db $driver */
        $driver= $db->driver;

        // cleanup the database
        $driver->cleanup();

        // use the local file if found else use the dist one: CI will only have this!
        $localDump = codecept_data_dir('ticket-4455.sql');
        $dumpFile = file_exists($localDump)? $localDump : codecept_data_dir('ticket-4455.dist.sql');

        // and load the dump
        $driver->load(file_get_contents(codecept_data_dir($dumpFile)));
    }

    protected function _after()
    {
    }

    /**
     * something should work
     */
    public function test_something_should_work()
    {
        // db fixture is loaded, run the test
    }
}

One can get way fancier but the base idea is there.
An alternative is to use Codeception Environments and have an environment set up for the ticket (not ideal to me).

Next

Decomposing the problem of an easier local set up for teams I will move to the search and replace function and the setup command integration.