If you are developing plugins for WordPress, one of the pain points I’ve struggled with is getting tests running. In the future, I need to document getting javascript tests running. Today, I’m going to outline the method for running phpunit tests. I will also discuss several problems I encountered along the way.
First: use @wordpress/env
This tool deserves a post all on it’s own but long story short, it allows a quick method to bootstrap a local development environment using docker. After installation it’s available as wp-env or npx wp-env (and I’ll be using the shorter version in this post).
The most basic “working” version of this is a .wp-env.json file in your plugin directory that looks like:
{
"plugins": [ "." ]
}Code language: JSON / JSON with Comments (json)
Launch the environment with wp-env start. (WordPress is downloaded and stored locally. Next it creates docker-compose file mapping several containers: wordpress, cli, mysql, tests-wordpress, tests-cli, and tests-mysql.
Second: use wp-cli to create the scaffolded plugin-tests
> wp-env run tests-cli wp scaffold plugin-tests $(basename $(pwd))
Success: Created test files.
✔ Ran `wp scaffold plugin-tests sample-plugin` in 'tests-cli'. (in 24s 436ms)Code language: Shell Session (shell)
The above command creates a bunch of files that aren’t technically necessary and you can remove them (e.g. .circleci, bin/install-wp-tests.sh, .phpcs.xml.dist).
By passing the --ci parameter you can change the continuous integration provider. With wp-env you’ll need to add -- --ci=github.
Third: get it running
In theory you should be able to run wp-env run tests-cli phpunit, but that runs in the wrong directory. Solution: pass the current working directory.
> wp-env run tests-cli --env-cwd=wp-content/plugins/sample-plugin phpunit
ℹ Starting 'phpunit' on the tests-cli container.
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.
✖ Command failed with exit code 1
Command failed with exit code 1Code language: Shell Session (shell)
Whoops, it looks like some libraries are missing. Let’s add them.
composer require --dev yoast/phpunit-polyfillsCode language: JavaScript (javascript)
That installs the library, but also gives us a version of phpunit we need to use to ensure they are loaded. With that slight change we see:
> wp-env run tests-cli --env-cwd=wp-content/plugins/sample-plugin vendor/bin/phpunit
ℹ Starting 'vendor/bin/phpunit' on the tests-cli container.
Installing...
Running as single site... To run multisite, use -c tests/phpunit/multisite.xml
[03-Oct-2024 18:17:14 UTC] PHP Warning: Class "PHPUnit\Framework\Error\Deprecated" not found in /wordpress-phpunit/includes/phpunit6/compat.php on line 8
[03-Oct-2024 18:17:14 UTC] PHP Warning: Class "PHPUnit\Framework\Error\Notice" not found in /wordpress-phpunit/includes/phpunit6/compat.php on line 9
[03-Oct-2024 18:17:14 UTC] PHP Warning: Class "PHPUnit\Framework\Error\Warning" not found in /wordpress-phpunit/includes/phpunit6/compat.php on line 10
[03-Oct-2024 18:17:14 UTC] PHP Warning: Class "PHPUnit\Framework\Warning" not found in /wordpress-phpunit/includes/phpunit6/compat.php on line 12
[03-Oct-2024 18:17:14 UTC] PHP Warning: Class "PHPUnit\Framework\TestListener" not found in /wordpress-phpunit/includes/phpunit6/compat.php on line 15
Not running ajax tests. To execute these, use --group ajax.
Not running ms-files tests. To execute these, use --group ms-files.
Not running external-http tests. To execute these, use --group external-http.
PHPUnit 11.3.6 by Sebastian Bergmann and contributors.
Runtime: PHP 8.2.24
Configuration: /var/www/html/wp-content/plugins/sample-plugin/phpunit.xml.dist
No tests executed!
✔ Ran `vendor/bin/phpunit` in 'tests-cli'. (in 1s 34ms)Code language: Shell Session (shell)
Why weren’t any tests run?
Because WordPress doesn’t like the latest version of phpunit. Let’s change it with composer require -W --dev phpunit/phpunit ^9.6
> wp-env run tests-cli --env-cwd=wp-content/plugins/sample-plugin vendor/bin/phpunit
ℹ Starting 'vendor/bin/phpunit' on the tests-cli container.
Installing...
Running as single site... To run multisite, use -c tests/phpunit/multisite.xml
Not running ajax tests. To execute these, use --group ajax.
Not running ms-files tests. To execute these, use --group ms-files.
Not running external-http tests. To execute these, use --group external-http.
PHPUnit 9.6.21 by Sebastian Bergmann and contributors.
No tests executed!
✔ Ran `vendor/bin/phpunit` in 'tests-cli'. (in 1s 32ms)Code language: Shell Session (shell)
Still no tests… 🤔
Oh! the phpunit.xml.dist is excluding the only test. Remove that line:
--- phpunit.xml.dist 2024-10-03 11:28:06.212985211 -0700
+++ 2phpunit.xml.dist 2024-10-03 11:28:39.641072205 -0700
@@ -1,16 +1,15 @@
<?xml version="1.0"?>
<phpunit
bootstrap="tests/bootstrap.php"
backupGlobals="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
>
<testsuites>
<testsuite name="testing">
<directory prefix="test-" suffix=".php">./tests/</directory>
- <exclude>./tests/test-sample.php</exclude>
</testsuite>
</testsuites>
</phpunit>Code language: Diff (diff)
And success! 🎉
> wp-env run tests-cli --env-cwd=wp-content/plugins/sample-plugin vendor/bin/phpunit
ℹ Starting 'vendor/bin/phpunit' on the tests-cli container.
Installing...
Running as single site... To run multisite, use -c tests/phpunit/multisite.xml
Not running ajax tests. To execute these, use --group ajax.
Not running ms-files tests. To execute these, use --group ms-files.
Not running external-http tests. To execute these, use --group external-http.
PHPUnit 9.6.21 by Sebastian Bergmann and contributors.
Test 'SampleTest::test_sample' started
Test 'SampleTest::test_sample' ended
Time: 00:00.021, Memory: 38.50 MB
OK (1 test, 1 assertion)
✔ Ran `vendor/bin/phpunit` in 'tests-cli'. (in 0s 927ms)Code language: Shell Session (shell)
Other investigations/changes
- phpunit 10 changes the way it finds tests. In the future, the file name and the class will need to agree (e.g. rename file to
SampleTest.phpand changephpunit.xml.distto find files like*Test.php). - WordPress needs to update its support of
phpunittoo. - If you are using a javascript build process:
- Add
@wordpress/envas a development requirement. - Add a
scriptto yourpackage.jsonto run tests:"test": "wp-env run tests-cli --env-cwd=wp-content/plugins/sample-plugin vendor/bin/phpunit" - Now you can just run
npm test!
- Add
- Need more investigation about using
wp-envin continuous integration environment.
Fin
As of October 3, 2024, these steps worked on getting an up-to-date sample plugin running phpunit tests using wp-env.
