Skip to content

Commit 25b67a5

Browse files
committed
docs: document new v4.5 features
1 parent 90e07c2 commit 25b67a5

File tree

5 files changed

+136
-0
lines changed

5 files changed

+136
-0
lines changed

arch-testing.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Granular expectations allow you to define specific architectural rules for your
4848
<div class="collection-method-list" markdown="1">
4949

5050
- [`toBeAbstract()`](#expect-toBeAbstract)
51+
- [`toBeCasedCorrectly()`](#expect-toBeCasedCorrectly)
5152
- [`toBeClasses()`](#expect-toBeClasses)
5253
- [`toBeEnums()`](#expect-toBeEnums)
5354
- [`toBeIntBackedEnums()`](#expect-toBeIntBackedEnums)
@@ -104,6 +105,19 @@ arch('app')
104105
->toBeAbstract();
105106
```
106107

108+
<a name="expect-toBeCasedCorrectly"></a>
109+
### `toBeCasedCorrectly()`
110+
111+
The `toBeCasedCorrectly()` method may be used to ensure that all class names match their file and directory path casing, verifying PSR-4 autoloading compliance.
112+
113+
```php
114+
arch('app')
115+
->expect('App')
116+
->toBeCasedCorrectly();
117+
```
118+
119+
For example, if a class is named `App\Models\UserProfile`, this expectation verifies that the file is located at `app/Models/UserProfile.php` — and not `app/Models/Userprofile.php` or `app/models/UserProfile.php`.
120+
107121
<a name="expect-toBeClasses"></a>
108122
### `toBeClasses()`
109123

cli-api-reference.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ In the preceding chapters of the Pest documentation, we have covered numerous CL
3434
- `--issue`: Output to standard output tests with the given issue number.
3535
- `--pr`: Output to standard output tests with the given pull request number.
3636
- `--pull-request`: Output to standard output tests with the given pull request number (alias for `--pr`).
37+
- `--flaky`: Output to standard output tests marked as flaky.
3738
- `--retry`: Run non-passing tests first and stop execution upon first error or failure.
3839
- `--list-suites` List available test suites.
3940
- `--testsuite <name>`: Only run tests from the specified test suite(s).
@@ -122,6 +123,8 @@ In the preceding chapters of the Pest documentation, we have covered numerous CL
122123

123124
- `--coverage`: Generate code coverage report and output to standard output.
124125
- `--coverage --min=<value>`: Set the minimum required coverage percentage, and fail if not met.
126+
- `--coverage --exactly=<value>`: Set the exact required coverage percentage, and fail if not met.
127+
- `--coverage --only-covered`: Hide files with 0% coverage from the code coverage report.
125128
- `--coverage-clover <file>`: Write code coverage report in Clover XML format to file.
126129
- `--coverage-cobertura <file>`: Write code coverage report in Cobertura XML format to file.
127130
- `--coverage-crap4j <file>`: Write code coverage report in Crap4J XML format to file.

datasets.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,36 @@ test('The generator produces only integers', function ($i) {
8585
});
8686
```
8787

88+
## Named Parameters
89+
90+
When using datasets with associative arrays, Pest matches the dataset keys to the closure parameter names, regardless of order. This allows you to define your dataset in any key order and have the values automatically mapped to the correct parameters.
91+
92+
```php
93+
it('has user data', function (string $email, string $name) {
94+
expect($name)->toBeString();
95+
expect($email)->toContain('@');
96+
})->with([
97+
['name' => 'Taylor', 'email' => 'taylor@laravel.com'],
98+
['name' => 'Nuno', 'email' => 'enunomaduro@gmail.com'],
99+
]);
100+
```
101+
102+
In the example above, even though the dataset defines `name` before `email`, Pest maps them correctly to the closure parameters `$email` and `$name`.
103+
104+
Named parameters also work with shared datasets and bound closures.
105+
106+
```php
107+
dataset('users', [
108+
['name' => 'Taylor', 'email' => 'taylor@laravel.com'],
109+
['name' => 'Nuno', 'email' => 'enunomaduro@gmail.com'],
110+
]);
111+
112+
it('has user data', function (string $email, string $name) {
113+
expect($name)->toBeString();
114+
expect($email)->toContain('@');
115+
})->with('users');
116+
```
117+
88118
## Bound Datasets
89119

90120
Pest's bound datasets can be used to obtain a dataset that is resolved after the `beforeEach()` method of your tests. This is particularly useful in Laravel applications (or any other Pest integration) where you may need a dataset of `App\Models\User` models that are created after your database schema is prepared by the `beforeEach()` method.
@@ -176,6 +206,34 @@ When running the example above, Pest's output will contain a description of each
176206
<img src="/assets/img/datasets-businesshours.webp?1" style="--lines: 10" />
177207
</div>
178208

209+
## Describe Blocks With Datasets
210+
211+
You can attach a dataset to a `describe()` block, and all tests within that block will receive the dataset values.
212+
213+
```php
214+
describe('user notifications', function () {
215+
test('can send notification', function (string $channel) {
216+
expect($channel)->toBeString();
217+
});
218+
219+
test('can queue notification', function (string $channel) {
220+
expect($channel)->toBeIn(['mail', 'sms']);
221+
});
222+
})->with(['mail', 'sms']);
223+
```
224+
225+
You can also use `beforeEach()->with()` inside a `describe()` block to apply a dataset to all tests within that scope.
226+
227+
```php
228+
describe('user settings', function () {
229+
beforeEach()->with([10, 20, 30]);
230+
231+
test('receives the dataset value', function (int $value) {
232+
expect($value)->toBeGreaterThan(0);
233+
});
234+
});
235+
```
236+
179237
## Repeating Tests
180238

181239
In some cases, you may need to repeat a test multiple times for debugging purposes or to ensure that the test is stable. On these occasions, you may use the `repeat()` method to repeat a test a given number of times.

filtering-tests.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ This chapter will cover even more ways to filter which tests are executed by Pes
1717

1818
- [`--bail`](#bail)
1919
- [`--dirty`](#dirty)
20+
- [`--flaky`](#flaky)
2021
- [`--filter`](#filter)
2122
- [`--group`](#group)
2223
- [`--exclude-group`](#exclude-group)
@@ -45,6 +46,52 @@ The `--dirty` option instructs Pest to only run tests that have uncommitted chan
4546

4647
> Note that, due to a limitation in Pest, test cases written using the PHPUnit syntax will always be considered dirty.
4748
49+
<a name="flaky"></a>
50+
### `--flaky`
51+
52+
Some tests may occasionally fail due to external factors like network latency, timing issues, or third-party service instability. You can mark these tests as "flaky" using the `flaky()` method, and Pest will automatically retry them before reporting a failure.
53+
54+
```php
55+
it('may have external dependencies', function () {
56+
$response = Http::get('https://example.com/api');
57+
58+
expect($response->status())->toBe(200);
59+
})->flaky();
60+
```
61+
62+
By default, `flaky()` retries the test up to **3 times**. You can customize the number of retries by passing the `tries` parameter.
63+
64+
```php
65+
it('may have external dependencies', function () {
66+
$response = Http::get('https://example.com/api');
67+
68+
expect($response->status())->toBe(200);
69+
})->flaky(tries: 5);
70+
```
71+
72+
Between retries, Pest properly re-runs your `setUp` and `tearDown` lifecycle hooks, clears mock objects, and resets dynamic properties — ensuring each attempt starts from a clean state.
73+
74+
Note that `flaky()` will not retry tests that are skipped, incomplete, or that throw an expected exception (via `->throws()`). It only retries on unexpected failures.
75+
76+
The `flaky()` method can be combined with other test methods like `with()`, `repeat()`, and `describe()` blocks.
77+
78+
```php
79+
it('works with datasets', function (string $url) {
80+
$response = Http::get($url);
81+
82+
expect($response->status())->toBe(200);
83+
})->flaky(tries: 2)->with([
84+
'https://example.com/api/users',
85+
'https://example.com/api/posts',
86+
]);
87+
```
88+
89+
To list all tests marked as flaky in your test suite, use the `--flaky` option.
90+
91+
```bash
92+
./vendor/bin/pest --flaky
93+
```
94+
4895
<a name="filter"></a>
4996
### `--filter`
5097

test-coverage.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,20 @@ Or, you can use the `--exactly` option to enforce that the coverage results matc
5656
./vendor/bin/pest --coverage --exactly=99.3
5757
```
5858

59+
## Hiding Uncovered Files
60+
61+
When working on a large codebase, the coverage report can be noisy with many files showing 0% coverage. You can use the `--only-covered` option to hide files with no coverage from the report, allowing you to focus on the files that are partially covered.
62+
63+
```bash
64+
./vendor/bin/pest --coverage --only-covered
65+
```
66+
67+
This option can be combined with `--min` or `--exactly` for threshold enforcement.
68+
69+
```bash
70+
./vendor/bin/pest --coverage --only-covered --min=90
71+
```
72+
5973
## Ignoring Code
6074

6175
If there are certain sections of your application that cannot be tested and should be excluded from code coverage analysis, you can use `@codeCoverageIgnoreStart` and `@codeCoverageIgnoreEnd` comments in your source code to achieve this.

0 commit comments

Comments
 (0)