PHP: PHPUnit

PHPUnit is the official testing framework chosen by the coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. team to test our PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher code.

Setup Setup

1. Install PHPUnit. WordPress uses PHPUnit, the standard for unit testing PHP projects. Installation instructions can be found in the PHPUnit manual or on the PHPUnit Github repository. Note: The latest release of PHPUnit is 8.x, WordPress is currently only compatible with the 7.x release tree. Until #46149 is merged, the latest PHPUnit 7.x release should be used:

wget https://phar.phpunit.de/phpunit-7.5.9.phar
chmod +x phpunit-7.5.9.phar
sudo mv phpunit-7.5.9.phar /usr/local/bin/phpunit
phpunit --version
Note: On Windows and having trouble? Check out this guide and add support for ANSI Command Line Colors under Windows.

Note: Multibyte String support (php-mbstring) needs to be installed to run PHPUnit tests.

2. Check out the test repository. The WordPress tests live in the core development repository, available via SVN at:

svn co https://develop.svn.wordpress.org/trunk/ wordpress-develop cd wordpress-develop

Or Git:

git clone git://develop.git.wordpress.org/ wordpress-develop
cd wordpress-develop


3. Create an empty MySQL database. The test suite will delete all data from all tables for whichever MySQL database it is configured. Use a separate database.

4. Set up a config file. Copy wp-tests-config-sample.php to wp-tests-config.php, and enter your database credentials. Use a separate database.

Top ↑

Running the Test Suite Running the Test Suite

Note that the tests run from the build folder, so you need to build before testing, and run build watch to keep the build updated when testing changes.

First ensure Node is installed (which includes npm). In the root directory – next to the tests folder  – run:

npm install

Grunt build or watch to sync changes from src to build:

npm run grunt build
npm run grunt watch

Finally, to run the tests:

phpunit


You should see output that looks roughly like the following:

....................................................SS.....SS 61 / 1303 ( 4%)
...SSSSSS.............S..SSS..........SS................S.... 122 / 1303 ( 9%)
..................................S.......................... 183 / 1303 ( 14%)
..................S............S.................S.......S... 244 / 1303 ( 18%)
.............S.......S.S.......S............................. 305 / 1303 ( 23%)
....SSSS.S..SSS.........S.SS................................. 366 / 1303 ( 28%)
............................................................. 427 / 1303 ( 32%)
............................................................. 488 / 1303 ( 37%)
............................................................. 549 / 1303 ( 42%)
......................................................S...... 610 / 1303 ( 46%)
...................SS............SS.......................... 671 / 1303 ( 51%)
..............SS.....................S....................... 732 / 1303 ( 56%)
.............SSS..SSSSSSS.................................... 793 / 1303 ( 60%)
SS.........SSSS.SS........................................... 854 / 1303 ( 65%)
....................................S........................ 915 / 1303 ( 70%)
..........................S..S................SS.S........... 976 / 1303 ( 74%)
..........................................S.............S.... 1037 / 1303 ( 79%)
............................................................. 1098 / 1303 ( 84%)
............................................................. 1159 / 1303 ( 88%)
.....S.................S..................................... 1220 / 1303 ( 93%)
.....................................S 

Time: 02:24, Memory: 119.75Mb 
OK, but incomplete or skipped tests! 
Tests: 1258, Assertions: 5219, Skipped: 74. 

What each symbol means:

  • . – Each dot signifies one “test” that passed.
  • S means a test was skipped. This usually means that the test is only valid in certain configurations, such as when a test requires Multisite.
  • F means a test failed. More output will be shown for what exactly failed and where.
  • E means a test failed due to a PHP error, warning, or notice.
  • I means a test was marked as incomplete.

Running Specific Tests Running Specific Tests

Individual Tests Individual Tests

To run an individual class, you can use the name of the class, prefixed with tests_phpunit:

phpunit tests_phpunit_Tests_Dependencies_Styles

To run an individual file, you can use the full path to the file:

phpunit tests/phpunit/tests/dependencies/styles.php

Top ↑

Groups Groups

To run a group of tests – defined by @group in code comments:

phpunit --group dependencies
phpunit --group themes

You may also combine groups: (Depending on your platform you may have to wrap the groups in double quotes)

phpunit --group shortcode,17657,6562,14050
ests: 37, Assertions: 77, Failures: 5.

To view all groups:

phpunit --list-groups

Many tests are marked with a @ticket annotation, which indicates they were the result of that WordPress Trac ticket. The test is skipped if the ticket is still open – in these cases, we treat the test as a “known bug” that will likely fail.

To forcibly run the skipped tests for an open ticket, you may specify that ticket as a group:

phpunit --group 17657 
Tests: 2, Assertions: 3, Failures: 2.

To see information about skipped and incomplete tests, use --verbose:

phpunit --group shortcode
Tests: 37, Assertions: 71, Skipped: 5.

phpunit --group shortcode --verbose 
There were 5 skipped tests: 
1) Tests_Shortcode::test_tag_hyphen_not_tag 
WordPress Ticket 17657 is not fixed 

tests/includes/testcase.php:150 
tests/includes/testcase.php:130

By default, the AJAX tests (tests written for core’s use of wp-admin/admin-ajax.php) are not run. To run these:

phpunit --group ajax

To run the tests under multisite, you must switch to the multisite.xml configuration file:

phpunit -c tests/phpunit/multisite.xml

Top ↑

With Grunt With Grunt

Additionally, you can npm run grunt phpunit and run PHPUnit tests, including the ajax and multisite tests.

Top ↑

Running Continuously Running Continuously

Rather than having to switch to a terminal and manually run a test group repeatedly while working on a patch, you can keep it running continuously. Whenever you save any file, the group will run again automatically. This lets you instantly know when a change you’ve made breaks a test, or causes it to pass.

To run PHPUnit tests and all other watch tasks, use:

npm run grunt watch -- --phpunit --group={testgroup}

To run only the PHPUnit watch task, use:

npm run grunt watch:phpunit -- --group={testgroup}

Run multiple groups by comma-separating them:

npm run grunt watch:phpunit -- --group=community-events,privacy

Top ↑

Optimizing Optimizing

You can speed up the suite in some cases by defining the WP_TESTS_SKIP_INSTALL environment variable to 1, so that the suite will skip the install step. While this shouldn’t be used for full test runs, it’s useful for saving time when running small groups of tests.

WP_TESTS_SKIP_INSTALL=1 phpunit --group=privacy

Top ↑

Writing Tests Writing Tests

We’ve written a guide for getting started writing PHPUnit tests for WordPress.

Top ↑

Contributing Tests to WordPress Contributing Tests to WordPress

There are three primary ways to contribute:

Write tests for a reported bug. A great way to contribute is to write tests that demonstrate an existing bug report. The core developers are reluctant to consider patches for many sensitive areas in core without test coverage. Well-written tests can help confirm that a patch fixes a problem without side effects, and can prevent any regressions from occurring in the future. When tests are particularly needed or desired for a ticket to proceed, they receive the needs-unit-tests workflow keyword. You can submit tests for existing tickets directly on the WordPress core Trac. Bonus points for submitting a bug report with a test case included.

Write new tests to improve our code coverage. Many areas of WordPress do not have adequate test coverage. Pick a function, class, or component and write tests for it. You can submit these tests on the WordPress Trac.

Fix or improve our existing test cases. There are many opportunities for improvement in the existing tests. Some of them are ancient and others are slow or fragile. Some do not tests well in multisite or under certain conditions. Some individual tests try to test too much, and could be improved by using data providers, dependencies, and more narrow assertions.

Top ↑

JavaScript Unit Tests JavaScript Unit Tests

Unit tests for JavaScript code are currently much more limited in WordPress Core in comparison to PHP unit tests. For more information on JS unit tests, see the Make/Core post or the QUnit section of this Handbook.

Top ↑

Further Reading Further Reading

Last updated: