Activation tests
The Activation test type performs basic operations on a test site with your plugin activated. It simulates essential workflows that a merchant might perform, ensuring your plugin behaves correctly throughout the entire process, from activation to order placement and deactivation.
Operations performed
- Log in as admin
- Activate any dependencies that your plugin has (e.g., WooCommerce)
- Activate your plugin
- Check that your plugin does not break common requests across the site (see Hook resilience check)
- Visit and take screenshots of any pages added by your plugin to the wp-admin menu
- Enable Cash on Delivery payment method
- Enable Local Pickup shipping method
- Create a product
- Create an order
- Add a product to cart
- Place an order as a guest
- Deactivate your plugin
Test outcomes
The status of the test is determined by the following:
- Success: All flows were completed, and no PHP notices, warnings, or errors were triggered.
- Warning: All flows were completed, but a non-fatal PHP error was triggered.
- Failed: One of the flows failed, a fatal PHP error was triggered, or the hook resilience check failed.
Hook resilience check
For plugins, the Activation test checks that activating your plugin doesn't break requests unrelated to it. It runs by default, and a failure fails the test.
The typical cause is a hook callback with a strict PHP type that another plugin can legally violate. For example, a rest_pre_serve_request callback declaring bool $served throws a TypeError when another callback returns null, and that breaks REST requests across the site.
Before and after activating your plugin, QIT requests the front page, wp-admin, several REST endpoints and the WooCommerce settings screen, and sends an email through wp_mail() that is never delivered. It also makes rest_pre_serve_request return null, and pre_http_request and rest_authentication_errors return a WP_Error, so make sure your callbacks on those hooks accept these values.
The Verify global request resilience step reports one of these results:
QIT_ACTIVATION_SMOKE_PASSED: every request still works after activation.QIT_ACTIVATION_SMOKE_REGRESSION: after activation, a request hit a PHP fatal error, an HTTP 5xx or another unexpected response. Failures markedsut-attributedhave your plugin's files in the error or its stack trace.QIT_ACTIVATION_SMOKE_BASELINE_INVALID: QIT couldn't get a reliable reading. If every failure is in thebaselineround, the site was unhealthy before your plugin was activated: run the test again, and email qit@woocommerce.com if it persists. Failures in thepost_activationround can mean your plugin brokeadmin-ajax.phpor the REST API.
When the check fails, the steps after it are skipped. The failing requests and PHP errors are in that step of the detailed test report linked from the test summary.
Request footprint
The request footprint is not part of the Activation test: QIT measures it alongside the test, for plugins, and it never changes the result. It appears as the Request footprint section of the test report.
It shows what your plugin does on three requests where it should do almost nothing: /wp-admin/admin-ajax.php?action=rest-nonce, /wp-admin/profile.php and the front page. For each one you get the database queries, writes and outbound HTTP calls your plugin made, and the main hooks and lines behind them. Use it to find work that runs on every request but only needs to run on a few, such as queries on admin_init that also run on every AJAX request.
The site is a clean store with no object cache, so code that only runs once your plugin is configured isn't measured.
Configurable options
You can tweak several parameters in the Activation Test, such as WordPress, WooCommerce, and PHP versions. To see all available options, run:
qit run:activation --help
This command displays a list of configurable parameters, enabling you to test under various conditions.
Skipping visited pages
If you want the Activation test to skip specific pages added by your plugin, add a qit.json file to your plugin's root directory (the same directory as your plugin entrypoint) with the following content:
{
"activation": {
"skipVisitPages": [
"wp-admin/admin.php?page=skip-visiting-this"
]
}
}
- Automatic page discovery: By default, the test suite visits all pages accessible from the WordPress admin sidebar menu that are added by your plugin.
- Skipvisitpages array: The
skipVisitPagesarray specifies the URLs of pages you want to exclude from visits during the tests. - Substring matching: The skipping mechanism is substring-based. If any part of a page's URL contains a string listed in
skipVisitPages, that page will not be visited.
For example, if you include wp-admin/admin.php?page=skip-visiting-this in the array, any admin page URL containing that substring will be skipped.
Visiting a specific page
You can also define specific pages to be visited that might not be visible from the sidebar menu. This uses a slightly different syntax, as it takes a page title and a URL. It only accepts relative URLs.
{
"activation": {
"visitPages": {
"Visit This": "wp-admin/admin.php?page=do-visit-this"
}
}
}
Running the activation test
Run the activation test with:
qit run:activation your-extension
Replace your-extension with the slug of your plugin.
Using a tunnel
Some plugins might need an actual live site URL to work properly, such as payment gateways and SaaS. For those, you can use our built-in tunnel feature to test these plugins.
Canonical compatibility check in the WooCommerce Marketplace
The WooCommerce Marketplace will automatically run an activation test using the compatibility extension set upon new submission or update. You will see the results in the list of tests under Activation (canonical compatibility check).
What to do if it fails
If your Activation test fails:
- Open the test report to review logs and identify the root cause.
- Identify the causes of failure. The test will log PHP notices, warnings, and errors that happens when activating your plugin.
- If the Verify global request resilience step failed, see Hook resilience check for what its result means and where to find the failing requests.
- Reproduce the issue locally and fix it in your code.
- If you believe the result is incorrect, please email us at qit@woocommerce.com for further assistance.
CLI Usage
Run activation tests
run:activation [options] [--] [<sut> [<passthrough>...]]
Arguments:
sut Extension identifier: plugin/theme slug or WooCommerce.com ID
passthrough Arguments after --
--profile[=PROFILE] Test profile to use [default: "default"]
-e, --environment[=ENVIRONMENT] Pick an environment block from qit.json (e.g. --environment=legacy) [default: "default"]
--zip[=ZIP] Custom source for the plugin/theme (local ZIP, local directory, or URL to a .zip file)
--source[=SOURCE] [Deprecated] Use --zip instead
--async|--no-async Enqueue test and return immediately without waiting
-w, --wait|--no-wait (Deprecated) Wait for test completion - this is now the default behavior
--passthrough_target[=PASSTHROUGH_TARGET] Test packages that should receive passthrough arguments (multiple allowed) (multiple values allowed)
--test-package[=TEST-PACKAGE] Test packages to include (multiple values allowed) (multiple values allowed)
--php_version[=PHP_VERSION] PHP version (e.g., 8.2, 8.3). Alias: --php [default: "8.2"]
--wordpress_version[=WORDPRESS_VERSION] WordPress version (stable, rc, 6.6). Alias: --wp [default: "stable"]
--woocommerce_version[=WOOCOMMERCE_VERSION] WooCommerce version. Alias: --woo
-p, --plugin[=PLUGIN] Additional plugins (multiple values allowed)
-t, --theme[=THEME] Additional themes (multiple values allowed)
--volume[=VOLUME] Volumes (host:container) (multiple values allowed)
-x, --php_extension[=PHP_EXTENSION] PHP extensions (multiple values allowed)
-o, --object_cache Enable Redis object cache
--xdebug[=XDEBUG] Enable Xdebug (mode=debug by default, or specify: profile, trace, debug,develop, etc.) [default: false]
--tunnel[=TUNNEL] Enable tunnelling (cloudflare, ngrok) [default: "no_tunnel"]
--offline Override: Force offline mode - will error if any test requires network
--online Override: Force online mode - enable network regardless of test requirements
--env[=ENV] Set env var --env KEY=VAL (multiple values allowed)
--env_file[=ENV_FILE] Load vars from file --env_file ./prod.env (multiple values allowed)
-j, --json Machine‑readable JSON output
-s, --skip_activating_plugins Skip activating plugins
--notify Notify on failures
-g, --group|--no-group Register into a group
--print-report-url Print the test report URL (contains sensitive data - use cautiously in public logs)
--ui Run tests in Playwright UI mode
--keep-env Keep the environment running after tests complete (for debugging with Playwright MCP)
--extension_set[=EXTENSION_SET] (Optional) The predefined set of extensions to include in the test. [possible values: compatibility]
-st, --skip_activating_themes Skip activating themes