WPDb multisite capabilities demo 01

Where I come up with a use case for the multisite capabilities of WP Browser.

Multisite theme

I will try to develop a theme meant to be used on a WordPress network installation.
The theme has but to play nice when activated on a single site installation so I’m not dropping the single site activation case.
The main site header will sport a unique header navigation that child blogs will not show and child sites will show their unique headers plus another common to all of the multisite installations.
In user story terms this means:

Given WordPress is installed as single site And there is a menu registered in the header location When I visit the site index page Then I should see an header with the main-header id attribute. Given WordPress is installed as multisite And there is a menu registered in the header location of the main site When I visit the main site index page Then I should see an header with the main-header id attribute. Given WordPress is installed as multisite And there is a menu registered in the header location of the main site And there is a menu registered in the header location of the child site When I visit the child site index page Then I should see an header with the parent-header id attribute And I should see an header with the child-header id attribute.

The cases of missing menus registrations will have to be covered too but the stories above get the main concept across.

Unusual and usual drill

Leveraging the multisite related capabilities WP Browser offers I will not scaffold two local WordPress test installations.
To put the package to the test I will setup just a single site installation of WordPress and go as standard as it can get.
After YeoPress did his fine job of scaffolding a WordPress installation that will respond on the multisite.dev address I lay down the basic style.css needed to create a Twentysixteen child theme in the /wp-content/themes/_blogs folder.
The style.css file of the theme contains the bare-bones information for the theme to properly activate:

/*
 Theme Name:     _Blogs
 Theme URI:      http://theaveragedev.local
 Description:    A Multisite Demonstration Twentysixteen Child Theme
 Author:         Luca Tumedei
 Author URI:     http://theaveragedev.local
 Template:       Twentysixteen
 Version:        1.0.0
*/

@import url("../Twentysixteen/style.css");

Before I write any code I will set up the test suite to run.
I navigate to the theme root folder (/wp-content/themes/_blogs) and initialize Composer

composer init

After some set up question I pull in WP Browser as the first development dependency

composer require --dev lucatume/wpbrowser

It will take some time but it will eventually finish. Time to bootstrap the testing environment

wpcept bootstrap

While it is not required to use the wpcept bootstrap command to scaffold the test structures I find it easier then starting from a generic Codeception configuration; this said it is a matter of preference.
After going through the settings in the codeception.yml configuration files and making sure database credentials, URLs and other details are correct I run the whole test suite to make sure everything is in order

codecept run

This is the codeception.yml configuration file local to my machine setup

actor: Tester
paths:
    tests: tests
    log: tests/_output
    data: tests/_data
    helpers: tests/_support
settings:
    bootstrap: _bootstrap.php
    colors: true
    memory_limit: 1024M
modules:
    config:
        Db:
            dsn: 'mysql:host=127.0.0.1;dbname=multisite'
            user: root
            password: root
            dump: tests/_data/dump.sql
        WPBrowser:
            url: 'http://multisite.dev'
            adminUsername: admin
            adminPassword: admin
            adminUrl: /wp-admin
        WPDb:
            dsn: 'mysql:host=127.0.0.1;dbname=multisite'
            user: root
            password: root
            dump: tests/_data/dump.sql
            populate: true
            cleanup: true
            url: 'http://multisite.dev'
            tablePrefix: mu_
            checkExistence: true
            update: true
        WPLoader:
            wpRootFolder: /Users/Luca/Sites/multisite
            dbName: multisite-tests
            dbHost: 127.0.0.1
            dbUser: root
            dbPassword: root
            wpDebug: true
            dbCharset: utf8
            dbCollate: ''
            tablePrefix: wp_
            domain: multisite.dev
            adminEmail: admin@multisite.dev
            title: 'WP Tests'
            phpBinary: php
            language: ''
        WPWebDriver:
            url: 'http://multisite.dev'
            browser: phantomjs
            port: 4444
            restart: true
            wait: 2
            adminUsername: admin
            adminPassword: admin
            adminUrl: /wp-admin

Configuring acceptance tests

Now that I know the test suite can reach the database, the WordPress root location and has all the details needed for it to work I will take a closer look at the acceptance suite configuration file, acceptance.suite.yml, to have it configured the way I need it.
By default the acceptance suite is configured to use the WPBrowser and \Helper\Acceptance modules:

class_name: AcceptanceTester
modules:
    enabled:
        - WPBrowser
        - \Helper\Acceptance

Codeception allows refining suite configurations in more than one place using a cascading configuration definition not dissimilar from what happens in CSS, this means that the nuts and bolts of the modules I’ve defined in the general codeception.yml file and will add details and missing pieces that make sense in the acceptance suite configuration file only. I know the tests I’m writing are not going to require any JavaScript code to work and hence will stick to the WPBrowser module when it comes to the driven browser but will add the WPDbmodule. Since I know I will want to switch from single to multisite installations during tests, the local WordPress installation is a single site one, I will specify the file system location of the WordPress installation root: this way the WPDb module will know where to fetch and manipulate the files needed to make the WordPress installation run like a multisite one.
The modified acceptance.suite.yml configuration file is the one below

class_name: AcceptanceTester
modules:
    enabled:
        - WPBrowser
        - \Helper\Acceptance
        - WPDb
    config:
        WPDb:
            - wpRootFolder: /Users/Luca/Sites/multisite

I will be using acceptance tests in this development experiment and will set up the acceptance test fixture using the WPDb module and make assertions using the WPBrowser module.
To make sure the acceptance suite is working as intended I write a first simple acceptance test:

codecept generate:cept acceptance PreFlight

PreFlightCept generation Where I’m only visiting the index page and making sure I see a published post title

$I = new AcceptanceTester($scenario);
$I->wantTo('see a published post title');
$I->havePostInDatabase(['post_title'=> 'A post of mine']);
$I->haveOptionInDatabase('current_theme', '_Blogs');
$I->amOnPage('/');
$I->see('A post of mine');

The trivial test passes but underlines the essence of the flow I’ll be using:

$I = new AcceptanceTester($scenario);
$I->wantTo('see a published post title');

// Setup
$I->havePostInDatabase(['post_title'=> 'A post of mine']);
$I->haveOptionInDatabase('current_theme', '_Blogs');

// Execute
$I->amOnPage('/');

// Verify
$I->see('A post of mine');

PreFlightCept passing The reason I’ve added the WPDb module to the acceptance suite is exactly to make such a set up as easy as possible.

On GitHub

To avoid code bloating I’ve set up a repository on GitHub where I’ll push code tagged by the article number and allow for some deeper nose-diving.

Next

Time to write the first acceptance tests for the user stories.