Setup integration exams in your WordPress Plugin
It took some time and my imaginative and prescient modified lots about exams throughout that time period.
Whereas writing the article on unit exams I used to be satisfied unit exams the place the primary to study to put in writing. Nevertheless, the fragility from theses exams made me change my thoughts as they weren’t giving sufficient outcomes for brand spanking new builders to persuade them to maintain utilizing them on the long run.
This is the reason I slowly modified my thoughts and at last began recommending to builders to start by specializing in essentially the most secure exams, integration exams, and that even when they’re extra complicated that unit exams to start out with.
All of that is what pushed me into writing this text to show the bottom of integration exams to builders wanting begin testing as creating the surroundings to check is usually essentially the most complicated half.
However first to know nicely what we might be doing you will need to get the principle variations between unit and integration exams.
The place unit exams are supposed to check the lessons or strategies individually as their identify let it guess, on the opposite aspect integration exams might be on an larger stage testing on the stage from the elements or options.
Being at options stage a bonus as now it’s potential to make use of enterprise assertions to check our code and it’s not any longer as much as us the developer to seek out instances from our exams.
On the similar time testing an larger stage additionally means larger abstraction main into extra flexibility to alter and fewer fragile exams.
Theses two factors makes theses exams a robust candidate to start out with and keep on with on the long run.
Now that know what are integration exams and why they’re your best option to start out with it’s time to set up the surroundings.
To not repeat the method I’ll contemplate that you have already got a composer mission initialized.
If it’s not the case you possibly can comply with the steps detailed in my article on Unit exams.
As setup a full surroundings for integration exams will be lengthy and complicated if performed manually we could have depend on some libraries to make the job for us.
wordpress/env
As organising a growing surroundings is one thing that may be time losing WordPress group developed an automatic option to setup one.
As you may guess the identify from that software is wordpress/env however earlier than utilizing it be sure to have Docker installed.
As soon as that is performed the subsequent requirement is to have npm, the Node.js package deal supervisor, put in. If it’s not the case you could find a tutorial here.
With theses necessities met then the set up can begin.
First a brand new Node.js mission must be initialized on the root from our plugin mission with the next command:
npm init
This could generate a brand new package deal.json file into the folder.
Then the subsequent step might be to put in wordpress/env with the next command:
npm i wordpress/env
As soon as that is accomplished we must add the next content material inside package deal.json:
{
"scripts": {
"wp-env:start": "wp-env start",
"wp-env:stop": "wp-env stop",
"wp-env:destroy": "wp-env destroy"
},
}
Lastly the final step is to run the surroundings utilizing this command:
npm run wp-env:begin
If the whole lot goes effective then it ought to give the next output:
> wp-env:begin
> wp-env begin
⚠ Warning: couldn’t discover a .wp-env.json configuration file and couldn’t decide if ‘/var/www/testing-wp/internet/app/plugins/my_plugin’ is a WordPress set up, a plugin, or a theme.
WordPress growth web site began at http://localhost:8888
WordPress check web site began at http://localhost:8889
MySQL is listening on port 32770
MySQL for automated testing is listening on port 32769
✔ Carried out! (in 57s 413ms)
Course of completed with exit code 0
wp-media/phpunit
As soon as the event surroundings is settled the subsequent step is to setup the exams themselves.
For that we’ll delegate a lot of the work to the library wp-media/phpunit which gonna setup and reset the surroundings for us.
The primary to make use of wp-media/phpunit is to put in the library by operating the next command:
composer i wp-media/phpunit --dev
wp-launchpad/phpunit-wp-hooks
Within the WordPress ecosystem integration exams mocking filters is one thing actually frequent resulting from that it’s actually essential to ensure that operation is the much less verbose as potential.
The library wp-launchpad/phpunit-wp-hooks is completed to scale back the quantity of code to work together with a filter.
To put in that library that library you should run the next command:
composer i wp-launchpad/phpunit-wp-hooks --dev
As soon as that is performed the library is put in it’s now time to create base lessons for exams.
Make the bottom
Step one might be to create the namespace contained in the composer.json file from the mission by including the next code inside:
"autoload-dev": {
"psr-4": {
"MyPlugin\\Tests\\Integration\\": "Integration/"
}
},
If it’s not the case contained in the mission we must create a brand new folder exams and inside that folder one other one named Integration.
Then the subsequent step is to create file init-tests.php contained in the Integration folder. The target from that file is to setup wp-media/phpunit library by indication the place from the testing folder:
<?php
/**
* Initializes the wp-media/phpunit handler, which then calls the rocket integration check suite.
*/
outline( 'WPMEDIA_PHPUNIT_ROOT_DIR', dirname( __DIR__ ) . DIRECTORY_SEPARATOR );
outline( 'WPMEDIA_PHPUNIT_ROOT_TEST_DIR', __DIR__ );
require_once WPMEDIA_PHPUNIT_ROOT_DIR . 'vendor/wp-media/phpunit/Integration/bootstrap.php';
outline( 'WPMEDIA_IS_TESTING', true ); // Utilized by wp-media/.
As soon as that is performed then we have to create one other file bootstrap.php which gonna setup preliminary surroundings for our exams:
<?php
namespace MyPlugin\Exams\Integration;
outline( 'MY_PLUGIN_PLUGIN_ROOT', dirname( dirname( __DIR__ ) ) . DIRECTORY_SEPARATOR );
outline( 'MY_PLUGIN_TESTS_DIR', __DIR__ );
// Manually load the plugin being examined.
Lastly PHPUnit ought to be configured to execute the suite.
For that we must add the next content material into phpunit.xml.dist :
<?xml model="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" bootstrap="init-tests.php" backupGlobals="false" colours="true" beStrictAboutCoversAnnotation="false" beStrictAboutOutputDuringTests="true" beStrictAboutTestsThatDoNotTestAnything="true" beStrictAboutTodoAnnotatedTests="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" verbose="true">
<protection includeUncoveredFiles="true">
<embody>
<listing suffix=".php">../../inc</listing>
</embody>
</protection>
<testsuites>
<testsuite identify="integration">
<listing suffix=".php">inc</listing>
</testsuite>
</testsuites>
</phpunit>
Lastly we must create a base TestCase class.
It is going to be used to include logic which might be frequent to every of our exams.
For that we’ll add the next content material into TestCase.php the place my_prefix is your plugin prefix:
namespace MyPlugin\Exams\Integration;
use WPMedia\PHPUnit\Integration\TestCase as BaseTestCase;
use WPLaunchpadPHPUnitWPHooks\MockHooks;
summary class TestCase extends BaseTestCase
{
use MockHooks;
public operate set_up()
dad or mum::set_up();
$this->mockHooks();
public operate tear_down()
operate getPrefix(): string
{
return 'my_prefix';
}
operate getCurrentTest(): string
{
return $this->getName();
}
}
Lastly the final step is so as to add the script to launch integration exams inside composer.json :
"test-integration": "\"vendor/bin/phpunit\" --testsuite integration --colors=always --configuration tests/Integration/phpunit.xml.dist --exclude-group AdminOnly,,",
And add the script to run the earlier script inside package deal.json the place my_plugin is the identify from the listing out of your plugin:
"integration": "wp-env run cli --env-cwd=wp-content/plugins/my_plugin composer run test-integration",
It’s now potential execute the exams by operating the next command:
npm run integration
If the whole lot goes effective you must have the next output:
> integration
> wp-env run cli --env-cwd=wp-content/plugins/my_plugin composer run test-integration
ℹ Beginning ‘composer run test-integration’ on the cli container.
> “vendor/bin/phpunit” –testsuite integration –colors=at all times –configuration exams/Integration/phpunit.xml.dist
Putting in…
Operating as single web site… To run multisite, use -c exams/phpunit/multisite.xml
Not operating ajax exams. To execute these, use –group ajax.
Not operating ms-files exams. To execute these, use –group ms-files.
Not operating external-http exams. To execute these, use –group external-http.
PHPUnit 9.6.17 by Sebastian Bergmann and contributors.
Runtime: PHP 8.2.15
Configuration: exams/Integration/phpunit.xml.dist
No exams executed!
✔ Ran `composer run test-integration` in ‘cli’. (in 5s 632ms)
Course of completed with exit code 0
Use fixtures
To completely perceive the significance of fixtures you possibly can test my earlier article about unit exams the place I already defined some great benefits of utilizing them.
On this article I’ll present find out how to make your exams appropriate with fixtures and this time it’s even easier than with unit exams as wp-media/phpunit is dealing with part of the complexity for us.
The primary half might be so as to add the Fixture folder contained in the exams folder.
Then the second half might be so as to add the logic to load fixtures contained in the TestCase class:
namespace MyPlugin\Exams\Integration;
use WPMedia\PHPUnit\Integration\TestCase as BaseTestCase;
use WPLaunchpadPHPUnitWPHooks\MockHooks;
summary class TestCase extends BaseTestCase
{
use MockHooks;
protected $config;
public operate set_up() {
dad or mum::set_up();
if ( empty( $this->config ) ) {
$this->loadTestDataConfig();
}
$this->mockHooks();
}
public operate tear_down()
public operate getPrefix(): string
{
return 'my_prefix';
}
public operate getCurrentTest(): string
{
return $this->getName();
}
public operate configTestData() {
if ( empty( $this->config ) ) {
$this->loadTestDataConfig();
}
return isset( $this->config['test_data'] )
? $this->config['test_data']
: $this->config;
}
protected operate loadTestDataConfig() {
$obj = new ReflectionObject( $this );
$filename = $obj->getFileName();
$this->config = $this->getTestData( dirname( $filename ), basename( $filename, '.php' ) );
}
}
As soon as this code is added then you’re free to create your fixture contained in the Fixtures folder and use them inside your exams.
Now that your surroundings for integration exams is setup it’s now time to put in writing your first integration check.