Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesiTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Test WordPress code at the layer where a regression can occur: fast unit tests for isolated PHP logic, WordPress-backed integration tests for plugin or theme interactions with core, browser end-to-end tests for user journeys, and a separate content-and-rendering review for themes. The current WordPress Playground CLI can run PHPUnit in a clean, database-free environment, while Playwright and Playground cover browser behavior. This tutorial shows how to combine those layers, test supported WordPress and PHP versions, and add repeatable checks without turning every change into a full staging deployment.
Choose the test layer before writing a test
A useful test answers a specific question. “Does this formatter return the right value?” is an isolated unit question. “Does this plugin register a shortcode and save its settings through WordPress?” is an integration question. “Can a visitor submit the form and see the confirmation?” is an end-to-end (E2E) question. A theme adds another dimension: whether realistic content renders correctly in the browsers and viewport sizes your project supports.
The WP-CLI handbook distinguishes pure unit tests from integration tests: a unit test can exercise code without loading WordPress, while an integration test loads WordPress to check interaction with core APIs and behavior. Read the distinction in the Plugin Integration Tests handbook.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →| Layer | What it exercises | Typical setup | Feedback | What it cannot establish |
|---|---|---|---|---|
| Unit | One class, function, or rule in isolation | PHP and PHPUnit; WordPress need not be loaded | Fast, local or in continuous integration (CI) | Whether WordPress hooks, queries, templates, or browser behavior work |
| Integration | Plugin/theme code working with WordPress core and its APIs | WordPress test runtime, commonly a clean Playground run | Slower than a pure unit test, still suitable for CI | Clicks, visual layout, JavaScript execution, and other browser outcomes |
| Browser E2E | A user journey through the front end or administration area | Node.js, Playwright, a browser, and a WordPress environment | Slower and more infrastructure-sensitive | Every PHP branch and every supported browser unless you exercise them |
| Theme/content review | Templates, CSS, JavaScript, accessibility-relevant rendering, and edge-case content | Theme Unit Test data plus manual browser inspection | Visual and functional findings that automation may miss | A manual pass does not provide a repeatable regression guard by itself |
Use more than one layer when the behavior crosses boundaries. A unit test for a query argument does not prove the query is wired to the right hook; an integration test does not prove a mobile menu opens in a browser; and a screenshot review does not prove a nonce or permission check is enforced.
#1 Best Overall
How do I establish an isolated WordPress test environment?
For repeatable plugin and theme checks, start with an environment that is disposable and independent of your development database. WordPress Playground runs WordPress locally in the browser. Its quick-start documentation says a site is not uploaded unless you explicitly choose an action such as exporting to GitHub; browser storage and ZIP export/import can preserve an environment when you need to inspect it again. See Start using WordPress Playground in 5 minutes and the Playground Test overview.
Keep the project and test state separate
- Keep source code, Composer files, PHPUnit configuration, and test fixtures in the plugin or theme repository.
- Use a fresh Playground run for a clean baseline. Do not rely on data left by a previous manual session when a test is meant to be repeatable.
- Use a copied or synthetic site for experiments. Do not point destructive tests at production credentials, customer data, or a live database.
- When a manual investigation must be preserved, export the Playground ZIP or use browser storage, then record the WordPress, PHP, theme, and plugin versions with the reproduction steps.
Install PHPUnit with Composer
The official Playground PHPUnit guide assumes PHPUnit is installed as a development dependency. From the project directory, run:
composer require --dev phpunit/phpunit
Commit the resulting Composer files so every developer and CI runner resolves the same dependency set. Your project also needs a PHPUnit configuration file; the documented command below expects phpunit.xml.dist in the mounted project.
Free tools Windows power users keep installed
One-click scans. No signup required.
How do I run PHPUnit tests for WordPress?
The current official route is to let the Playground CLI mount your plugin or theme into a clean WordPress installation and invoke the project’s PHPUnit binary. The Running PHPUnit with the Playground CLI guide was last updated September 30, 2026. Its command uses --auto-mount to detect the current WordPress directory, plugin, or theme and mount it below /wordpress/wp-content/.
Run a plugin test suite
From the plugin directory, replace MY_PLUGIN with the directory name used by your project:
npx @wp-playground/cli@latest php --auto-mount -- /wordpress/wp-content/plugins/MY_PLUGIN/vendor/bin/phpunit -c /wordpress/wp-content/plugins/MY_PLUGIN/phpunit.xml.dist
The command starts a clean WordPress installation for that run, mounts the project, and passes the configuration file to PHPUnit. Because the WordPress runtime is created by Playground, this path does not require you to maintain a local database.
Rank #2
Run a theme test suite
From the theme directory, substitute the theme path:
npx @wp-playground/cli@latest php --auto-mount -- /wordpress/wp-content/themes/THEME_NAME/vendor/bin/phpunit -c /wordpress/wp-content/themes/THEME_NAME/phpunit.xml.dist
Use a theme-specific configuration if your tests need different bootstrap files, source directories, or test suites. The important boundary is that the test process loads WordPress when you are checking hooks, template functions, options, metadata, or other core integration.
Use an explicit mount when discovery is not suitable
--auto-mount is convenient for the conventional directory layout. If your repository contains several projects or you need a precise mapping, use Playground’s --mount option instead and map the host project to the desired path under /wordpress/wp-content/plugins/ or /wordpress/wp-content/themes/. Keep the PHPUnit path and the configuration path consistent with that mapping.
Select PHP and WordPress versions deliberately
The same guide documents --php and --wp flags. As stated in the September 30, 2026 edition, the CLI reports PHP 7.4 through 8.5 and accepts a WordPress version, latest, nightly, or beta. These values are tool-version-dependent, so check the current guide when you update your matrix.
npx @wp-playground/cli@latest php --php=8.2 --wp=latest --auto-mount -- /wordpress/wp-content/plugins/MY_PLUGIN/vendor/bin/phpunit -c /wordpress/wp-content/plugins/MY_PLUGIN/phpunit.xml.dist
Run the same suite again with each PHP and WordPress combination that your support policy promises. A passing run on one pair demonstrates that pair only; it is not evidence of universal compatibility.
Separate pure unit tests from integration tests
Keep logic that does not need WordPress in fast unit tests. For example, a slug normalizer, value object, or permission decision can usually receive plain inputs and return a result without a WordPress bootstrap. Put hook registration, REST callbacks, database queries, options, metadata, and template behavior in the WordPress-backed suite. This separation makes failures easier to diagnose: a unit failure points at project logic, while an integration failure can expose an API or lifecycle mismatch.
How do I add browser end-to-end tests?
PHPUnit cannot click a button, submit a form, follow a redirect, or assert what a visitor sees. For those workflows, WordPress documents combining Playwright with Playground CLI in E2E Testing with Playwright and WordPress Playground. The documented approach avoids Docker, database provisioning, and manual WordPress setup.
Install the prerequisites
The guide lists Node.js 20 or newer, a plugin, theme, or site to test, the Playwright test package, the Playground CLI, and Chromium. In a JavaScript project, install the packages and browser:
npm install --save-dev @playwright/test @wp-playground/cli
npx playwright install chromium
Keep the browser install in your developer and CI setup rather than downloading it ad hoc during each test. Pin dependency versions in your lockfile so a routine install does not silently change the runner.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchDesign a workflow test around observable results
- Start the Playground-backed WordPress site with the plugin or theme mounted.
- Navigate to the page or administration screen a real user would open.
- Use Playwright locators to click controls and enter representative data.
- Assert a visible result, URL change, saved value, error message, or other outcome that matters to the user.
- Capture diagnostic information on failure, such as a trace or screenshot, and close the environment cleanly.
Prefer a small number of high-value journeys: activation and first-run setup, a front-end form submission, a permissions boundary, a checkout or publishing path, and the most important responsive navigation. Keep business-rule permutations in PHPUnit; use E2E to prove that the pieces are connected through the browser.
Do not treat E2E as a replacement for PHP tests
An E2E test can pass while an unvisited PHP branch is broken, and it can fail because of a selector or timing issue even when the underlying logic is correct. Run fast unit tests on every change, integration tests on every merge, and the smaller E2E set according to the risk and runtime your CI can support. The scopes described in the official PHPUnit and Playwright guides are complementary, not interchangeable.
How do I test a WordPress theme with realistic content?
A theme can be valid PHP and still break when a title is unusually long, an image has a different aspect ratio, comments are deeply nested, or post content contains mixed HTML. WordPress provides importable Theme Unit Test data for these cases. The Theme Handbook testing page describes the data as one part of a broader process, not a complete certification.
Rank #4
- Keep track of everything from attendance to test scores
- Spiral bound
- Measures 8-1/2" x 11"
Load Theme Unit Test data
- Prepare a disposable WordPress installation, such as a fresh Playground run.
- Install and activate the WordPress Importer.
- Import the Theme Unit Test data package.
- Activate the theme under test and inspect posts, pages, archives, comments, media, widgets, menus, and any custom templates.
Look deliberately at long and short titles, differently sized images, galleries, captions, empty and populated sidebars, nested comments, pagination, password-protected content, and posts containing mixed HTML. Record the URL and content item for every defect so another person can reproduce it.
Follow the manual theme checklist
The Theme Testing handbook recommends enabling WP_DEBUG, checking template files, walking through the Theme Unit Test content, validating HTML and CSS, checking JavaScript errors, and testing target browsers. Its examples include Safari, Chrome, Opera, Firefox, and Microsoft Edge; choose the browsers and devices that your own support statement names.
- Enable debugging in a non-production environment and inspect PHP notices, warnings, deprecated calls, and JavaScript console errors.
- Check that required template files and fallback behavior work for posts, pages, archives, search, 404 pages, comments, and media.
- Validate generated HTML and CSS, then test keyboard navigation, focus states, form controls, and responsive breakpoints.
- Compare representative pages at the viewport sizes and browsers you support, including high-density displays when image clarity matters.
- Remove temporary debug settings and material before release.
Use inspection tools selectively
The Theme Handbook names Theme Check for checking against Theme Review Guidelines. It also lists Debug Bar, Query Monitor, Log Deprecated Notices, and, for classic themes, Monster Widget as possible aids. These are inspection tools, not mandatory dependencies: choose the one that answers the question you are investigating and remove or deactivate temporary tooling in production.
How can I test my plugin against different WordPress and PHP versions?
Start with a written support policy: the oldest PHP version, oldest WordPress version, current stable versions, and any versions you explicitly label experimental. Then run the same automated suite against those combinations. Playground’s version-selection support makes this practical, including beta and nightly WordPress channels as described in the Playground test documentation.
| Matrix row | Purpose | When to run |
|---|---|---|
| Minimum supported PHP + minimum supported WordPress | Protect the oldest compatibility promise | Every merge or release candidate |
| Current supported PHP + current stable WordPress | Catch the path most users receive today | Every merge |
| Newest supported PHP + current stable WordPress | Find language or runtime deprecations early | Every merge when practical |
| WordPress beta or nightly with a supported PHP | Detect upcoming core changes before release | Scheduled or pre-release jobs; treat failures as early-warning signals |
The exact PHP range and accepted WordPress labels can change as the Playground CLI evolves. Quote the versions from the current official guide when publishing your support matrix, and date that statement. Do not infer support for a version you have not run.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Make tests repeatable in local work and CI
Use deterministic inputs
- Build fixtures in code or import a known package instead of depending on whatever is in a developer’s database.
- Use stable selectors in E2E tests, preferably semantic roles, labels, or dedicated test attributes rather than fragile CSS ancestry.
- Control time, timezone, locale, and external responses when a test depends on them.
- Reset state between tests that mutate options, posts, users, or files.
Keep failure evidence actionable
A failed test should identify the environment and the smallest reproduction. Print the PHP and WordPress versions, test name, URL or route, fixture name, and relevant log output. For browser failures, retain a trace or screenshot in CI artifacts. Do not include production secrets or personal data in those artifacts.
Best Value
Order the feedback loop by cost
- Run pure unit tests first because they provide the quickest signal.
- Run WordPress-backed integration tests next, using a clean Playground instance.
- Run the focused E2E journeys, then the broader browser matrix when the change warrants it.
- Perform the manual theme/content pass before a release, after template or CSS changes, and whenever supported browsers or devices change.
Or skip the browser setup
If your immediate need is a rendered reference image, visual review, or a screenshot artifact for a test report, ScreenshotNeo can capture a URL with one request instead of requiring you to install and maintain a browser runner. It is a screenshot API and MCP server for developers; it is not a replacement for PHPUnit assertions or Playwright interaction tests.
The API accepts options for full-page captures with lazy images loaded, CSS-selector element captures, dark mode, device presets or custom viewports, retina scale, custom CSS and JavaScript, clicks before capture, hidden selectors, waits for a selector, delay, or network idle, blocked ads/trackers/requests/resource types, custom headers, cookies, user agent and Authorization, timezone and geolocation, transparent backgrounds, resizing, chosen cache TTL, signed links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, usage reporting, and PDF output. Every plan includes these features. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.
Use the API documentation at https://screenshotneo.com/docs/ for the current parameter list. A minimal cURL capture is:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://wordpress.org -o shot.webp
The same request in Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://wordpress.org"}, timeout=90)
open("shot.webp", "wb").write(r.content)
And in Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://wordpress.org' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo accepts a cookie or consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and each response identifies the result with X-Page-Verdict and X-Billed headers. The free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots. Sign up for the free ScreenshotNeo plan when you want those captures without setting up a browser.
Troubleshooting common failures
| Symptom | Likely cause | Fix |
|---|---|---|
| PHPUnit cannot find the binary | Composer dependencies were not installed in the mounted project, or the path does not match the project type. | Run composer require --dev phpunit/phpunit in the project directory, confirm vendor/bin/phpunit exists, and use the matching plugins/ or themes/ path. |
| Playground starts but the plugin or theme is absent | Automatic discovery did not identify the intended project. | Run from the project directory or replace --auto-mount with an explicit --mount mapping. |
| Tests pass locally but fail in CI | Different PHP, WordPress, Node, browser, locale, or fixture state. | Print versions in the job, pin Composer and npm lockfiles, use a clean Playground run, and install the declared Chromium dependency. |
| Integration tests leak state into one another | Tests share options, posts, users, files, or a reused environment. | Reset mutated data between cases or start a fresh environment for the suite that requires isolation. |
| E2E tests time out waiting for a control | The page is still loading, a selector is brittle, or a consent/chat overlay covers the control. | Wait for a meaningful state, use a role or label locator, and remove or explicitly handle overlays in the test fixture. |
| A theme looks correct with default posts but breaks imported content | Templates assume short titles, fixed image dimensions, flat comments, or restricted HTML. | Re-run the Theme Unit Test import and inspect the specific template, CSS rule, and responsive breakpoint responsible. |
| A ScreenshotNeo response is not a clean image | The target may have failed to load, shown a bot check, returned a blank page, or hit cache. | Inspect X-Page-Verdict and X-Billed, then adjust waits, headers, cookies, user agent, or blocking options as appropriate. Failed loads and cache hits are not billed. |
A release checklist that matches the risk
- Pure PHP logic has unit coverage that runs without WordPress.
- Hooks, settings, queries, REST behavior, permissions, and template integration have WordPress-backed tests.
- Critical front-end and admin workflows have Playwright coverage with observable assertions.
- Theme Unit Test data has been imported and inspected for content extremes.
WP_DEBUG, HTML/CSS validation, JavaScript console checks, and target-browser reviews are complete in a non-production environment.- The automated suite has run against every promised minimum and current WordPress/PHP combination, with experimental beta/nightly runs clearly labeled.
- Temporary debug settings, notes, test credentials, and generated artifacts have been removed or isolated before release.
FAQ
Can a visual screenshot be used as the only theme test?
No. A screenshot can document rendered output, but it does not exercise form submission, permissions, JavaScript interaction, or PHP branches. Pair visual review with integration and browser tests.
Should beta and nightly WordPress runs block every release?
Not necessarily. They are useful early-warning jobs; decide whether they are advisory or release-blocking in your project policy, and record that decision alongside the supported-version matrix.
What should I publish when a version combination fails?
Report the exact PHP and WordPress versions, test command, failing case, and whether the combination is inside or outside your stated support policy. A failure outside the policy is still useful as an upgrade warning, but it should not be presented as a supported-version defect.
Frequently Asked Questions
Can a visual screenshot be used as the only theme test?
No. A screenshot documents rendered output but does not exercise form submission, permissions, JavaScript interaction, or PHP branches; combine it with integration and browser tests.
Should beta and nightly WordPress runs block every release?
Not necessarily. Treat them as advisory early-warning jobs unless your project policy explicitly makes them release-blocking.
What should I publish when a version combination fails?
Record the exact PHP and WordPress versions, command, failing case, and whether that combination is inside your support policy.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Recommended Free Tools

