Jun 27, 2019
When do WordPress Unit Tests Run (At Which Hook?)
Writing unit tests for a WordPress plugin recently had me wondering:
When do WordPress unit tests run?
Meaning, at what point during the WordPress lifecycle are unit tests executed?
I ran some checks and determined that most of the action hooks that run during a typical WordPress page load are also run during unit testing, up to and including the posts_selection
hook. The wp
hook that comes after that is never reached.
List of Action Hooks that Run
Here is a full breakdown of which action hooks run when PHPUnit unit tests are executed. This list of hooks comes from WP’s Action Reference page.
The hooks shown with a strikethrough are never run, and those without a strikethrough are run.
muplugins_loaded
registered_taxonomy
registered_post_type
plugins_loaded
sanitize_comment_cookies
setup_theme
load_textdomain
after_setup_theme
auth_cookie_malformed
auth_cookie_valid
set_current_user
init
widgets_init
register_sidebar
wp_register_sidebar_widget
wp_default_scripts
wp_default_styles
admin_bar_init
add_admin_bar_menus
wp_loaded
parse_request
send_headers
parse_query
pre_get_posts
posts_selection
wp
…and no hooks fire after this point.
So with that knowledge, you can expect that:
- Code that is hooked to
plugins_loaded
/init
/etc. will be reflected in your unit tests. - Code hooked to a hook that is crossed out in the list above or something after
posts_selection
will not be reflected in your unit tests.
What About the Rest?
Unit Tests are meant to be used to test individual units (classes/methods/functions) of your code in isolation. In order to test functionality during the rest of the WordPress lifecycle, you can take a look at setting up end-to-end tests using Codeception.
How Did I Determine This?
A few people have asked about how I determined which hooks fire during unit tests. My method for doing so was pretty simple. I threw some constant definitions like this into the main file of a plugin I was unit testing:
add_action( 'plugins_loaded', function() {
define( 'PLUGINS_LOADED_RAN', true );
} );
…then threw some corresponding checks like this into one of my unit test methods:
echo defined('PLUGINS_LOADED_RAN') ? 'plugins_loaded ran' : 'plugins_loaded did NOT run';
Then depending on which of those messages printed to the command line when I ran phpunit
, I was able to tell whether or not each hook had been run. Give it a try if you like and please let me know if any updates to the list above need to be made. Thanks!