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 themain-header
id
attribute. Given WordPress is installed as multisite And there is a menu registered in theheader
location of the main site When I visit the main site index page Then I should see an header with themain-header
id
attribute. Given WordPress is installed as multisite And there is a menu registered in theheader
location of the main site And there is a menu registered in theheader
location of the child site When I visit the child site index page Then I should see an header with theparent-header
id
attribute And I should see an header with thechild-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 WPDb
module. 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
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');
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.