Benjamin Crozat “Heard about Sevalla? They let you deploy PHP apps with ease.” Claim $50 →

What’s new in Pest 4 and how to upgrade

4 minutes read

What’s new in Pest 4 and how to upgrade

Introduction to Pest 4

Pest 4 is the biggest leap the framework has made since its birth: it brings built-in browser testing that actually feels like writing unit tests, plus useful quality gates and CI scalability features. In this post I cover the highlights and give you a dead-simple upgrade path from Pest 3.

Is Pest 4 as easy to upgrade as version 3?

Pretty muchas long as you’re on PHP 8.3+ and willing to bump your Pest plugins. Pest 4 sits on PHPUnit 12, so you inherit PHPUnit’s behavior changes as well. Start by updating your dev deps, then run a composer update.

{
  "require-dev": {
    "pestphp/pest": "^4.0"
  }
}

Then:

composer update

Notes that matter:

  • Pest requires PHP 8.3+ and runs on top of PHPUnit 12. Read the Upgrade Guide and PHPUnit 12 notes if you maintain a big suite.
  • Update official Pest plugins to ^4.0 (browser, type-coverage, mutate, etc.).
  • If you use Laravel, Collision 8.x remains the right line for Laravel 11/12 and works fine alongside Pest 4.
  • Using snapshot tests? Pest 4 changes snapshot naming, so regenerate them with --update-snapshots.

What’s new in Pest 4?

Browser testing that doesn’t fight you

Pest 4 adds first-class, Playwright-based browser testing with Laravel testing API support, parallel runs, device emulation, and light/dark mode toggles. It’s the first browser runner that feels ergonomic inside PHP.

Install once:

composer require pestphp/pest-plugin-browser --dev
npm install playwright@latest
npx playwright install

A tiny example:

it('lets users sign in', function () {
    $page = visit('/')->on()->mobile()->inDarkMode();
    $page->click('Sign In')
         ->fill('email', 'user@example.com')
         ->fill('password', 'secret')
         ->press('Submit')
         ->assertSee('Dashboard')
         ->assertNoJavascriptErrors();
});

You can also pick browsers (--browser firefox|safari), emulate devices (->on()->iPhone14Pro()), set geolocation/timezone/locale, and even pause or ->tinker() for debugging. There’s built-in assertNoAccessibilityIssues() and a visual diff assertion (see below).

One-liner smoke tests (JS/console clean)

Want to sanity-check your whole app? This assertion crawls routes and fails on JS errors or console logs:

visit(['/', '/about', '/contact'])->assertNoSmoke();

It’s a practical “break-glass” test before deploys.

Visual regression testing

Snapshot pixels, not just strings:

visit(['/', '/about'])->assertScreenshotMatches();

Great for UI-heavy apps and CSS refactors.

Test sharding for real CI speed

Split the suite across machines with --shard=1/4, --shard=2/4, etc., and combine with --parallel. CI finally scales horizontally without hacks.

./vendor/bin/pest --parallel --shard=1/4

Type coverage, now actually fast

The type-coverage engine is ~2× faster on first run and near-instant afterwards, and it supports sharding. If you care about strict typing, this removes the pain.

Profanity checker (yes, really)

Keep code comments and constants professional with --profanity, with language filters and include/exclude lists. It’s opt-in via a plugin:

composer require pestphp/pest-plugin-profanity --dev
./vendor/bin/pest --profanity

Silly? Maybe. Useful for teams and OSS? Definitely.

Small but handy refinements

  • skipLocally() / skipOnCi() for environment-conditional tests.
  • New arch/expectations like not->toHaveSuspiciousCharacters() (enabled on the php preset) and toBeSlug.
  • Still all the good stuff from v3: architecture presets, mutation testing, team management, etc. (unchanged concepts, new base).

Upgrade guide: Pest 3 → Pest 4 (copy/paste)

  1. Bump PHP and packages:
{
  "require": {
    "php": "^8.3"
  },
  "require-dev": {
    "pestphp/pest": "^4.0",
    "pestphp/pest-plugin-browser": "^4.0",        // if you’ll use browser tests
    "pestphp/pest-plugin-type-coverage": "^4.0"   // optional but recommended
  }
}
  1. Update & install Playwright if using browser tests:
composer update
npm install playwright@latest
npx playwright install
  1. Snapshots? Regenerate names:
./vendor/bin/pest --update-snapshots
  1. Remove archived plugins (pest-plugin-watch, pest-plugin-faker) if present.

  2. On Laravel, keep Collision 8.x for Laravel 11/12; PHPUnit 12 compatibility is fine.

Practical tips (from running real suites)

  • Start with smoke + a11y + visuals on a small route list. Expand once CI is green.
  • Shard by test type (browser shards separate from unit/feature) to keep feedback loops tight.
  • For flaky UI, prefer text selectors or data-test hooks (@login) over brittle CSS. It’s all in the Browser Testing API.
  • If you’re coming from Dusk/Selenium, the Playwright engine plus Laravel helpers is the best of both worlds. Less ceremony, more signal.

Conclusion

Pest 4 is a serious upgrade: Playwright-powered browser tests, smoke & visual checks, sharding, faster type coverage, and a few thoughtful niceties. Upgrade is straightforward: PHP 8.3+, bump to pest:^4.0 (and plugins), regenerate snapshots if needed, and start adding browser coverage where it makes you money. If you test Laravel for a living, this is worth the jump.


Did you like this article? Then, keep learning:

Help me reach more people by sharing this article on social media!

0 comments

Guest

Markdown is supported.

Hey, you need to sign in with your GitHub account to comment. Get started →

Great deals for developers

Search for posts and links

Try to type something…