Setting up for WP Unit Tests with NPM & WP-ENV

In this lesson, we’ll learn how to set up WP PHPUnit testing using wp-env which doesn’t require additional Test DB setup. This will help you understand what is happening under the hood.

For a standard/typical setup guide please follow:

We will use the following tools:

  • Composer
  • NPM
  • Docker (Internally)
  • wp-env

Let’s get started.

The following code is the minimum files/code required to run the WP PHP Unit tests.

Note: We don’t have to download the WordPress-develop repo for this setup.

Install wp-env

Follow the guide to install the https://developer.wordpress.org/block-editor/reference-guides/packages/packages-env/

Composer setup

  • Step 1
    • Create composer.json file
    • Add in basic details
  • Step 2
    • Add classmap autoload for your plugin src files
    • Add classmap autoload-dev for your test directory files.
{
  "name": "namespace/plugin-name",
  "require-dev": {
    "phpunit/phpunit": "^8.5",
    "wp-phpunit/wp-phpunit": "^5.9",
    "yoast/phpunit-polyfills": "^1.0"
  },
  "autoload": {
    "classmap": ["inc/"]
  },
  "autoload-dev": {
    "classmap": ["tests/"]
  }
}

NPM Setup

The only dependency is @wordpress/env

Create the following script commands

"test:php": "wp-env run phpunit 'phpunit -c /var/www/html/wp-content/plugins/$(basename \"$PWD\")/phpunit.xml.dist --verbose'",
"wp-env": "wp-env"

Note: 

  • “wp-env run” is for starting/stopping the environment.
  • test:php for running PHPUnit tests
  • $(basename \\”$PWD\\”) might not work on Windows, you can use Git Bash to make it work on Windows
{
  "name": "plugin",
  "scripts": {
    "test:php": "wp-env run phpunit 'phpunit -c /var/www/html/wp-content/plugins/$(basename \"$PWD\")/phpunit.xml.dist --verbose'",
    "wp-env": "wp-env"
  },
  "devDependencies": {
    "@wordpress/env": "^4.9.0"
  }
}

Configure wp-env

In the plugin’s root folder create the .wp-env.json file, and add the following code.

You can change the ports according to your system’s availability of ports

{
  "core": null,
  "phpVersion": "7.4",
  "plugins": ["."],
  "themes": ["../../themes/yourthemedirectory/"],
  "port": 5888,
  "env": {
    "tests": {
      "port": 5889
    }
  }
}

For further details about the wp-env config please visit:
https://www.npmjs.com/package/@wordpress/env

Bootstrap file

We need to define a bootstrap file which loads the required files and functions

  • Create tests/php/unit directory
  • Create bootstrap.php in tests/php directory
  • Add the following code.
<?php
/**
* PHPUnit bootstrap file
*
* @package features-plugin-v2
*/

define( 'TESTS_PLUGIN_DIR', dirname( __FILE__, 2 ) );
define( 'WP_TESTS_PHPUNIT_POLYFILLS_PATH', dirname( TESTS_PLUGIN_DIR ) . '/vendor/yoast/phpunit-polyfills' );

// Determine correct location for plugins directory to use.
define( 'WP_PLUGIN_DIR', dirname( dirname( TESTS_PLUGIN_DIR ) ) );

define( 'WP_PHPUNIT__DIR', dirname( TESTS_PLUGIN_DIR ) . '/vendor/wp-phpunit/wp-phpunit/' );

// Load Composer dependencies if applicable.
if ( file_exists( dirname( TESTS_PLUGIN_DIR ) . '/vendor/autoload.php' ) ) {
    require_once dirname( TESTS_PLUGIN_DIR ) . '/vendor/autoload.php';
}

// Detect where to load the WordPress tests environment from.

$_test_root = WP_PHPUNIT__DIR;

require_once $_test_root . '/includes/functions.php';

/**
* Load plugin in test env.
*
* @return void
*/
function features_plugin_unit_test_load_plugin_file() {
    require_once dirname( TESTS_PLUGIN_DIR ) . '/you-plugin-init-file.php';
}

tests_add_filter( 'muplugins_loaded', 'features_plugin_unit_test_load_plugin_file' );

require $_test_root . '/includes/bootstrap.php';

Configure tests using phpunit.xml.dist

In the plugin’s root directory create phpunit.xml.dist and add the following configuration:

<phpunit
  bootstrap="tests/php/bootstrap.php"
  backupGlobals="false"
  colors="true"
  convertErrorsToExceptions="true"
  convertNoticesToExceptions="true"
  convertWarningsToExceptions="true"
>
  <testsuites>
    <testsuite name="unittest">
      <directory suffix="-test.php">./tests/php/unit</directory>
    </testsuite>
  </testsuites>
</phpunit>

Note:
For Mac users, you must add the below <php> tag element inside <phpunit> to run.

<php>
    <env name="WP_PHPUNIT__TESTS_CONFIG" value="/wordpress-phpunit/wp-tests-config.php"/>
</php>

Running the tests

After adding all the files, it’s time to run the tests. You can add test code in ./tests/php/unit folder.

The file structure/hierarchy can reflect your plugin’s source structure/hierarchy with *-test.php appended.

To start running tests:

  • Step 1: Start wp-env by using npm run wp-env start
    • This will create all the docker containers required
  • Step 2: Run npm run test:php
  • This will run all the tests in the tests/php/unit folder and that’s it. Your WP PHPUnit testing setup is ready to roll.

Output: