Faster WordPress acceptance testing in Codeception – 02

In an earlier post I’ve presented a basic WordPress-oriented extension of the PhpBrowser Codeception class.
Although working used alone it will generate some strong test coupling and inter-dependency issues in cases where one test will fail, and hence return, without restoring the original state.

Before, after and failed

Cest format tests allow for more flexibility over cept format tests thanks to _before, _after and failed methods but still do not allow conditionals in the tests to implement a dynamic pre-condition setting.
As an example a test like this one to check for dependent plugin activation

<?php 
$I = new AcceptanceTester($scenario);

// describe
$I->am('an administrator');
$I->wantTo('activate Plugin B with Plugin A installed and activated');

// set up the test pre-conditions
$I->loginAsAdmin();
$I->amOnPluginsPage();
$I->activatePlugin('plugin-a'); // could fail here but still pre-condition!

// test
$I->activatePlugin('plugin-b');
$I->seeElement('#message.updated');
$I->seePluginActivated('plugin-b');

// reset, might never happen and screw following tests
$I->deactivatePlugin('plugin-b');
$I->deactivatePlugin('plugin-a');

could fail because “plugin-a” is activated already, the activation link is not found and the test will fail before any real testing began.
But there a reason and a solution to it.

Easy solution

Since WordPress is a stateful machine persisting its state to a database resetting that same database will reset WordPress to a known state; Codeception allows that in an easy way using the Db module.
To allow for that soft-site-reset I’ve modified the Vagrant machine to allow for external connections to the database and added the Db module to acceptance test.
That’s done modifying the /tests/acceptance.suite.yml file to include the module and its configuration

# Codeception Test Suite Configuration

# suite for acceptance tests.
# perform tests in browser using the WebDriver or PhpBrowser.
# If you need both WebDriver and PHPBrowser tests - create a separate suite.

class_name: AcceptanceTester
modules:
    enabled:
        - AcceptanceHelper
        - WPBrowser
        - Db
    config:
        WPBrowser:
            url: 'http://test-site.local'
            adminUsername: 'admin'
            adminPassword: 'admin'
            adminUrl: '/wp-core/wp-admin'
        Db:
            dsn: 'mysql:host=192.168.33.21;dbname=testDb'
            user: 'root'
            password: 'root'
            dump: 'tests/_data/dump.sql'
            populate: true
            cleanup: false

and rebuilding the AcceptanceTester class after that with

codecept build

I will now get totally independent acceptance tests separated by a thorough database reset.

3 thoughts on “Faster WordPress acceptance testing in Codeception – 02

  1. Can you explain me please, how I can use _failed method in my acceptance test if I need use $I in there? And what to pass in those method? What $test variable I can pass from, for example, Helper class, in which I will overload _failed?

    1. I have not dug that deep into Codeception module creation and thus my answer might be wrong; _failed is a module hook and is not to be used writing tests so it falls into “module developer” domain rather than “developer testing code using a module” domain.
      When it comes to passing parameters it’s not the module developer business as those parameters will be passed to the method, _failed as any other module method, by (my guess) Codeception reflection engine; my guess (again) is that a module method will be called in a call_user_func way so in modules I will type-hint the parameters rather than passing them and in _failed specific case $test will be an object representing the current test being run and $fail should be meta information about that test fail conditions.

      To trust your own eyes instead run a debug session, set a breakpoint after the _failed method signature and see what’s in those parameters.

      Hope it helps.

I appreciate your input