The road to a real WordPress functional module for Codeception.
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
$_POSTvariables 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
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
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.
WPWebDriver are for “acceptance” and “as functional as it can get for the time being” testing, not “real functional testing”.
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
So I’m working to create a real “functional” test module for WordPress that would allow me to write tests like this:
<?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.
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.