A WordPress functional testing module 00

The road to a real WordPress functional module for Codeception.

Why? And: another module?

The wp-browser package contains a number of modules.
Those were born out of my growing knowledge of WordPress and testing techniques and, in a learning process, I’ve called many things many different, and often wrong, names.
What I’ve very often misnamed are “functional” tests; in turn I’ve called “functional” tests what really were “integration” tests and then “acceptance” tests. Mostly out of ignorance and confusion.
The recent work to put up the “Codeception for WordPress” page and the simple but clear feedback received from Codeception creator, Michael Bodnarchuck, picked my brain and showed me that misnaming of mine in full light.
So, to borrow Codeception site definition of “functional tests”:

Now that we’ve written some acceptance tests, functional tests are almost the same, with just one major difference: functional tests don’t require a web server to run tests. In simple terms we set $_REQUEST, $_GET and $_POST variables and then we execute application from a test. This may be valuable as functional tests are faster and provide detailed stack traces on failures.

A provided example of a Symfony2 functional test might below:

$I = new FunctionalTester($scenario);
$I->amOnPage('/');
$I->click('Login');
$I->fillField('Username', 'Miles');
$I->fillField('Password', 'Davis');
$I->click('Enter');
$I->see('Hello, Miles', 'h1');
// $I->seeEmailIsSent() - special for Symfony2

Does not WPLoader does that? Or WPBrowser?

For a quick overview of the modules included in the package see the README file.
While the method naming looks like what I could, right now, write in a module using the WPBrowser or WPWebDriver modules those will require a web server to run.
This means the request will be processed by a web-server like Apache and then forwarded to WordPress index to get a response.
So: no, WPBrowser and WPWebDriver are for “acceptance” and “as functional as it can get for the time being” testing, not “real functional testing”.
What about WPLoader then? No web server and direct access to WordPress code base. Again from Codeception site:

Acceptance tests are usually much slower than functional tests. But functional tests are less stable as they run Codeception and application in one environment. If your application was not designed to run in long living process, for instance you use exit operator or global variables, probably functional tests are not for you.

That sounds a lot like WPLoader module (beside the note about global variables that is kind of a WordPress trademark) but while I will be able to access WordPress defined code in my tests including WPLoader module I will not be able to access methods like amOnPage().

The pieces are there

Almost.
So I’m working to create a real “functional” test module for WordPress that would allow me to write tests like this: s

<?php
$I->am('a site visitor');
$I->wantToTest('that I can see posts on the front page');

$I->factory()->post->create(['post_title' => 'A post']);
$I->amOnPage('/');
$I->see('A post');

As trivial as this test might be it tells the story of what I’d like to be able to do in a WordPress functional test:

  • access unit test facilities and utilities to manipulate WordPress database content
  • “browse” the WordPress code base having a WordPress pseudo-index file serve the request responses

Another example nails those concepts:

<?php
$I->am('a site visitor');
$I->wantToTest('that I can see a post single page using permalinks');

update_option('permalink_structure', '/%postname%/');
flush_rewrite_rules(false);

$I->factory()->post->create(['post_title' => 'A post', post_name' => 'a-post']);
$I->amOnPage('/a-post');
$I->see('A post');

A functional test module should allow for the use of WordPress defined functions in functional tests beside facilities and module-defined methods.
Furthermore the tests above have the syntax of Codeception Cept format tests but a WordPress functional module should support Cest test format too.

Next

I will work to release a first working version of the aptly named WordPress module in a branch and see what can be done with it.