Ever anxious about pushing new release of WordPress plugin causing the white screen of death on your clients’ sites? You should write some acceptance tests! I will demonstrate how to leverage Varying Vagrant Vagrants, Codeception and wp-browser to write acceptance tests for WordPress plugins.
The Tools
Codeception
Codeception is a PHP testing framework built on PHPUnit that automates acceptance testing. It does functional and unit tests also.
wp-browser
wp-browser is a WordPress specific set of extensions for Codeception written by theAverageDev.
The package includes a class extending Codeception PhpBrowser module that adds WordPress related assertions for
cest
andcept
tests, an extension of Codeception own Db module meant to allow for more comfortable WordPress specific database handling and testing and a class taking care of installing and loading a WordPress installation relying on WordPress automated testing suite.
Start with VVV
We’ll run our tests from within VVV because WP CLI, Node, and Composer are already installed for us there.
Before we actually writing the tests, we need a WordPress installation and a plugin to test. I use my plugin Remove Medium Cross Links as an example. All it does is remove the medium cross link footer from WordPress post.
Preparation
Create a WordPress site in VVV so that we can run our plugin on.
$ vv create
New VVV Site Setup
Name of new site directory: rmcl-tester
And create our plugin.
$ vagrant ssh
$ cd /srv/www/rmcl-test/htdocs/wp-content/plugins
$ wp scaffold plugin remove-medium-cross-links
The plugin is simple. Add these lines in remove-medium-cross-links.php
function remove_medium_cross_links() {
remove_action( 'init', array( 'Medium_Site', 'init' ) );
}
if ( ! is_admin() ) {
add_action( 'init', 'remove_medium_cross_links', 5 );
}
Test Manually
- Head to
rmcl-tester.dev
- Install and activate the official Medium plugin
- Add the Medium Integration Token on your profile page
- Add a new post and make sure it cross posted to medium
- Go to the new post. You should see the cross link footer
- Activate our
remove-medium-cross-links
plugin - Go back the post. The cross link footer should be gone
Database Snapshot
Codeception will reset the database between every test. We need to make this database dump.
$ wp db export tests/_data/dump.sql --path=/srv/www/rmcl-test/htdocs
Success: Exported to 'tests/_data/dump.sql'.
If you have a more complex setup, you could use WP Migrate DB Pro to fine tune the sql dump.
Start Testing
Install latest stable WPBrowser package via Composer:
$ composer require lucatume/wp-browser --dev
It might take a while. But once it’s done, we can configure Codeception and wp-browser. Answer the questions. Use default if not shown below.
$ vendor/bin/wpcept bootstrap -i
MySQL database host? (localhost) rmcl-test.dev
Test database name? (database) rmcl-test
Test database password? () root
Integration tests database password? () root
WordPress site url? (http://wp.dev) http://rmcl-test.dev
Absolute path to the WordPress root directory? (/var/www/wp) /srv/www/rmcl-test/htdocs/
Activate a plugin? (order matters, leave blank to move on) medium/medium.php
Activate a plugin? (order matters, leave blank to move on) remove-medium-cross-links/remove-medium-cross-links.php
Acceptance Test for Real
Time for our first acceptance test.
$ vendor/bin/wpcept generate:cept acceptance RemoveMediumCrossLinkFooter
In the generated tests/acceptance/RemoveMediumCrossLinkFooterCept.php
<?php
$I = new AcceptanceTester($scenario); $I->wantTo('test medium cross link footer is removed');
$I->amOnpage('/');
$I->click('Acceptance Test for rmcl');
$I->dontSee('Also published on Medium.');
However, it’s dangerous to just testing what we don’t see. Make a sanity check also.
$ vendor/bin/wpcept generate:cept acceptance SanityCheck
In tests/acceptance/SanityCheckCept.php
:
<?php
$I = new AcceptanceTester($scenario); $I->wantTo('see medium cross link footer when rmcl is deactivated');
$I->loginAsAdmin();
$I->amOnPluginsPage();
$I->deactivatePlugin('remove-medium-cross-links');
$I->amOnpage('/');
$I->click('Acceptance Test for rmcl');
$I->see('Also published on Medium.');
Note: loginAsAdmin()
, amOnPluginsPage()
and deactivatePlugin
come from wp-browser. Check the docs for more WordPress-specific methods.
Run the Acceptance Tests
$ vendor/bin/wpcept run acceptance
If you follow along, your tests should pass.
Real Browser Testing
Two green ticks sounds good. But where is the freaky browser jumping around and clicking itself you found on all those acceptance test demo? By default wp-browser run acceptance tests on WPBrowser, a PHP based, JavaScript-less and headless browser for acceptance testing not requiring JavaScript support.
We can do better, since VVV doesn’t provide GUI support. We will run the tests outside VVV, using your real browsers.
Selenium Server
Open a new tab in the terminal:
$ npm install selenium-standalone@latest -g
$ selenium-standalone install
$ selenium-standalone start
Note: The default version coms with this package is quite old. You can use $ selenium-standalone install --version=3.0.1 --drivers.firefox.version=0.13.0 --drivers.chrome.version=2.27
and $ selenium-standalone start --version=3.0.1 --drivers.firefox.version=0.13.0 --drivers.chrome.version=2.27
to specific selenium and drivers versions.
WPWebDriver
WPWebDriver – a Guzzle based, JavaScript capable web driver; to be used in conjunction with a Selenium server, PhantomJS or any real web browser for acceptance testing requiring JavaScript support
Head back to tests/acceptance.suite.yml
and instruct Codeception to use WPWebDriver instead.
class_name: AcceptanceTester
modules:
enabled:
- \Helper\Acceptance
- WPDb
- WPWebDriver
config:
WPDb:
dsn: 'mysql:host=rmcl-test.dev;dbname=rmcl-test'
user: root
password: root
dump: tests/_data/dump.sql
populate: true
cleanup: true
url: 'http://rmcl-test.dev'
tablePrefix: wp_
WPWebDriver:
url: 'http://rmcl-test.dev'
adminUsername: admin
adminPassword: password
adminPath: /wp-admin
wait: 5
host: '192.168.50.1'
browser: chrome
Run the Acceptance Tests Again
With $ selenium-standalone start
running in another tab.
$ vendor/bin/wpcept build
$ vendor/bin/wpcept run acceptance
Always good idea to run $ wpcept build
whenever you changed the config files.
A chrome tab will jump out and freaking around this time. As before, the tests should pass.
Stay tuned
Be sure to subscribe the my newsletter. I will talk about how to run these acceptance tests on TravisCI soon.