Run PHPUnit locally in your WordPress Plugin with DDEV
Tags: phpunit, wordpress, ddev, unittests
Published: 2024-06-27 17:16:49

While working with WordPress over the years, I have used multiple solutions for local developments, ranging from old XAMPP setups and transferring files with FTP on FileZilla to Docker custom environments. By the way, here is an [example of one of my Dockers](https://github.com/sarahcssiqueira/docker-wordpress) you can refer. 

Recently, I discovered DDEV. [DDEV](https://ddev.com/) is an open source tool for launching local web development environments that can be extended, version controlled, and shared across a team easily. With DDEV, we can **take advantage of a Docker workflow without Docker experience**. Cool right? Of course, it is important to know how docker works under the hood, and beginners should experiment with it. However, later on, why to reinvent the wheel? Give DDEV a chance, and you won't regret it.

Okay, I am digressing; the focus here is [PHPUnit](https://phpunit.de/index.html) for plugins. **As with many of my other articles, my goal is to create a reference for myself to use when I need it in the future.**

Given my [DDEV](https://ddev.com/) environment running, I also want to run tests locally in my projects, in this case a **WordPress plugin**.

Requirements:

- DDEV
- Docker
- PHP 8.3
- MySQL
- SVN
- git
- WP-CLI
- wget
- plugin-folder

The versions for **PHP, PHPUnit and PHP Code Coverage** I am using, were the compatible ones on the date I am writing this post, June 2024. To check compatibility with PHPUnit and PHP, [please refer to official documentation](https://phpunit.de/supported-versions.html).

First step is to install PHPUnit if it is not installed yet. There are multiple ways to do this, but I choose to do it per project, through Composer with the following command in the plugin root folder:

`composer require --dev phpunit/phpunit ^9.5`

Also, will need those dependencies:

`composer require --dev phpunit/php-code-coverage ^9.2`

Remembering proper unit tests for a plugin or theme would not load WordPress. By loading WordPress those will be integration tests. 

That said, to generate the plugin test files, run on your plugin root folder:

`ddev exec wp scaffold plugin-tests your-plugin-name`

While working in a DDEV environment, don't forget to use **ddev exec** before **wp cli** commands.

Next, run the install script (which will require **wget**):

`bash bin/install-wp-tests.sh wordpress_test root '' localhost latest`

The script above first installs a copy of WordPress in the /tmp directory (by default) as well as the WordPress unit testing tools. Then it creates a database to be used while running tests. More details [here](https://make.wordpress.org/cli/handbook/misc/plugin-unit-tests/#2-generate-the-plugin-test-files).

_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 update -W` 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._

To fix the error above, install:

`composer require --dev yoast/phpunit-polyfills *`

Edit the **./tests/bootstrap.php** file created with the previous scaffold step, in order to require this file:

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

**Start to write your tests!**
         
Run tests by using `./vendor/bin/phpunit filename` or register a Composer script, as I did: 

`"scripts": {
    "test": "vendor/bin/phpunit"
  }, `

Now, I can simply run `composer test filename` and that's it!