### GitHub Actions CI Setup for Playwright Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Steps to set up Node.js, install dependencies, and install Playwright browsers in a GitHub Actions workflow. ```yaml - uses: actions/setup-node@v4 with: node-version: lts/* - name: Install dependencies run: npm ci - name: Install Playwright Browsers run: npx playwright install --with-deps ``` -------------------------------- ### Validate String Start with toStartWith Source: https://github.com/pestphp/docs/blob/4.x/expectations.md Ensures the string starts with the specified prefix. ```php expect('Hello World')->toStartWith('Hello'); ``` -------------------------------- ### Describe Blocks with Setup and Teardown Source: https://github.com/pestphp/docs/blob/4.x/pest-spicy-summer-release.md Use `describe` blocks to group related tests and share setup (`beforeEach`) and teardown logic. Blocks can also be skipped. ```php beforeEach(fn () => $this->user = User::factory()->create()); describe('auth', function () { beforeEach(fn () => $this->actingAs($this->user)); test('cannot login when already logged in', function () { // ... }); test('can logout', function () { // ... }); })->skip(/* Skip the entire describe block */); describe('guest', function () { test('can login', function () { // ... }); // ... }); ``` -------------------------------- ### Install Pest Browser Plugin Source: https://github.com/pestphp/docs/blob/4.x/pest-v4-is-here-now-with-browser-testing.md Commands to install the necessary PHP and Node.js dependencies for browser testing. ```bash composer require pestphp/pest-plugin-browser --dev npm install playwright@latest npx playwright install ``` -------------------------------- ### Install Profanity Plugin Source: https://github.com/pestphp/docs/blob/4.x/profanity.md Install the plugin as a development dependency via Composer. ```bash composer require pestphp/pest-plugin-profanity --dev ``` -------------------------------- ### expect()->toStartWith() Source: https://github.com/pestphp/docs/blob/4.x/expectations.md Ensures that the value starts with the provided string. ```APIDOC ## `toStartWith(string $expected)` ### Description This expectation ensures that `$value` starts with the provided string. ### Method `toStartWith` ### Endpoint N/A (Assertion method) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```php expect('Hello World')->toStartWith('Hello'); ``` ### Response #### Success Response (200) N/A (Assertion result) #### Response Example N/A ``` -------------------------------- ### Install Pest Browser Plugin and Playwright Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Commands to install the necessary Pest browser plugin and Playwright for browser testing. ```bash composer require pestphp/pest-plugin-browser --dev npm install playwright@latest npx playwright install ``` -------------------------------- ### Install Pest Livewire Plugin Source: https://github.com/pestphp/docs/blob/4.x/plugins.md Install the Pest Livewire plugin via Composer to enable testing of Livewire components within Pest. ```bash composer require pestphp/pest-plugin-livewire --dev ``` -------------------------------- ### Install Mockery Source: https://github.com/pestphp/docs/blob/4.x/mocking.md Use Composer to add Mockery as a development dependency. ```bash composer require mockery/mockery --dev ``` -------------------------------- ### PHPUnit Test Example Source: https://github.com/pestphp/docs/blob/4.x/migrating-from-phpunit-guide.md A standard PHPUnit test class structure before migration. ```php assertTrue(true); } } ``` -------------------------------- ### Install Drift Plugin Source: https://github.com/pestphp/docs/blob/4.x/migrating-from-phpunit-guide.md Add the drift plugin as a development dependency to enable automated test conversion. ```bash composer require pestphp/pest-plugin-drift --dev ``` -------------------------------- ### Identify missing type hints in PHP methods Source: https://github.com/pestphp/docs/blob/4.x/pest-spicy-summer-release.md Example of a method lacking parameter and return type declarations. ```php public function find($id) { return User::find($id); } ``` -------------------------------- ### Pest Test Example Source: https://github.com/pestphp/docs/blob/4.x/migrating-from-phpunit-guide.md The resulting Pest test syntax after running the drift conversion. ```php test('true is true', function () { expect(true)->toBeTrue(); }); ``` -------------------------------- ### Install Pest as a development dependency Source: https://github.com/pestphp/docs/blob/4.x/installation.md Removes existing PHPUnit dependencies and installs Pest with all required dependencies. ```bash composer remove phpunit/phpunit composer require pestphp/pest --dev --with-all-dependencies ``` -------------------------------- ### Install Pest Stressless Plugin Source: https://github.com/pestphp/docs/blob/4.x/stress-testing.md Install the Pest Stressless plugin using Composer. This is a development dependency. ```bash composer require pestphp/pest-plugin-stressless --dev ``` -------------------------------- ### Install Pest Faker Plugin Source: https://github.com/pestphp/docs/blob/4.x/plugins.md Install the Pest Faker plugin using Composer. This plugin provides namespaced functions for generating fake data. ```bash composer require pestphp/pest-plugin-faker --dev ``` -------------------------------- ### Check for File Prefix Source: https://github.com/pestphp/docs/blob/4.x/arch-testing.md Ensures all files within a namespace start with a specific prefix. Useful for enforcing naming conventions. ```php arch('app') ->expect('App\Helpers') ->not->toHavePrefix('Helper'); ``` -------------------------------- ### Chipper CI Configuration for Pest Source: https://github.com/pestphp/docs/blob/4.x/continuous-integration.md Configure your `.chipperci.yml` file to set up PHP, Node.js, install dependencies, generate an application key, compile assets, and run Pest tests. Chipper CI automatically adds `vendor/bin` to your PATH. ```yaml version: 1 environment: php: 8.3 node: 16 # Optional services services: # - mysql: 8 # - redis: # Build all commits on: push: branches: .* pipeline: - name: Setup cmd: | cp -v .env.example .env composer install --no-interaction --prefer-dist --optimize-autoloader php artisan key:generate - name: Compile Assets cmd: | npm ci --no-audit npm run build - name: Test cmd: pest ``` -------------------------------- ### Pest Time-Balanced Sharding Data Example Source: https://github.com/pestphp/docs/blob/4.x/continuous-integration.md An example of the `tests/.pest/shards.json` file generated by Pest. This JSON file contains test class durations and is used for time-balanced test sharding. ```json { "timings": { "Tests\\Feature\\Payments\\StripeCheckoutTest": 1.608, "Tests\\Feature\\Reports\\SalesReportTest": 2.105, "Tests\\Unit\\Models\\UserTest": 0.050 }, "checksum": "...", "updated_at": "2026-04-14T10:30:00+00:00" } ``` -------------------------------- ### Install Pest Laravel Plugin Source: https://github.com/pestphp/docs/blob/4.x/plugins.md Install the Pest Laravel plugin via Composer. This plugin integrates Laravel's testing features with Pest. ```bash composer require pestphp/pest-plugin-laravel --dev ``` -------------------------------- ### Architectural Testing for Controllers Source: https://github.com/pestphp/docs/blob/4.x/pest-spicy-summer-release.md This example demonstrates advanced architectural testing using Pest's expectations. It checks controllers for strict types, specific suffixes, immutability, and inheritance/implementation constraints. ```php test('controllers') ->expect('App\Http\Controllers') ->toUseStrictTypes() ->toHaveSuffix('Controller') // or toHavePreffix, ... ->toBeReadonly() ->toBeClasses() // or toBeInterfaces, toBeTraits, ... ->classes->not->toBeFinal() // 🌶 ->classes->toExtendNothing() // or toExtend(Controller::class), ->classes->toImplementNothing() // or toImplement(ShouldQueue::class), ``` -------------------------------- ### Define a basic test in Pest Source: https://github.com/pestphp/docs/blob/4.x/why-pest.md A simple example demonstrating the test function and expectation API to verify a function's output. ```php function sum($a, $b) { return $a + $b; } test('sum', function () { $result = sum(1, 2); expect($result)->toBe(3); }); ``` -------------------------------- ### Install Pest Type Coverage Plugin Source: https://github.com/pestphp/docs/blob/4.x/type-coverage.md Require the Pest Type Coverage plugin using Composer. This is necessary to enable type coverage analysis. ```bash composer require pestphp/pest-plugin-type-coverage --dev ``` -------------------------------- ### Define comprehensive global hook chains Source: https://github.com/pestphp/docs/blob/4.x/global-hooks.md Chain multiple lifecycle hooks together in the configuration file to manage setup and teardown for specific test groups. ```php pest()->extend(TestCase::class)->beforeAll(function () { // Runs before each file... })->beforeEach(function () { // Runs before each test... })->afterEach(function () { // Runs after each test... })->afterAll(function () { // Runs after each file... })->group('integration')->in('Feature'); ``` -------------------------------- ### Initialize Pest configuration Source: https://github.com/pestphp/docs/blob/4.x/installation.md Creates a Pest.php configuration file in the test suite root directory. ```bash ./vendor/bin/pest --init ``` -------------------------------- ### Migrate PHPUnit tests to Pest with Drift Source: https://github.com/pestphp/docs/blob/4.x/pest-spicy-summer-release.md Example of a standard PHPUnit test class and its corresponding converted Pest test. ```php assertTrue(true); } } ``` ```php test('true is true', function () { expect(true)->toBeTrue(); }); ``` -------------------------------- ### Get Current URL Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Use the `url` method to get the URL of the currently loaded page. ```php $currentUrl = $page->url(); ``` -------------------------------- ### Get TIA Storage Path Source: https://github.com/pestphp/docs/blob/4.x/tia.md The `--baseline` flag prints the absolute path of the project's TIA storage directory and exits. This is primarily for CI uploads. ```bash ./vendor/bin/pest --baseline ``` -------------------------------- ### Configure Browser Server Host Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Set the host for the test server, useful for testing subdomains or different host configurations. Asserts welcome text for a subdomain. ```php $page = visit('/dashboard')->withHost('some-subdomain.localhost'); $page->assertSee('Welcome to Some Subdomain'); ``` -------------------------------- ### Write Stress Tests in Pest PHP Files Source: https://github.com/pestphp/docs/blob/4.x/announcing-stressless.md Integrate stress testing directly into your Pest PHP test files using the Stressless plugin. This example demonstrates testing a URL with specific concurrency and duration, and asserting the results. ```php concurrently(5) ->for(10)->seconds(); $requests = $result->requests; expect($requests->failed->count) ->toBe(0); expect($requests->duration->med) ->toBeLessThan(100.0); // 100ms }); ``` -------------------------------- ### Stress Test with HTTP Methods and Payloads Source: https://github.com/pestphp/docs/blob/4.x/stress-testing.md Demonstrates using various HTTP methods (delete, get, head, options, patch, put, post) with the `stress()` function, including optional and required payload arguments for certain methods. ```php $result = stress('example.com/articles/1')->delete(); // or $result = stress('example.com/articles')->get(); // or $result = stress('example.com/articles')->head(); // or $result = stress('example.com/articles')->options(); // or $result = stress('example.com/articles')->options(["name" => "Nuno"]); // or $result = stress('example.com/articles/1')->patch(); // or $result = stress('example.com/articles/1')->patch(["name" => "Nuno"]); // or $result = stress('example.com/articles')->put(); // or $result = stress('example.com/articles')->put(["name" => "Nuno"]); // or $result = stress('example.com/articles')->post(["name" => "Nuno"]); ``` -------------------------------- ### url Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Gets the page's URL. ```APIDOC ## url ### Description Gets the page's URL. ### Method ```php $page->url() ``` ``` -------------------------------- ### Browser Testing with Laravel Source: https://github.com/pestphp/docs/blob/4.x/pest-v4-is-here-now-with-browser-testing.md Demonstrates a browser test using Laravel helpers, database factories, and Playwright-based interactions. ```php it('may reset the password', function () { // access any laravel testing helpers... Notification::fake(); // access to the database — using the RefreshDatabase trait (even sqlite in memory...) $this->actingAs(User::factory()->create()); $page = visit('/sign-in') // visit on a real browser... ->on()->mobile() // or ->desktop(), ->tablet(), etc... ->inDarkMode(); // or ->inLightMode() $page->assertSee('Sign In') ->click('Forgot Password?') ->type('email', 'nuno@laravel.com') ->press('Send Reset Link') ->assertSee('We have emailed your password reset link!') ->assertNoJavascriptErrors(); // or ->assertNoConsoleLogs() Notification::assertSent(ResetPassword::class); }); ``` -------------------------------- ### Browser Testing with GitHub Actions Source: https://github.com/pestphp/docs/blob/4.x/continuous-integration.md This snippet extends the GitHub Actions workflow to include browser testing using Playwright. It installs Node.js, npm dependencies, Playwright browsers, and then runs Pest tests in parallel mode with the `--ci` flag. ```yaml - uses: actions/setup-node@v4 with: node-version: lts/* - name: Install dependencies run: npm ci - name: Install Playwright Browsers run: npx playwright install --with-deps - name: Run Browser Tests run: ./vendor/bin/pest --ci --parallel ``` -------------------------------- ### Stress Test with HTTP Methods Source: https://github.com/pestphp/docs/blob/4.x/stress-testing.md Specify the HTTP method for the stress test using options like `--get`, `--head`, `--options`, `--patch`, or `--post`. The `--post` method requires a payload. ```bash ./vendor/bin/pest stress example.com/articles ``` ```bash ./vendor/bin/pest stress example.com/articles --get ``` ```bash ./vendor/bin/pest stress example.com/articles --head ``` ```bash ./vendor/bin/pest stress example.com/articles --options ``` ```bash ./vendor/bin/pest stress example.com/articles --options='{"name": "Nuno"}' ``` ```bash ./vendor/bin/pest stress example.com/articles/1 --patch ``` -------------------------------- ### content Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Gets the page's content. ```APIDOC ## content ### Description Gets the page's content. ### Method ```php $page->content() ``` ``` -------------------------------- ### Run Pest Tests in GitHub Actions Source: https://github.com/pestphp/docs/blob/4.x/continuous-integration.md This YAML configuration sets up a GitHub Actions workflow to automatically run PestPHP tests on push and pull request events. It includes steps for checking out code, setting up PHP with Composer and xdebug, installing dependencies, and executing tests in CI mode. ```yaml name: Tests on: ['push', 'pull_request'] jobs: ci: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: 8.3 tools: composer:v2 coverage: xdebug - name: Install Dependencies run: composer install --no-interaction --prefer-dist --optimize-autoloader - name: Tests run: ./vendor/bin/pest --ci ``` -------------------------------- ### Navigate Between Pages Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md After visiting an initial page, this snippet demonstrates navigating to another page within the same browser context. ```php $page = visit('/'); $page->navigate('/about') ->assertSee('About Us'); ``` -------------------------------- ### Apply Datasets to Describe Blocks Source: https://github.com/pestphp/docs/blob/4.x/datasets.md Attach datasets to describe blocks or beforeEach hooks to share data across multiple tests within a scope. ```php describe('user notifications', function () { test('can send notification', function (string $channel) { expect($channel)->toBeString(); }); test('can queue notification', function (string $channel) { expect($channel)->toBeIn(['mail', 'sms']); }); })->with(['mail', 'sms']); ``` ```php describe('user settings', function () { beforeEach()->with([10, 20, 30]); test('receives the dataset value', function (int $value) { expect($value)->toBeGreaterThan(0); }); }); ``` -------------------------------- ### value Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Gets the value of the element matching the given selector. ```APIDOC ## value ### Description Gets the value of the element matching the given selector. ### Method ```php $page->value(string $selector) ``` ### Parameters #### Path Parameters - **selector** (string) - Required - The selector of the element to get the value from. ``` -------------------------------- ### text Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Gets the text of the element matching the given selector. ```APIDOC ## text ### Description Gets the text of the element matching the given selector. ### Method ```php $text = $page->text('.header'); ``` ``` -------------------------------- ### Configure Team Management Project Source: https://github.com/pestphp/docs/blob/4.x/pest3-now-available.md Set the project URL in Pest.php to link todos to a project management system. ```php pest()->project()->github('my-organization/my-repository'); ``` -------------------------------- ### Use beforeEach hook Source: https://github.com/pestphp/docs/blob/4.x/hooks.md Executes a closure before every test in the file. Use it to initialize shared properties. ```php beforeEach(function () { // Prepare something before each test run... }); ``` ```php beforeEach(function () { $this->userRepository = new UserRepository(); }); it('may be created', function () { $user = $this->userRepository->create(); expect($user)->toBeInstanceOf(User::class); }); ``` -------------------------------- ### attribute Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Gets the given attribute from the element matching the given selector. ```APIDOC ## attribute ### Description Gets the given attribute from the element matching the given selector. ### Method ```php $alt = $page->attribute('img', 'alt'); ``` ``` -------------------------------- ### Migrate to New Configuration API Source: https://github.com/pestphp/docs/blob/4.x/pest3-now-available.md Transition from the legacy uses function to the fluent pest configuration API. ```diff -uses(TestCase::class)->in(__DIR__); +pest()->extends(TestCase::class); -uses(TestCase::class, RefreshDatabase::class)->in('Features'); +pest()->extends(TestCase::class)->use(RefreshDatabase::class)->in('Features'); -uses()->compact(); +pest()->printer()->compact(); ``` -------------------------------- ### Accessing Failed Request Count Source: https://github.com/pestphp/docs/blob/4.x/stress-testing.md Get the number of requests that failed during the stress test. ```php $result->requests()->failed()->count(); ``` -------------------------------- ### Configure Default Browser to Safari Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Set Safari as the default browser for all Pest browser tests within the Pest.php configuration file. ```php pest()->browser()->inSafari(); ``` -------------------------------- ### Accessing Request Count Source: https://github.com/pestphp/docs/blob/4.x/stress-testing.md Get the total number of requests made during the stress test. ```php $result->requests()->count(); ``` -------------------------------- ### Configure Return Values and Exceptions Source: https://github.com/pestphp/docs/blob/4.x/mocking.md Define return values for mocked methods or instruct them to throw exceptions. ```php $client->shouldReceive('post')->andReturn('post response'); ``` ```php $client->shouldReceive('post')->andReturn(1, 2); $client->post(); // int(1) $client->post(); // int(2) ``` ```php $mock->shouldReceive('post') ->andReturnUsing( fn () => 1, fn () => 2, ); ``` ```php $client->shouldReceive('post')->andThrow(new Exception); ``` -------------------------------- ### Check for UUID Source: https://github.com/pestphp/docs/blob/4.x/expectations.md Ensures the given value is a valid UUID string. No setup is required. ```php expect('ca0a8228-cdf6-41db-b34b-c2f31485796c')->toBeUuid(); ``` -------------------------------- ### Check for URL Source: https://github.com/pestphp/docs/blob/4.x/expectations.md Ensures the given value is a valid URL string. No setup is required. ```php expect('https://pestphp.com/')->toBeUrl(); ``` -------------------------------- ### Basic Navigation Test Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md A fundamental test using `visit()` to navigate to a URL and assert the presence of specific text. ```php test('example', function () { $page = visit('/'); $page->assertSee('Welcome'); }); ``` -------------------------------- ### Use Custom Preset Source: https://github.com/pestphp/docs/blob/4.x/arch-testing.md Applies a previously defined custom preset named 'silex'. ```php arch()->preset()->silex(); ``` -------------------------------- ### Check for StudlyCase String Source: https://github.com/pestphp/docs/blob/4.x/expectations.md Ensures the given value is a string in StudlyCase format. No setup is required. ```php expect('StudlyCase')->toBeStudlyCase(); ``` -------------------------------- ### Run Stress Test from Command Line Source: https://github.com/pestphp/docs/blob/4.x/announcing-stressless.md Use this command to quickly stress test a given URL from the command line. Specify concurrency and duration as needed. ```bash ./vendor/bin/pest stress example.com --concurrency=5 --duration=10 ``` -------------------------------- ### Check for camelCase String Source: https://github.com/pestphp/docs/blob/4.x/expectations.md Ensures the given value is a string in camelCase format. No setup is required. ```php expect('camelCase')->toBeCamelCase(); ``` -------------------------------- ### Tested Mutation Example Source: https://github.com/pestphp/docs/blob/4.x/mutation-testing.md A mutation that is successfully detected by the test suite, causing the test to fail. ```diff class TodoController { public function index(): array { - return Todo::all()->toArray(); + return []; } } it('list todos', function () { Todo::factory()->create(['name' => 'Buy milk']); // this fails because the mutation changed the return value, proving that the test is working and testing the return value... $this->getJson('/todos')->assertStatus(200)->assertJsonContains([ ['name' => 'Buy milk'], ]); }); ``` -------------------------------- ### Wait for Key Press Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Use `waitForKey` to open the current URL and pause execution until a key is pressed, useful for debugging. ```php $page->waitForKey(); // Useful for debugging ``` -------------------------------- ### Run Tests in Headed Mode Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Use the `--headed` CLI option to run tests with the browser window visible. Configure default headed mode in `Pest.php`. ```bash ./vendor/bin/pest --headed ``` ```php pest()->browser()->headed(); ``` -------------------------------- ### Define Custom Preset with Namespaces Source: https://github.com/pestphp/docs/blob/4.x/arch-testing.md Defines a custom preset named 'silex' and accesses PSR-4 namespaces within the closure. Demonstrates how to use provided namespaces in custom preset definitions. ```php pest()->presets()->custom('silex', function (array $userNamespaces) { var_dump($userNamespaces); // array(1) { [0]=> string(3) "App" } return [ expect($userNamespaces)->toBeArray(), ]; }); ``` -------------------------------- ### Get Page Content Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Use the `content` method to retrieve the entire HTML content of the current page. ```php $html = $page->content(); ``` -------------------------------- ### Generate coverage report Source: https://github.com/pestphp/docs/blob/4.x/test-coverage.md Run the test suite with coverage reporting enabled. ```bash ./vendor/bin/pest --coverage ``` -------------------------------- ### Get Element Value Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Use the `value` method to retrieve the current value of an input element identified by a selector. ```php $value = $page->value('input[name=email]'); ``` -------------------------------- ### Check for StudlyCase Array Keys Source: https://github.com/pestphp/docs/blob/4.x/expectations.md Ensures the given value is an array where all keys are in StudlyCase format. No setup is required. ```php expect(['StudlyCase' => 'abc123'])->toHaveStudlyCaseKeys(); ``` -------------------------------- ### Run TIA with Baseline Fetching Source: https://github.com/pestphp/docs/blob/4.x/tia.md Enable TIA to replay existing graphs or record new ones. Use `--baselined` to opt into fetching a shared baseline from CI when no local graph exists or the local graph drifts. ```bash ./vendor/bin/pest --tia --baselined ``` -------------------------------- ### Check for camelCase Array Keys Source: https://github.com/pestphp/docs/blob/4.x/expectations.md Ensures the given value is an array where all keys are in camelCase format. No setup is required. ```php expect(['camelCase' => 'abc123'])->toHaveCamelCaseKeys(); ``` -------------------------------- ### Check for kebab-case Array Keys Source: https://github.com/pestphp/docs/blob/4.x/expectations.md Ensures the given value is an array where all keys are in kebab-case format. No setup is required. ```php expect(['kebab-case' => 'abc123'])->toHaveKebabCaseKeys(); ``` -------------------------------- ### Run Basic Stress Test Source: https://github.com/pestphp/docs/blob/4.x/stress-testing.md Quickly stress test a URL using the `pest stress` command. The default duration is 5 seconds. ```bash ./vendor/bin/pest stress example.com ``` -------------------------------- ### Basic Object Property and Method Expectations Source: https://github.com/pestphp/docs/blob/4.x/higher-order-testing.md Use this to test object properties and method return values directly. Ensure the properties and methods exist on the object. ```php expect($user->name)->toBe('Nuno'); expect($user->surname)->toBe('Maduro'); expect($user->addTitle('Mr.'))->toBe('Mr. Nuno Maduro'); ``` -------------------------------- ### Check for snake_case Array Keys Source: https://github.com/pestphp/docs/blob/4.x/expectations.md Ensures the given value is an array where all keys are in snake_case format. No setup is required. ```php expect(['snake_case' => 'abc123'])->toHaveSnakeCaseKeys(); ``` -------------------------------- ### Configure Browser Host Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Set the host for browser tests, useful for subdomain applications. Configure in `Pest.php`. ```php pest()->browser()->withHost('some-subdomain.localhost'); ``` -------------------------------- ### Verify Property Documentation with toHavePropertiesDocumented Source: https://github.com/pestphp/docs/blob/4.x/arch-testing.md Ensures all properties within a namespace have documentation. ```php arch('app') ->expect('App') ->toHavePropertiesDocumented(); ``` -------------------------------- ### Verify Method Documentation with toHaveMethodsDocumented Source: https://github.com/pestphp/docs/blob/4.x/arch-testing.md Ensures all methods within a namespace have documentation. ```php arch('app') ->expect('App') ->toHaveMethodsDocumented(); ``` -------------------------------- ### Untested Mutation Example Source: https://github.com/pestphp/docs/blob/4.x/mutation-testing.md A mutation that remains undetected by the test suite, allowing the test to pass despite the code change. ```diff class TodoController { public function index(): array { - return Todo::all()->toArray(); + return []; } } it('list todos', function () { Todo::factory()->create(['name' => 'Buy milk']); // this test still passes even though the return value was changed by the mutation... $this->getJson('/todos')->assertStatus(200); }); ``` -------------------------------- ### View Pest project structure Source: https://github.com/pestphp/docs/blob/4.x/writing-tests.md Displays the standard directory layout for a Pest-enabled project. ```plain ├── 📂 tests │ ├── 📂 Unit │ │ └── ExampleTest.php │ └── 📂 Feature │ │ └── ExampleTest.php │ └── TestCase.php │ └── Pest.php ├── phpunit.xml ``` -------------------------------- ### Run Todos via CLI Source: https://github.com/pestphp/docs/blob/4.x/pest3-now-available.md Filter and view todos from the console using the --todos option. ```bash ./vendor/bin/pest --todos --assignee=taylor # or --issue=123 ``` -------------------------------- ### Snapshot Test for Array Data Source: https://github.com/pestphp/docs/blob/4.x/pest-spicy-summer-release.md Snapshot testing can be applied to any data type, not just responses. This example shows how to snapshot an array. ```php $array = /** Fetch array somewhere */; expect($array)->toMatchSnapshot(); ``` -------------------------------- ### Execute Pest tests Source: https://github.com/pestphp/docs/blob/4.x/installation.md Runs the test suite using the Pest binary. ```bash ./vendor/bin/pest ``` -------------------------------- ### Run test with simple dataset Source: https://github.com/pestphp/docs/blob/4.x/datasets.md Executes the test for each element in the provided array. ```php it('has emails', function (string $email) { expect($email)->not->toBeEmpty(); })->with(['enunomaduro@gmail.com', 'other@example.com']); ``` -------------------------------- ### Get Element Text Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Retrieves the text content of the element matching the given CSS selector. Useful for verifying visible text on the page. ```php $text = $page->text('.header'); ``` -------------------------------- ### Handling Failing Parent Tests Source: https://github.com/pestphp/docs/blob/4.x/test-dependencies.md If a parent test fails, the dependent child test will be bypassed. This example shows a failing parent test. ```php test('parent', function () { expect(true)->toBeFalse(); }); test('child', function () { expect(false)->toBeFalse(); })->depends('parent'); ``` -------------------------------- ### expect()->toBeKebabCase() Source: https://github.com/pestphp/docs/blob/4.x/expectations.md Ensures that the value is in kebab-case format. ```APIDOC ## `toBeKebabCase()` ### Description This expectation ensures that `$value` only contains string in kebab-case format. ### Method `toBeKebabCase` ### Endpoint N/A (Assertion method) ### Request Example ```php expect('kebab-case')->toBeKebabCase(); ``` ### Response N/A (Assertion result) ``` -------------------------------- ### Configure Browser User-Agent Header Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Set the User-Agent header for test requests, useful for simulating different clients like mobile browsers or bots. Asserts a welcome message for bots. ```php $page = visit('/')->withUserAgent('Googlebot'); $page->assertSee('Welcome, bot!'); ``` -------------------------------- ### waitForKey Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Opens the current page URL and waits for a key press. ```APIDOC ## waitForKey ### Description Opens the current page URL in the default web browser and waits for a key press. ### Method ```php $page->waitForKey() ``` ``` -------------------------------- ### Use Custom Plugin Function in a Test Source: https://github.com/pestphp/docs/blob/4.x/creating-plugins.md Once the plugin is installed and autoloading is configured, users can import and use your custom functions within their test files. ```php use function YourGitHubUsername\PestPluginName\{myPluginFunction}; test('plugin example', function () { myPluginFunction(); // ... }) ``` -------------------------------- ### Use Custom Plugin Method in a Test Source: https://github.com/pestphp/docs/blob/4.x/creating-plugins.md After installing the plugin, users can invoke the custom methods defined in your plugin directly on the `$this` variable within their test closures. ```php test('plugin example', function () { $this->myPluginMethod(); // }) ``` -------------------------------- ### Create a Todo Item Source: https://github.com/pestphp/docs/blob/4.x/team-management.md Use the `todo()` method on a test to mark it as a task. Pest will highlight these in test results. Run with `--todos` to view only todo items. ```php it('has a contact page', function () { // })->todo(); ``` -------------------------------- ### Verify Traits with toBeTraits Source: https://github.com/pestphp/docs/blob/4.x/arch-testing.md Ensures all files within a namespace are traits. ```php arch('app') ->expect('App\Concerns') ->toBeTraits(); ``` -------------------------------- ### Get Element Attribute Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Retrieves the value of a specified attribute from the element matching the given CSS selector. Commonly used for 'alt', 'href', or 'src' attributes. ```php $alt = $page->attribute('img', 'alt'); ``` -------------------------------- ### Pest CLI Configuration Options Source: https://github.com/pestphp/docs/blob/4.x/cli-api-reference.md Options related to initializing, configuring, and managing Pest's settings and environment. ```APIDOC ## Configuration Options ### Description Options for initializing, configuring, and managing Pest settings. ### Method CLI Command ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example N/A ### Response N/A ## CLI Options - `--init`: Initialize a standard Pest configuration. - `--bootstrap `: A PHP script that is included before the tests run. - `-c|--configuration `: Read configuration from XML file. - `--no-configuration`: Ignore default configuration file (phpunit.xml). - `--extension `: Register test runner extension with bootstrap . - `--no-extensions`: Do not load PHPUnit extensions. - `--include-path `: Prepend PHP's include_path with given path(s). - `-d `: Set a php.ini value. - `--cache-directory `: Specify cache directory. - `--generate-configuration`: Generate configuration file with suggested settings. - `--migrate-configuration`: Migrate configuration file to current format. - `--generate-baseline `: Generate baseline for issues. - `--use-baseline `: Use baseline to ignore issues. - `--ignore-baseline`: Do not use baseline to ignore issues. - `--test-directory`: Specify test directory containing Pest.php, TestCase.php, helpers and your tests. Default: tests ``` -------------------------------- ### Authenticated User Test with Namespaced Functions Source: https://github.com/pestphp/docs/blob/4.x/plugins.md Illustrates using namespaced functions like `actingAs` and `get` for authenticated user tests in Pest with the Laravel plugin. ```php use App\Models\User; use function Pest\Laravel\{actingAs}; test('authenticated user can access the dashboard', function () { $user = User::factory()->create(); actingAs($user)->get('/dashboard') ->assertStatus(200); }); ``` -------------------------------- ### Basic Stress Test with Assertion Source: https://github.com/pestphp/docs/blob/4.x/stress-testing.md Use the `stress()` function to perform a stress test on a URL and assert the response time. Requires importing `stress` function. ```php requests()->duration()->med())->toBeLessThan(100); // < 100.00ms }); ``` -------------------------------- ### Skip a test with a deferred condition Source: https://github.com/pestphp/docs/blob/4.x/skipping-tests.md Use a closure as the first argument to skip() to defer the condition evaluation until after the beforeEach() hook. This is useful for conditions that depend on setup. ```php it('has home', function () { // })->skip(fn () => DB::getDriverName() !== 'mysql', 'db driver not supported'); ``` -------------------------------- ### Combine Todos with Assignees, Issues, and PRs Source: https://github.com/pestphp/docs/blob/4.x/team-management.md Use `describe`, `it`, `issue`, `pr`, `done`, and `wip` methods to associate tests with external tracking items. This helps in tracking progress and providing context for each test case. ```php describe('contacts', function () { it('has a contact page', function () { // }))->issue(123); // or ->pr(123) etc it('has a contact form', function () { // })->done(pr: 567); })->wip(assignee: 'nunomaduro'); ``` -------------------------------- ### Use Namespaced HTTP Functions in Pest Laravel Source: https://github.com/pestphp/docs/blob/4.x/plugins.md Bypass the `$this` variable and use namespaced functions like `get` for making HTTP requests in Pest Laravel tests. ```php use function Pest\Laravel\{get}; it('has a welcome page', function () { get('/')->assertStatus(200); // same as $this->get('/')... }); ``` -------------------------------- ### Take Screenshot Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Use `screenshot()` to capture an image of the current page. Optionally specify `fullPage: true` or a custom `filename`. ```php $page->screenshot(); $page->screenshot(fullPage: true); $page->screenshot(filename: 'custom-name'); ``` -------------------------------- ### Define a Custom Expectation: toBeWithinRange Source: https://github.com/pestphp/docs/blob/4.x/custom-expectations.md Define a custom expectation `toBeWithinRange` by chaining `extend()` onto `expect()`. This example uses built-in expectations for assertions and returns `$this` to allow chaining. ```php // Pest.php or Expectations.php expect()->extend('toBeWithinRange', function (int $min, int $max) { return $this->toBeGreaterThanOrEqual($min) ->toBeLessThanOrEqual($max); }); // Tests/Unit/ExampleTest.php test('numeric ranges', function () { expect(100)->toBeWithinRange(90, 110); }); ``` -------------------------------- ### expect()->toBeReadableDirectory() Source: https://github.com/pestphp/docs/blob/4.x/expectations.md Ensures that the value is a readable directory. ```APIDOC ## `toBeReadableDirectory()` ### Description This expectation ensures that the string `$value` is a directory and that it is readable. ### Method `toBeReadableDirectory` ### Endpoint N/A (Assertion method) ### Request Example ```php expect('/tmp')->toBeReadableDirectory(); ``` ### Response N/A (Assertion result) ``` -------------------------------- ### Run Pest Browser Tests Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Command to execute all Pest tests, including browser tests. ```bash ./vendor/bin/pest ``` -------------------------------- ### Snapshot Test for API Response Source: https://github.com/pestphp/docs/blob/4.x/pest-spicy-summer-release.md Use `toMatchSnapshot` to assert that the output of a function or method has not changed. The first run creates a snapshot file; subsequent runs compare against it. This example tests an API response. ```php it('has a contact page', function () { $response = $this->get('/contact'); expect($response)->toMatchSnapshot(); }); ``` -------------------------------- ### Trigger Test Failure in Custom Expectation Source: https://github.com/pestphp/docs/blob/4.x/custom-expectations.md Use `test()->fail()` within a custom expectation to explicitly trigger a test failure with a custom message, for example, when a condition like division by zero is met. ```php // Pest.php or Expectations.php expect()->extend('toBeDivisibleBy', function (int $divisor) { if ($divisor === 0) { test()->fail('The divisor cannot be 0.'); } return expect($this->value % $divisor)->toBe(0); }); // Tests/Unit/ExampleTest.php test('numeral division', function () { expect(10)->toBeDivisibleBy(2); // Pass expect(10)->toBeDivisibleBy(0); // Fail "The divisor cannot be 0." }); ``` -------------------------------- ### expect()->toBeDirectory() Source: https://github.com/pestphp/docs/blob/4.x/expectations.md Ensures that the value is a directory. ```APIDOC ## `toBeDirectory()` ### Description This expectation ensures that the string `$value` is a directory. ### Method `toBeDirectory` ### Endpoint N/A (Assertion method) ### Request Example ```php expect('/tmp')->toBeDirectory(); ``` ### Response N/A (Assertion result) ``` -------------------------------- ### Enable Baselined TIA Mode Source: https://github.com/pestphp/docs/blob/4.x/tia.md Opt in to fetching the shared TIA baseline from CI when no local graph exists or the local graph drifts. This is equivalent to running with `--tia --baselined`. ```php pest()->tia()->baselined(); ``` -------------------------------- ### Force CI Baseline Fetch Source: https://github.com/pestphp/docs/blob/4.x/tia.md Use `--refetch` to force a CI baseline fetch, even if it's within the 24-hour cooldown period after a previous failed fetch. ```bash ./vendor/bin/pest --tia --refetch ``` -------------------------------- ### Convert Specific Directory Source: https://github.com/pestphp/docs/blob/4.x/migrating-from-phpunit-guide.md Target a specific folder for migration by passing the path as an argument to the drift command. ```console /vendor/bin/pest --drift tests/Helpers ``` ```console /vendor/bin/pest --drift tests/Helpers ✔✔✔✔✔✔✔✔✔✔✔✔✔✔✔✔✔✔✔✔✔✔✔✔✔✔ INFO The [tests/Helpers] directory has been migrated to PEST with XY files changed. ``` -------------------------------- ### Run Pest Tests in GitLab CI/CD Source: https://github.com/pestphp/docs/blob/4.x/continuous-integration.md This GitLab CI/CD configuration defines stages for building and testing. It installs Composer dependencies in the build stage and then runs PestPHP tests in CI mode in the test stage, utilizing caching for composer.lock. ```yaml stages: - build - test build:vendors: stage: build only: refs: - merge_requests - push cache: key: files: - composer.lock policy: pull-push image: composer:2 script: - composer install --no-interaction --prefer-dist --optimize-autoloader tests: stage: test only: refs: - merge_requests - push cache: key: files: - composer.lock policy: pull image: php:8.2 script: - ./vendor/bin/pest --ci ``` -------------------------------- ### Verify Interfaces with toBeInterfaces Source: https://github.com/pestphp/docs/blob/4.x/arch-testing.md Ensures all files within a namespace are interfaces. ```php arch('app') ->expect('App\Contracts') ->toBeInterfaces(); ``` -------------------------------- ### Press Button and Wait Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Use `pressAndWaitFor` to click a button and pause execution for a specified duration. ```php $page->pressAndWaitFor('Submit', 2); // Wait for 2 seconds ``` -------------------------------- ### Enable Mutation Testing with covers() Source: https://github.com/pestphp/docs/blob/4.x/pest3-now-available.md To enable mutation testing, specify the code covered by your test using the `covers()` function. This helps ensure your tests are thoroughly evaluating your application. ```php covers(TodoController::class); it('list todos', function () { $this->getJson('/todos')->assertStatus(200); }); ``` -------------------------------- ### Migrate PHPUnit Configuration Source: https://github.com/pestphp/docs/blob/4.x/upgrade-guide.md If you encounter a deprecated schema warning for your `phpunit.xml` file, run Pest with the `--migrate-configuration` option to update it. ```bash ./vendor/bin/pest --migrate-configuration ``` -------------------------------- ### Visit Mobile Viewport Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Navigates to a URL and sets the viewport to a mobile device size. ```php $page = visit('/')->on()->mobile(); ``` -------------------------------- ### Configure Project URL in Pest Source: https://github.com/pestphp/docs/blob/4.x/team-management.md Specify the project's URL in your `Pest.php` configuration file to link todos to your project management system. Supports GitHub, GitLab, Bitbucket, Jira, and custom URLs. ```php pest()->project()->github('my-organization/my-repository'); ``` -------------------------------- ### Verify Interface Implementation with toImplement Source: https://github.com/pestphp/docs/blob/4.x/arch-testing.md Ensures all classes within a namespace implement a specific interface. ```php arch('app') ->expect('App\Jobs') ->toImplement('Illuminate\Contracts\Queue\ShouldQueue'); ``` -------------------------------- ### expect()->toBeWritableDirectory() Source: https://github.com/pestphp/docs/blob/4.x/expectations.md Ensures that the value is a writable directory. ```APIDOC ## `toBeWritableDirectory()` ### Description This expectation ensures that the string `$value` is a directory and that it is writable. ### Method `toBeWritableDirectory` ### Endpoint N/A (Assertion method) ### Request Example ```php expect('/tmp')->toBeWritableDirectory(); ``` ### Response N/A (Assertion result) ``` -------------------------------- ### Combine Datasets Source: https://github.com/pestphp/docs/blob/4.x/datasets.md Chain multiple with() calls to combine datasets using a cartesian product approach. ```php dataset('days_of_the_week', [ 'Saturday', 'Sunday', ]); test('business is closed on day', function(string $business, string $day) { expect(new $business)->isClosed($day)->toBeTrue(); })->with([ Office::class, Bank::class, School::class ])->with('days_of_the_week'); ``` -------------------------------- ### Generate Pest Test Timing Data in Parallel Source: https://github.com/pestphp/docs/blob/4.x/continuous-integration.md Speed up the generation of test timing data by combining `--parallel` with `--update-shards`. This helps in creating a more accurate `tests/.pest/shards.json` file faster. ```bash ./vendor/bin/pest --parallel --update-shards ``` -------------------------------- ### Configure Default Browser to Firefox Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Set Firefox as the default browser for all Pest browser tests within the Pest.php configuration file. ```php pest()->browser()->inFirefox(); ``` -------------------------------- ### Applying multiple test case classes and traits Source: https://github.com/pestphp/docs/blob/4.x/configuring-tests.md Uses a pattern to match multiple directories while applying both a base test case class and a trait. ```php // tests/Pest.php pest() ->extend(DuskTestCase::class) ->use(DatabaseMigrations::class) ->in('../Modules/*/Tests/Browser'); // This will apply the DuskTestCase class and the DatabaseMigrations trait to all test files within any module's "Browser" directory. ``` -------------------------------- ### Using glob patterns for test configuration Source: https://github.com/pestphp/docs/blob/4.x/configuring-tests.md Applies a base test case class to multiple files using glob patterns in the in() method. ```php // tests/Pest.php pest()->extend(Tests\TestCase::class)->in('Feature/*Job*.php'); // This will apply the Tests\TestCase to all test files in the "Feature" directory that contains "Job" in their filename. ``` -------------------------------- ### Create and Assign Todos Source: https://github.com/pestphp/docs/blob/4.x/pest3-now-available.md Use the todo method to track tasks, optionally assigning them to members or linking to issues. ```php it('has a contact page', function () { // })->todo(assignee: 'taylor@laravel.com', issue: 123); ``` -------------------------------- ### Skip tests based on environment Source: https://github.com/pestphp/docs/blob/4.x/skipping-tests.md Use skipLocally() to skip tests when running locally, or skipOnCi() to skip tests when running in a CI environment. ```php it('has home', function () { // })->skipLocally(); // or skipOnCi() ``` -------------------------------- ### Assert URL Host Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Use `assertHostIs` to check if the URL's host matches. Use `assertHostIsNot` to ensure it does not match a specific host. ```php $page->assertHostIs('example.com'); ``` ```php $page->assertHostIsNot('wrong-domain.com'); ``` -------------------------------- ### Run specific test file Source: https://github.com/pestphp/docs/blob/4.x/filtering-tests.md Execute a single test file by passing its path as an argument. ```bash ./vendor/bin/pest tests/Unit/TestExample.php ``` -------------------------------- ### Press Button Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Use the `press` method to simulate a button click based on its text or name. ```php $page->press('Submit'); ``` -------------------------------- ### Run Mutation Testing in Pest Source: https://github.com/pestphp/docs/blob/4.x/pest3-now-available.md After configuring your tests with `covers()`, run Pest with the `--mutate` option to initiate mutation testing. ```bash ./vendor/bin/pest --mutate ``` -------------------------------- ### Run mutation testing via CLI Source: https://github.com/pestphp/docs/blob/4.x/mutation-testing.md Execute mutation testing using the --mutate flag, optionally with --parallel for faster performance. ```bash ./vendor/bin/pest --mutate # or in parallel... ./vendor/bin/pest --mutate --parallel ``` -------------------------------- ### Basic Browser Test Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md A simple test to verify if the homepage displays expected content. ```php it('may welcome the user', function () { $page = visit('/'); $page->assertSee('Welcome'); }); ``` -------------------------------- ### Run tests only on specific operating systems Source: https://github.com/pestphp/docs/blob/4.x/skipping-tests.md Use onlyOnWindows(), onlyOnMac(), or onlyOnLinux() to run tests exclusively on the specified operating system. ```php it('has home', function() { // })->onlyOnWindows(); // or onlyOnMac() or onlyOnLinux() ... ``` -------------------------------- ### Run Drift Conversion Source: https://github.com/pestphp/docs/blob/4.x/migrating-from-phpunit-guide.md Execute the drift command to automatically transform PHPUnit tests into Pest tests. ```bash ./vendor/bin/pest --drift ``` -------------------------------- ### Visit Multiple Pages and Assertions Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Visits an array of URLs simultaneously and performs global assertions on all visited pages. ```php $pages = visit(['/', '/about']); $pages->assertNoSmoke() ->assertNoAccessibilityIssues() ->assertNoConsoleLogs() ->assertNoJavaScriptErrors(); [$homePage, $aboutPage] = $pages; $homePage->assertSee('Welcome to our website'); $aboutPage->assertSee('About Us'); ``` -------------------------------- ### Run Pest Tests with Safari Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Command to run Pest tests specifically using the Safari browser. ```bash ./vendor/bin/pest --browser safari ``` -------------------------------- ### Verify Invokable Classes with toBeInvokable Source: https://github.com/pestphp/docs/blob/4.x/arch-testing.md Ensures all files within a namespace are invokable. ```php arch('app') ->expect('App\Actions') ->toBeInvokable(); ``` -------------------------------- ### Multiple Test Dependencies Source: https://github.com/pestphp/docs/blob/4.x/test-dependencies.md A test can depend on multiple parent tests. All parent tests must pass, and their return values are available as arguments in the order they are specified. ```php test('a', function () { expect(true)->toBeTrue(); return 'a'; }); test('b', function () { expect(true)->toBeTrue(); return 'b'; }); test('c', function () { expect(true)->toBeTrue(); return 'c'; }); test('d', function ($testA, $testC, $testB) { var_dump($testA); // a var_dump($testB); // b var_dump($testC); // c })->depends('a', 'b', 'c'); ``` -------------------------------- ### Configure PHPUnit source coverage Source: https://github.com/pestphp/docs/blob/4.x/test-coverage.md Add this configuration to your phpunit.xml file to specify which directories should be included in coverage reports. ```xml ./app ``` -------------------------------- ### press Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md Presses the button with the given text or name. ```APIDOC ## press ### Description Presses the button with the given text or name. ### Method ```php $page->press(string $buttonTextOrName) ``` ### Parameters #### Path Parameters - **buttonTextOrName** (string) - Required - The text or name of the button to press. ``` -------------------------------- ### Skip a test with a reason Source: https://github.com/pestphp/docs/blob/4.x/skipping-tests.md Provide a reason string to the skip() method to explain why the test is skipped. This reason will be displayed when running tests. ```php it('has home', function () { // })->skip('temporarily unavailable'); ```