WordPress Automated Testing with Playwright and PHPUnit: A Practical Start
How to add automated testing to a WordPress site with Playwright and PHPUnit: what to test first, the official tools, example tests and running them on updates.
WordPress automated testing means writing small programs that check your site still works, then running them every time something changes. The two main tools are PHPUnit, which tests your PHP code directly, and Playwright, which drives a real browser to test what visitors actually do. Start with a few Playwright tests for your most important pages and forms, then add PHPUnit tests around your custom code.
This guide explains what each tool does, what to test first, and how to set them up with the official WordPress tools.
Why automated tests matter for WordPress sites
A typical WordPress site runs WordPress core, a theme, many plugins and often some custom code. Each of those updates on its own schedule. Any update can break something, and the break is not always on the page you happen to check.
Without tests, every update relies on someone clicking around and hoping they spot the problem. That is slow, and it gets skipped when people are busy. Tests do the same checks in minutes, the same way every time.
Untested custom code is also one of the six areas we score when we measure WordPress technical debt. Adding tests is one of the most direct ways to lower that score, and it makes every future change cheaper.
PHPUnit vs Playwright: what each one tests
PHPUnit: testing the code
PHPUnit is the standard testing tool for PHP. WordPress core uses it, and so do many plugins. A PHPUnit test calls a function or class directly and checks the result.
Use PHPUnit for:
- Business logic, such as price calculations, discount rules or eligibility checks.
- Custom post types, taxonomies and settings being registered correctly.
- Hooks and filters doing what you expect.
- Data being saved and read correctly.
PHPUnit tests are fast. Hundreds can run in seconds or minutes.
Playwright: testing what visitors do
Playwright is a browser automation tool. A Playwright test opens a real browser, visits pages, clicks buttons, fills in forms and checks what appears on screen. These are called end-to-end tests, because they test the whole stack, from the browser to the database.
Use Playwright for:
- Contact and quote forms submitting successfully.
- Checkout and payment flows (using test payment modes).
- Login, registration and member areas.
- Key pages loading with the right content.
- Anything built with a page builder or the block editor.
End-to-end tests are slower than PHPUnit tests, but they catch problems no unit test can see, like a JavaScript error that stops a form from submitting.
What to test first
You do not need to test everything. Start where a failure would hurt the business most:
- The tasks that make money or bring leads. The quote form, checkout, booking or sign-up.
- The tasks people rely on daily. Member login, course access, account pages.
- Custom code with business rules. Pricing, permissions, integrations with outside systems.
- Things that broke before. Every past bug is a good test case, because it shows where the site is fragile.
Five to ten well-chosen end-to-end tests already make updates much safer.
Setting up a test environment with wp-env
Tests need a WordPress site they can safely change and reset. Never run tests that write data against your live site.
The official option is wp-env, from the @wordpress/env package. It starts a local WordPress site with one command. By default it runs on Docker, and it creates two sites: a development site at localhost:8888 and a separate test site at localhost:8889. You describe the site in a .wp-env.json file, including which plugins and themes to load and which PHP version to use.
npm install @wordpress/env --save-dev
npx wp-env start
For a real client site, the test environment should match production as closely as possible: same PHP version, same plugins, and realistic (but not real personal) data.
Writing Playwright tests for WordPress
WordPress maintains a helper package, @wordpress/e2e-test-utils-playwright, that adds WordPress-aware tools on top of Playwright. It provides helpers called fixtures, including admin for the dashboard, editor for the block editor, pageUtils for general page actions and requestUtils for setting up data through the REST API. The WordPress Developer Blog has a step-by-step guide to getting started with WordPress end-to-end tests in Playwright.
Installation looks like this:
npm install @playwright/test @wordpress/e2e-test-utils-playwright --save-dev
npx playwright install --with-deps
Here is a simple test that checks a contact form on the front end. The field labels and messages are examples; use the ones from your own form.
import { test, expect } from '@wordpress/e2e-test-utils-playwright';
test( 'contact form shows a confirmation message', async ( { page } ) => {
await page.goto( '/contact/' );
await page.getByLabel( 'Name' ).fill( 'Test Visitor' );
await page.getByLabel( 'Email' ).fill( 'test@example.com' );
await page.getByLabel( 'Message' ).fill( 'This is an automated test.' );
await page.getByRole( 'button', { name: 'Send' } ).click();
await expect( page.getByText( 'Thanks for contacting us' ) ).toBeVisible();
} );
A few habits make Playwright tests reliable:
- Find elements the way people do, by label, role and visible text. This also nudges you toward accessible markup, since a field with no label is hard to test.
- Create test data in setup, through the REST API, instead of depending on content that might change.
- Keep each test independent, so one failure does not cause a chain of others.
- Turn off real side effects like outgoing emails and live payments in the test environment.
Writing PHPUnit tests for WordPress
For plugin and theme code, WordPress provides a test framework built on PHPUnit. Tests extend the WP_UnitTestCase class, which resets the database between tests and includes a “factory” for creating posts, users and terms.
The quickest way to scaffold the files is WP-CLI, the WordPress command-line tool. The wp scaffold plugin-tests command creates a PHPUnit configuration file, a bootstrap file, a sample test and a script that installs the WordPress test suite. The WordPress Developer Blog also has a guide on adding automated unit tests to a WordPress plugin, which uses the yoast/phpunit-polyfills and wp-phpunit/wp-phpunit Composer packages.
A simple test looks like this. The function name is an example from a fictional plugin.
<?php
class Test_Member_Discount extends WP_UnitTestCase {
public function test_subscribers_get_ten_percent_discount() {
$user_id = self::factory()->user->create( array( 'role' => 'subscriber' ) );
$this->assertSame( 10, myplugin_get_discount_percent( $user_id ) );
}
public function test_guests_get_no_discount() {
$this->assertSame( 0, myplugin_get_discount_percent( 0 ) );
}
}
Good unit tests are small, test one thing each, and cover the edge cases: empty values, logged-out users, missing data.
Running tests automatically
Tests only help if they run. The best time is before anything reaches production:
- Before plugin, theme and core updates. Apply updates on staging, run the tests, then deploy. Our guide to safe WordPress updates with staging and tests covers the full process.
- On every code change. Run the tests automatically when code is pushed to your Git repository, using a continuous integration service such as GitHub Actions.
- Before a PHP upgrade. Run the full suite on the new PHP version first. See our article on how to upgrade the PHP version on WordPress.
- Before and during a refactor. Tests are what make it safe to change old code. Read more in our guide on whether to refactor or rebuild a legacy WordPress site.
How we use testing at Verma IT
Testing is part of our daily work, not an extra. Our founder, Ajay Verma, is a core developer of Uncanny Automator and a WordPress core contributor, and he works with Docker, PHPUnit and Playwright every day. We can spin up hundreds of WordPress test sites in automated environments to check plugins and updates across many setups at once.
For client sites, that means we write tests around the parts of your site that matter most, especially complex forms and automations like those described in our articles on Gravity Forms custom development and Uncanny Automator workflows.
Add a safety net to your site
If your site has custom code or critical forms and no tests, we can help you set up a practical test suite and run it on every update as part of our WordPress maintenance service. Contact us and tell us which parts of your site you can least afford to break.
Frequently asked questions
- What is the difference between PHPUnit and Playwright for WordPress?
- PHPUnit tests PHP code directly, such as a function that calculates a price or saves a setting. Playwright drives a real browser and tests what a visitor does, such as filling in a form or completing checkout. Most sites benefit from both.
- Do I need automated tests for a small WordPress site?
- A small brochure site may only need a handful of browser tests for its forms and key pages. The more custom code and business logic a site has, the more tests pay off.
- What is wp-env?
- wp-env is an official WordPress tool that starts a local WordPress site for development and testing with one command. By default it uses Docker and creates both a development site and a separate test site.
- How long does it take to set up automated testing for WordPress?
- A first set of browser tests for your most important pages and forms can often be running within a few days. Full coverage of custom code takes longer and is usually built up gradually.