Pest v4.5.0 adds first-class support for retrying flaky tests with a new flaky() modifier and --flaky CLI flag. The release also includes a new architecture assertion for detecting namespace/file path casing mismatches, a --only-covered coverage filter, and more.
flaky()test modifier with configurable retry count--flakyCLI option to run only flaky-marked teststoBeCasedCorrectlyarchitecture assertion--only-coveredoption for code coverage output- Multiple bug fixes for datasets, traits, and parallel testing
What's New
flaky() Test Modifier and --flaky CLI Option
Tests that fail intermittently due to timing, external dependencies, or other non-deterministic conditions can now be marked with ->flaky(). When a flaky test fails, Pest automatically retries it up to the configured number of times before reporting it as a failure. The default retry count is 3.
it('sends an email notification', function () { // ...})->flaky(); it('resolves within the timeout', function () { // ...})->flaky(tries: 5);
The new --flaky CLI flag filters the test run to execute only tests marked as flaky, making it easier to verify or debug unstable tests in isolation:
vendor/bin/pest --flaky
Lifecycle hooks such as beforeEach and afterEach run between each retry, so test state is properly reset on every attempt.
toBeCasedCorrectly Architecture Assertion
A new ->toBeCasedCorrectly() assertion has been added to Pest's architecture testing suite. It compares each class's namespace against its file path and flags any casing discrepancies. Because macOS and Windows use case-insensitive file systems by default, mismatched casing is often invisible in local development but causes class-not-found errors when deployed to Linux servers.
arch() ->expect('App') ->toBeCasedCorrectly();
A class at app/Providers/AppServiceProvider.php with the namespace App\providers\AppServiceProvider would be caught by this assertion.
PR: #1455, contributed by @SimonBroekaert
--only-covered Coverage Option
The --coverage flag now accepts an --only-covered companion option that hides all files with 0% coverage from the output. This is useful when working on large applications where you want to focus on which files your new tests actually cover, without scrolling past a long list of uncovered files.
vendor/bin/pest --coverage --only-covered
The option does not affect --min or --exact thresholds; those calculations still include all files.
PR: #1626, contributed by @SimonBroekaert
Bug Fixes
- Fixed
toUseTraitto detect traits inherited through parent classes and nested trait usage (#1515), contributed by @yondifon - Fixed missing classes before
toExtendin the Laravel preset (#1569), contributed by @treyssatvincent - Added "Rules" classes to the Laravel preset (#1580), contributed by @bibrokhim
- Fixed
--paralleland--teamcityargument handling for ParaTest (#1615), contributed by @smirok - Fixed nested dataset discovery and invalid-dataset reporting in parallel mode (#1655), contributed by @stsepelin
- Fixed Unicode character preservation in filenames when using
--filter(#1624), contributed by @Vmadmax - Fixed dataset named parameters (#1634), contributed by @dbpolito
- Fixed
thistype annotations for parameter closures in functions (#1628), contributed by @DevDavido - Fixed dataset inheritance when using method chaining with
beforeEach()->with()anddescribe()->with()(#1565), contributed by @louisbels