Writing PHP Unit tests is a good practice to help developers identify the bugs and fix them in the development environment before going to production. It’s a good practice to write unit tests for your WordPress plugin as well. However, setting up a PHP Unit Test environment isn’t as easy as you’d like. These are the issues I encountered while setting up and writing PHP Unit Tests for WordPress plugins.

Issue 1 – The PHPUnit Polyfills library is a requirement

Issue 2 – Path to WordPress codebase on Windows

Issue 3 – Fatal error: Declaration of WP_UnitTestCase_Base::setUpBeforeClass() must be compatible with PHPUnit\Framework\TestCase::setUpBeforeClass(): void

Issue 4 – Could not find /tmp/wordpress-tests-lib/includes/functions.php

Issue 5 – wp scaffold plugin-tests command fails silently.

Issue 6 – Error: The following required constants are not defined: WP_TESTS_DOMAIN, WP_TESTS_EMAIL…

PHPUnit Tests Configuration For WordPress Plugins

Before writing about the issues, I’ll review the configuration/requirements.

1) Installing PHPUnit globally

composer global require phpunit/phpunit:8.*

We’re installing PHPUnit 8 dot latest. Run phpunit --version to confirm it’s been installed.

2) Installing WP-CLI globally

I’ll assume that WP-CLI is already installed. Follow the official documentation if it isn’t installed already.

That’s all we’ll need globally.

3) Creating tests files for the plugin

From the WordPress root directory run the following command. Note that ‘wp-force-logout’ is the plugin slug. Replace it with yours.

wp scaffold plugin-tests wp-force-logout

4) Creating a WordPress instance to test against

From the plugin’s root directory run the following command. Note that wordpress_test is the database name you’ll want to create, root is the DB username, empty DB password, localhost is the DB_HOST, and 5.8 is the WordPress version we’re installing.

bin/install-wp-tests.sh wordpress_test root '' localhost 5.8

That’s all. Now when we run the command phpunit from the plugin’s root directory. The tests should be performed for the test file tests/test-sample.php of the plugin directory at the minimum. To write your tests, there’s documentation in WordPress handbook. You might also want to look at writing PHPUnit tests for Custom Post Types REST API endpoint.

Now into the main topic, the issues when running the command phpunit which should actually run the tests but isn’t to be.

Issue 1

Error: The PHPUnit Polyfills library is a requirement for running the WP test suite.
If you are trying to run plugin/theme integration tests, make sure the PHPUnit Polyfills library (https://github.com/Yoast/PHPUnit-Polyfills) is available and either load the autoload file of this library in your own test bootstrap before calling the WP Core test bootstrap file; or set the absolute path to the PHPUnit Polyfills library in a "WP_TESTS_PHPUNIT_POLYFILLS_PATH" constant to allow the WP Core bootstrap to load the Polyfills.

If you are trying to run the WP Core tests, make sure to set the "WP_RUN_CORE_TESTS" constant to 1 and run composer install before running the tests.
Once the dependencies are installed, you can run the tests using the Composer-installed version of PHPUnit or using a PHPUnit phar file, but the dependencies do need to be installed whichever way the tests are run.


Fix

PHPUnit Polyfills library is now required by WordPress tests. This is because it helps to fix the version compatibility issues we often face with WordPress. Here are more details if you’d like to check.

To fix the issue, add a PHPUnit Polyfills library in the plugin. Here’s one of the methods to add which is in composer.json

"require-dev":{
      "yoast/phpunit-polyfills" : "1.0.3"
},

Enter composer update to save the changes. Once the PHPUnit Polyfills library is available, load it. There are several methods as described in the error message above. I’ve included it in the plugin’s tests directory.

your-plugin/tests/bootstrap.php, in the first line, include this library:

require dirname( dirname( __FILE__ ) ) . '/vendor/yoast/phpunit-polyfills/phpunitpolyfills-autoload.php';


Issue 2

Warning: require_once(/tmp/wordpress/wp-includes/PHPMailer/PHPMailer.php): failed to open stream: No such file or directory in C:\Users\dell\AppData\Local\Temp\wordpress-tests-lib\includes\mock-mailer.php on line 2

Fatal error: require_once(): Failed opening required ‘/tmp/wordpress/wp-includes/PHPMailer/PHPMailer.php’ (include_path=’.;C:/laragon/etc/php/pear’) in C:\Users\dell\AppData\Local\Temp\wordpress-tests-lib\includes\mock-mailer.php on line 2


Fix

If you’re on windows, go to C:\Users\{user}\AppData\Local\Temp\wordpress-tests-lib\wp-tests-config.php

In line 4, after the comment:

/* Path to the WordPress codebase you’d like to test. Add a forward slash in the end. */

define( 'ABSPATH', '/tmp/wordpress/' );


Change the absolute path to C:\Users{User}\AppData\Local\Temp/wordpress/ or to any of your WordPress root directory. So, that it will be:

define( 'ABSPATH', 'C:\Users\{name}\AppData\Local\Temp/wordpress/' );


Issue 3

Fatal error: Declaration of WP_UnitTestCase_Base::setUpBeforeClass() must be compatible with PHPUnit\Framework\TestCase::setUpBeforeClass(): void in C:\Users\{name}\AppData\Local\Temp\wordpress-tests-lib\includes\abstract-testcase.php on line 15


Fix

This is a void conundrum. The PHP Polyfills should also fix this issue. But, if you’re still facing issues, check the version of WordPress, PHPUnit, PHPUnit Polyfills library, etc. or this is supposed to be fixed in WordPress 5.9. Here are the changes coming in WordPress 5.9 you might want to look at.


There’s also a famous core trac.


Issue 4

Could not find /tmp/wordpress-tests-lib/includes/functions.php, have you run bin/install-wp-tests.sh ?

Fix

Delete the wordpress-tests-lib folder from temp. In windows, generally, it would be something like C:/Users/{name}/AppData/Local/Temp/wordpress-tests-lib.

And then re-run

bin/install-wp-tests.sh wordpress_test root '' localhost 5.8


Issue 5

wp scaffold plugin-tests command does nothing, fails silently.

Fix

This is usually because of fatal errors within your site. To find out the errors, make sure you’ve turned on the error display in wp-config.php.

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'SAVEQUERIES', true );

define( 'WP_DEBUG_DISPLAY', true );

@ini_set( 'display_errors', 1 );
define( 'SCRIPT_DEBUG', true );

Once you enabled the error display, the fatal error will display while you enter the WP-CLI command instead of failing silently.

If you get errors like undefined add_action(), undefined add_filter(), double-check your wp-config.php file, it might have been poorly customized resulting in the error.


Issue 6

Error: The following required constants are not defined: WP_TESTS_DOMAIN, WP_TESTS_EMAIL, WP_TESTS_TITLE, WP_PHP_BINARY.

Fix

It is likely that the wp-tests-config.php is missing or is empty. If you’re on windows, go to C:\Users\{user}\AppData\Local\Temp\wordpress-tests-lib\wp-tests-config.php. If it’s missing or is empty, we’ll need to create a wp-tests-config.php file manually. Copy the contents from here and paste them in wp-tests-config.php. You can check your wp-config.php file for reference.

I hope you found this tutorial helpful! Have you encountered any other issues and have a fix? Let me know.

Common issues while setting up PHP Unit Tests for WordPress plugins
Tagged on:

Sanjeev Aryal

Don't bury your thoughts, put your vision into reality ~ Bob Marley.

7 thoughts on “Common issues while setting up PHP Unit Tests for WordPress plugins

  • October 8, 2023 at 4:02 pm
    Permalink

    This post was incredibly helpful. Just a note. In my case, the polyfills didn’t fix the void conundrum issues on Windows. I just needed to do add void as return type for the setUp method, replacing:

    protected function setUp() {
    parent::setUp();
    // …
    }

    For this:

    protected function setUp(): void {
    parent::setUp();
    // …
    }

    An the same for the tearDown methods.

    Reply
    • September 23, 2023 at 7:59 pm
      Permalink

      Not understanding what you wrote down for that error, It needs more explanation on the setup, are we supposed to create a file wp-tests-config.php and put it somewhere in the app (for example the root directory of a plugin)? And are the contents supposed to be the exact same of the wp-config.php thats in the tests folder of that example plugin?

      Reply
  • August 27, 2023 at 8:48 pm
    Permalink

    getting issue 4 function.php missing . trying to fix as you mentioned but not working.

    Reply
  • May 25, 2023 at 5:43 pm
    Permalink

    Thanks a lot Sanjeev! Was struggling with setting up tests. Not a lot of documentation available. And not a lot of plugins seem to have any tests haha

    Reply
  • February 2, 2022 at 4:58 am
    Permalink

    Hi Sanjeev,

    Thanks for taking the time to share these fixes!

    I was struggling with Issue 1 and your second step of including it in your-plugin/tests/bootstrap.php fixed it for me.

    Thanks!
    Nathan

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

× WhatsApp