### GitHub Actions CI Setup for Playwright Source: https://pestphp.com/docs/browser-testing Steps required in a GitHub Actions workflow file to set up Node.js, install dependencies, and install Playwright browsers for running browser tests in CI. ```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 ``` -------------------------------- ### Install Mockery Source: https://pestphp.com/docs/mocking Install Mockery using Composer. This is a development dependency. ```bash composer require mockery/mockery --dev ``` -------------------------------- ### GitHub Actions Browser Testing Setup Source: https://pestphp.com/docs/continuous-integration Add steps to install Node.js, npm dependencies, and Playwright browsers before running browser tests in GitHub Actions. Run tests in parallel for faster execution. ```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 ``` -------------------------------- ### toStartWith Source: https://pestphp.com/docs/expectations 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 `expect()` ### Parameters #### Path Parameters - **expected** (string) - Required - The string to check for at the beginning. ### Request Example ```php expect('Hello World')->toStartWith('Hello'); ``` ``` -------------------------------- ### Pest Type Coverage Output Example Source: https://pestphp.com/docs/pest-spicy-summer-release Example output from running `pest --type-coverage`, indicating missing parameter and return types. ```bash ...\napp/Models\User.php .......................................... 100%\napp/Repositories/UserRepository.php .................. pa8, rt8 33%\n───────────────────────────────────────────────────────────────────\nTotal: 91.6 % ``` -------------------------------- ### Install Pest Livewire Plugin Source: https://pestphp.com/docs/plugins Install the Pest Livewire plugin using Composer. This plugin enables testing of Livewire components within Pest. ```bash composer require pestphp/pest-plugin-livewire --dev ``` -------------------------------- ### Install Pest Drift Plugin Source: https://pestphp.com/docs/migrating-from-phpunit-guide Install the Pest Drift plugin as a dev dependency to enable automatic test conversion. ```bash composer require pestphp/pest-plugin-drift --dev ``` -------------------------------- ### Check if string starts with a prefix Source: https://pestphp.com/docs/expectations Use `toStartWith` to assert that a string begins with a specified substring. ```php expect('Hello World')->toStartWith('Hello'); ``` -------------------------------- ### GitHub Actions: Time-Balanced Sharding Example Source: https://pestphp.com/docs/continuous-integration Configure GitHub Actions to run PestPHP tests using time-balanced sharding. This example demonstrates how to set up a matrix strategy for parallel test execution across multiple shards. ```yaml strategy: matrix: shard: [1, 2, 3, 4, 5] name: Tests (Shard ${{ matrix.shard }}/5) steps: - name: Run tests run: ./vendor/bin/pest --shard=${{ matrix.shard }}/5 ``` -------------------------------- ### Install Pest Browser Plugin and Playwright Source: https://pestphp.com/docs/pest-v4-is-here-now-with-browser-testing Installs the Pest Browser Plugin and Playwright, essential for enabling browser testing capabilities in Pest v4. ```bash composer require pestphp/pest-plugin-browser --dev npm install playwright@latest npx playwright install ``` -------------------------------- ### Pest Hooks Example with Nested Describes Source: https://pestphp.com/docs/hooks Demonstrates how to use `beforeEach` hooks within nested `describe` blocks to manage scope. ```php beforeEach(function () { // }); describe('something', function () { beforeEach(function () { // }); // describe('something else', function () { beforeEach(function () { // }); // }); }); test('something', function () { // }); ``` -------------------------------- ### Shard Pest Tests (Basic) Source: https://pestphp.com/docs/continuous-integration Use the `--shard` option to split your test suite into smaller groups for parallel execution. This example runs the first shard out of five. ```bash ./vendor/bin/pest --shard=1/5 ``` -------------------------------- ### Run Pest Tests Source: https://pestphp.com/docs/installation Execute your tests using the pest command after installation and initialization. ```bash ./vendor/bin/pest ``` -------------------------------- ### Basic Page Visit and Assertion Source: https://pestphp.com/docs/browser-testing Demonstrates the fundamental `visit()` method to navigate to a URL and `assertSee()` to check for specific text content on the page. This is the starting point for most browser tests. ```php test('example', function () { $page = visit('/'); $page->assertSee('Welcome'); }); ``` -------------------------------- ### GitLab CI/CD Pipeline Configuration Source: https://pestphp.com/docs/continuous-integration Configure GitLab CI/CD to install Composer dependencies and run PestPHP tests. This setup includes caching for composer.lock to speed up builds. ```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 ``` -------------------------------- ### Install Pest Stressless Plugin Source: https://pestphp.com/docs/stress-testing 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://pestphp.com/docs/plugins Install the Pest Faker plugin using Composer. This plugin provides namespaced functions for generating fake data. ```bash composer require pestphp/pest-plugin-faker --dev ``` -------------------------------- ### PHPUnit Test Example Source: https://pestphp.com/docs/migrating-from-phpunit-guide A typical PHPUnit test case structure. ```php assertTrue(true); } } ``` -------------------------------- ### Install Pest Type Coverage Plugin Source: https://pestphp.com/docs/type-coverage Require the plugin via Composer to enable type coverage analysis. ```bash composer require pestphp/pest-plugin-type-coverage --dev ``` -------------------------------- ### Mutation Testing Result Example Source: https://pestphp.com/docs/mutation-testing Example output showing an untested mutation, highlighting the specific code change and its impact on the mutation score. ```diff UNTESTED app/Http/TodoController.php > Line 44: ReturnValue - ID: 76d17ad63bb7c307 class TodoController { public function index(): array { // pest detected that this code is untested because // the test is not covering the return value - return Todo::all()->toArray(); + return []; } } Mutations: 1 untested Score: 33.44% ``` -------------------------------- ### Install Pest PHP Testing Framework Source: https://pestphp.com/docs/installation Add Pest as a dev dependency using Composer. This command removes PHPUnit and installs Pest with all its dependencies. ```bash composer remove phpunit/phpunit composer require pestphp/pest --dev --with-all-dependencies ``` -------------------------------- ### Configure Chipper CI for Pest Tests Source: https://pestphp.com/docs/continuous-integration Add this configuration to your `.chipperci.yml` file to set up PHP, Node.js, and run Composer/NPM installations, generate keys, and execute Pest tests. ```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 ``` -------------------------------- ### Complex User Sign-in Test with Laravel Features Source: https://pestphp.com/docs/browser-testing This example demonstrates a comprehensive browser test for user sign-in, leveraging Laravel's testing utilities like database seeding, event faking, and authentication assertions. It also shows how to specify the browser and device type. ```php it('may sign in the user', function () { Event::fake(); User::factory()->create([ 'email' => 'nuno@laravel.com', 'password' => 'password', ]); $page = visit('/')->on()->mobile()->firefox(); $page->click('Sign In') ->assertUrlIs('/login') ->assertSee('Sign In to Your Account') ->fill('email', 'nuno@laravel.com') ->fill('password', 'password') ->click('Submit') ->assertSee('Dashboard'); $this->assertAuthenticated(); Event::assertDispatched(UserLoggedIn::class); }); ``` -------------------------------- ### Install Pest Laravel Plugin Source: https://pestphp.com/docs/plugins Install the Pest Laravel plugin using Composer. This plugin integrates Laravel's testing features with Pest. ```bash composer require pestphp/pest-plugin-laravel --dev ``` -------------------------------- ### PHPUnit Test Example Source: https://pestphp.com/docs/pest-spicy-summer-release A standard PHPUnit test case that will be converted by the Drift plugin. ```php assertTrue(true); } } ``` -------------------------------- ### Install Pest Profanity Plugin Source: https://pestphp.com/docs/profanity Install the Profanity plugin for PestPHP using Composer. This is a development dependency. ```bash composer require pestphp/pest-plugin-profanity --dev ``` -------------------------------- ### Basic Test with Pest Source: https://pestphp.com/docs/why-pest Demonstrates a simple PHP function and a Pest test case using the expect API to assert the function's output. Ensure Pest is installed and configured for your project. ```php function sum($a, $b) { return $a + $b; } test('sum', function () { $result = sum(1, 2); expect($result)->toBe(3); }); ``` -------------------------------- ### Start Mutation Testing with Pest PHP Source: https://pestphp.com/docs/pest3-now-available Use the `covers()` function to specify code coverage for a test. Then, run Pest with the `--mutate` option to begin mutation testing. ```php covers(TodoController::class); it('list todos', function () { $this->getJson('/todos')->assertStatus(200); }); ``` ```bash ./vendor/bin/pest --mutate # or in parallel... ./vendor/bin/pest --mutate --parallel ``` -------------------------------- ### Tested Mutation Example Source: https://pestphp.com/docs/mutation-testing Demonstrates a mutation that is detected by the test suite. The test fails due to the change, proving the test is working. ```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'], ]); }); ``` -------------------------------- ### Assert URL Fragment Begins With Source: https://pestphp.com/docs/browser-testing Use to check if the URL's hash fragment starts with the given string. ```php $page->assertFragmentBeginsWith('section'); ``` -------------------------------- ### Ensure files do not have a specific prefix Source: https://pestphp.com/docs/arch-testing Use `not->toHavePrefix()` to assert that files within a namespace do not start with the specified string. ```php arch('app') ->expect('App\Helpers') ->not->toHavePrefix('Helper'); ``` -------------------------------- ### Converted Pest Test Example Source: https://pestphp.com/docs/migrating-from-phpunit-guide The equivalent Pest test case after conversion from PHPUnit. ```php test('true is true', function () { expect(true)->toBeTrue(); }); ``` -------------------------------- ### Assert URL Path Begins With Source: https://pestphp.com/docs/browser-testing Use to check if the current URL path starts with the given path segment. ```php $page->assertPathBeginsWith('/users'); ``` -------------------------------- ### Using Describe Blocks for Test Grouping Source: https://pestphp.com/docs/pest-spicy-summer-release Describe blocks group related tests and allow sharing setup and teardown logic using `beforeEach` and `afterEach`. The entire block can be skipped using `.skip()`. ```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 () { // ... }); // ... }); ``` -------------------------------- ### Use Laravel Assertions in Pest Source: https://pestphp.com/docs/plugins Access standard Laravel testing assertions directly within Pest tests after installing the Pest Laravel plugin. No special setup is required beyond the plugin installation. ```php it('has a welcome page', function () { $this->get('/')->assertStatus(200); }); ``` -------------------------------- ### Specify Request Headers Source: https://pestphp.com/docs/stress-testing Add custom headers to your stress test requests using the `headers()` method. This example includes an Authorization header. ```php $result = stress('example.com/articles')->headers([ 'Authorization' => 'Bearer SecretToken', ])->get(); ``` -------------------------------- ### Use Custom Plugin Method in Test Source: https://pestphp.com/docs/creating-plugins After installation and setup, custom methods defined in your plugin's traits can be invoked directly on the `$this` variable within Pest test closures. ```php test('plugin example', function () { $this->myPluginMethod(); // }) ``` -------------------------------- ### Complex Configuration with Glob Patterns and Traits Source: https://pestphp.com/docs/configuring-tests Apply a custom base test class and a trait to tests matching a complex glob pattern across multiple directories. This example targets browser tests in any module's 'Tests/Browser' directory. ```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. ``` -------------------------------- ### Pest Type Coverage with Minimum Percentage Source: https://pestphp.com/docs/pest-spicy-summer-release Example output when enforcing a minimum type coverage percentage (`--min=100`), showing an error if the threshold is not met. ```bash ...\n app/Models\User.php .......................................................... 100%\n app/Repositories/UserRepository.php .................................. pa8, rt8 33%\n ───────────────────────────────────────────────────────────────────────────────────\n Total: 91.6 %\n ERROR Type coverage below expected: 91.6%. Minimum: 100.0% ``` -------------------------------- ### Authenticate and Access Page with Namespaced Functions in Pest Laravel Source: https://pestphp.com/docs/plugins Use namespaced functions like `actingAs` and `get` provided by the Pest Laravel plugin to test authenticated user access to pages. Ensure the plugin is installed. ```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); }); ``` -------------------------------- ### Use Namespaced HTTP Functions in Pest Laravel Source: https://pestphp.com/docs/plugins Bypass the `$this` variable and use namespaced functions like `get` for making HTTP requests in Pest tests, facilitated by the Pest Laravel plugin. Requires Composer installation. ```php use function Pest\Laravel\{get}; it('has a welcome page', function () { get('/')->assertStatus(200); // same as $this->get('/')... }); ``` -------------------------------- ### Initialize Properties with `beforeEach` Source: https://pestphp.com/docs/hooks Initialize properties within `beforeEach` to share them across tests in the same file. ```php beforeEach(function () { $this->userRepository = new UserRepository(); }); it('may be created', function () { $user = $this->userRepository->create(); expect($user)->toBeInstanceOf(User::class); }); ``` -------------------------------- ### Specify HTTP Methods and Payloads Source: https://pestphp.com/docs/stress-testing Perform stress tests using different HTTP methods (delete, get, head, options, patch, put, post). Methods like options, patch, and put can accept an optional payload, while post requires one. ```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"]); ``` -------------------------------- ### Bitbucket Pipelines CI Configuration Source: https://pestphp.com/docs/continuous-integration Set up Bitbucket Pipelines to install Composer dependencies and execute PestPHP tests. This configuration uses a Composer Docker image and caches dependencies. ```yaml image: composer:2 pipelines: default: - parallel: - step: name: Test script: - composer install --no-interaction --prefer-dist --optimize-autoloader - ./vendor/bin/pest caches: - composer ``` -------------------------------- ### Untested Mutation Example Source: https://pestphp.com/docs/mutation-testing Illustrates a mutation that is not detected by the test suite. The test still passes despite the change, indicating a gap in test coverage. ```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); }); ``` -------------------------------- ### Test Livewire Component Increment Source: https://pestphp.com/docs/plugins Use the `livewire` namespaced function from the Pest Livewire plugin to interact with and assert the state of Livewire components. Requires Composer installation. ```php use function Pest\Livewire\livewire; it('can be incremented', function () { livewire(Counter::class) ->call('increment') ->assertSee(1); }); ``` -------------------------------- ### Simulate Specific Mobile Devices Source: https://pestphp.com/docs/browser-testing Utilize the `on()` method chained with specific device names (e.g., `iPhone14Pro`) to simulate precise mobile device viewports and user agents. ```php $page = visit('/')->on()->iPhone14Pro(); ``` -------------------------------- ### Basic Assertion with expect() Source: https://pestphp.com/docs/expectations Use `expect($value)` to start an assertion. Chain expectation methods like `toBe()` to verify the value. This is the fundamental way to test values in Pest. ```php test('sum', function () { $value = sum(1, 2); expect($value)->toBe(3); // Assert that the value is 3... }); ``` -------------------------------- ### Set Host for Browser Test Server Source: https://pestphp.com/docs/browser-testing Configure the host for your test server using the `withHost` method. This is useful for testing subdomains or scenarios where different hosts serve distinct content. ```php $page = visit('/dashboard')->withHost('some-subdomain.localhost'); $page->assertSee('Welcome to Some Subdomain'); ``` -------------------------------- ### Generate Basic Test Coverage Report Source: https://pestphp.com/docs/test-coverage Run your Pest test suite with the `--coverage` option to generate a code coverage report. This requires XDebug 3.0+ or PCOV to be installed and XDEBUG_MODE set to 'coverage'. ```bash ./vendor/bin/pest --coverage ``` -------------------------------- ### Customize Concurrent Requests Source: https://pestphp.com/docs/stress-testing Adjust the number of concurrent requests made during a stress test using the `concurrently()` method. This example sets concurrency to 2 requests for 5 seconds. ```php $result = stress('example.com')->concurrently(requests: 2)->for(5)->seconds(); ``` -------------------------------- ### Initialize Pest in Project Source: https://pestphp.com/docs/installation Run this command to initialize Pest in your current PHP project. It creates a Pest.php configuration file at the root of your test suite. ```bash ./vendor/bin/pest --init ``` -------------------------------- ### Advanced Architectural Testing Expectations Source: https://pestphp.com/docs/pest-spicy-summer-release This example demonstrates advanced architectural testing in Pest, checking controller classes for strict types, specific suffixes, readonly properties, and inheritance/implementation constraints. Use `classes->not->toBeFinal()` to ensure classes are not final. ```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), ``` -------------------------------- ### Run a Stress Test from the Command Line Source: https://pestphp.com/docs/stress-testing Execute a stress test on a given URL directly from the command line. This is a quick way to test a URL without writing PHP code. ```bash ./vendor/bin/pest stress example.com/articles/1 --delete ``` -------------------------------- ### Handle Dynamic Data in Snapshots Source: https://pestphp.com/docs/snapshot-testing Employ Expectation Pipes to manage dynamic data, like CSRF tokens, within snapshots. This example replaces a dynamic token with a fixed test value before snapshotting. ```php expect()->pipe('toMatchSnapshot', function (Closure $next) { if (is_string($this->value)) { $this->value = preg_replace( '/name="_token" value=".*"/', 'name="_token" value="my_test"', $this->value ); } return $next(); }); ``` -------------------------------- ### Share Datasets Separately in `tests/Datasets` Folder Source: https://pestphp.com/docs/datasets Store datasets in the `tests/Datasets` folder to keep them separate from test code. This example shows how to use a shared dataset named 'emails'. ```diff // tests/Unit/ExampleTest.php... it('has emails', function (string $email) { expect($email)->not->toBeEmpty(); -})->with(['enunomaduro@gmail.com', 'other@example.com']); +})->with('emails'); // tests/Datasets/Emails.php... +dataset('emails', [ + 'enunomaduro@gmail.com', + 'other@example.com' +]); ``` -------------------------------- ### Apply Dataset to All Tests within `describe` using `beforeEach()` Source: https://pestphp.com/docs/datasets Use `beforeEach()->with()` inside a `describe` block to apply a dataset to all tests within that scope, ensuring consistent data for each test. ```php describe('user settings', function () { beforeEach()->with([10, 20, 30]); test('receives the dataset value', function (int $value) { expect($value)->toBeGreaterThan(0); }); }); ``` -------------------------------- ### Get Element Attribute Source: https://pestphp.com/docs/browser-testing Retrieves the value of a specified attribute from an element matching the given selector. Commonly used for getting 'alt' text from images or 'href' from links. ```php $alt = $page->attribute('img', 'alt'); ``` -------------------------------- ### Stress Test with Different HTTP Methods Source: https://pestphp.com/docs/stress-testing Specify the HTTP method for the stress test using options like `--get`, `--head`, `--options`, `--patch`, `--put`, or `--post`. Some methods support optional payload arguments. ```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 ``` ```bash ./vendor/bin/pest stress example.com/articles/1 --patch='{"name": "Nuno"}' ``` ```bash ./vendor/bin/pest stress example.com/articles --put ``` ```bash ./vendor/bin/pest stress example.com/articles --put='{"name": "Nuno"}' ``` ```bash ./vendor/bin/pest stress example.com/articles --post='{"name": "Nuno"}' ``` -------------------------------- ### url Source: https://pestphp.com/docs/browser-testing Gets the page's URL. ```APIDOC ## url ### Description Gets the page's URL. ### Method ```php $currentUrl = $page->url(); ``` ``` -------------------------------- ### Basic `beforeEach` Hook Source: https://pestphp.com/docs/hooks Use `beforeEach` to execute a closure before every test in the current file. ```php beforeEach(function () { // Prepare something before each test run... }); ``` -------------------------------- ### content Source: https://pestphp.com/docs/browser-testing Gets the page's content. ```APIDOC ## content ### Description Gets the page's content. ### Method ```php $html = $page->content(); ``` ``` -------------------------------- ### Configure Headed Mode in Pest.php Source: https://pestphp.com/docs/browser-testing Sets the browser to run in headed mode by default by configuring the Pest settings in the `Pest.php` file. ```php pest()->browser()->headed(); ``` -------------------------------- ### Write Stress Tests in Pest PHP Test Files Source: https://pestphp.com/docs/announcing-stressless Integrate stress testing directly into your Pest PHP test suite. This example shows how to assert the number of failed requests and the median request duration. ```php concurrently(5) ->for(10)->seconds(); $requests = $result->requests; expect($requests->failed->count) ->toBe(0); expect($requests->duration->med) ->toBeLessThan(100.0); // 100ms }); ``` -------------------------------- ### value Source: https://pestphp.com/docs/browser-testing 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 $value = $page->value('input[name=email]'); ``` ``` -------------------------------- ### Write a Basic Pest Test Source: https://pestphp.com/docs/writing-tests Use the `test()` function to define a simple test case. This is the most basic way to write a test in Pest. ```php test('sum', function () { $result = sum(1, 2); expect($result)->toBe(3); }); ``` -------------------------------- ### Get Current URL Source: https://pestphp.com/docs/browser-testing Retrieves the URL of the current page. ```php $currentUrl = $page->url(); ``` -------------------------------- ### Basic Browser Test in Pest Source: https://pestphp.com/docs/browser-testing A simple test to verify if the homepage displays the expected welcome message. Ensure the `visit` function is available in your test scope. ```php it('may welcome the user', function () { $page = visit('/'); $page->assertSee('Welcome'); }); ``` -------------------------------- ### text Source: https://pestphp.com/docs/browser-testing 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'); ``` ``` -------------------------------- ### Create Todos with Assignee and Issue Tracking Source: https://pestphp.com/docs/pest3-now-available Use the `todo()` method to create tasks. Assign todos to team members using the `assignee` argument and link them to issues with the `issue` argument. ```php it('has a contact page', function () { // })->todo(assignee: 'taylor@laravel.com', issue: 123); ``` -------------------------------- ### attribute Source: https://pestphp.com/docs/browser-testing 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'); ``` ``` -------------------------------- ### Get Page Content Source: https://pestphp.com/docs/browser-testing Retrieves the entire HTML content of the current page. ```php $html = $page->content(); ``` -------------------------------- ### Run and Filter Todos from CLI Source: https://pestphp.com/docs/pest3-now-available View and manage todos directly from the command line. Use `--todos` to list all, `--assignee` to filter by user, or `--issue` to filter by issue number. ```bash ./vendor/bin/pest --todos --assignee=taylor # or --issue=123 ``` -------------------------------- ### Create Bound Datasets for User Models Source: https://pestphp.com/docs/datasets Use bound datasets to obtain data resolved after `beforeEach()`, useful for creating models like `App\Models\User` after the database schema is prepared. ```php it('can generate the full name of a user', function (User $user) { expect($user->full_name)->toBe("{$user->first_name} {$user->last_name}"); })->with([ fn() => User::factory()->create(['first_name' => 'Nuno', 'last_name' => 'Maduro']), fn() => User::factory()->create(['first_name' => 'Luke', 'last_name' => 'Downing']), fn() => User::factory()->create(['first_name' => 'Freek', 'last_name' => 'Van Der Herten']), ]); ``` -------------------------------- ### Define a Custom Preset with Namespaces Source: https://pestphp.com/docs/arch-testing Create a custom preset that utilizes PSR-4 namespaces provided as an argument to the closure. This allows dynamic rule creation based on project structure. ```php pest()->presets()->custom('silex', function (array $userNamespaces) { var_dump($userNamespaces); // array(1) { [0]=> string(3) "App" } return [ expect($userNamespaces)->toBeArray(), ]; }); ``` -------------------------------- ### Configuration Options Source: https://pestphp.com/docs/cli-api-reference Options related to initializing, configuring, and managing Pest's behavior and environment. ```APIDOC ## Configuration 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 ``` -------------------------------- ### Mutation Testing Success Result Source: https://pestphp.com/docs/mutation-testing Example output indicating that all mutations are now tested, resulting in a 100% mutation score. ```bash Mutations: 1 tested Score: 100.00% ``` -------------------------------- ### Basic `beforeAll` Hook Source: https://pestphp.com/docs/hooks Use `beforeAll` to execute a closure once before any tests in the current file run. ```php beforeAll(function () { // Prepare something once before any of this file's tests run... }); ``` -------------------------------- ### Run Stress Test from Command Line with Stressless Source: https://pestphp.com/docs/announcing-stressless 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 ``` -------------------------------- ### Get Request Upload Data Count Source: https://pestphp.com/docs/stress-testing Returns the total count of data uploaded during requests, measured in bytes. ```php $result->requests()->upload()->data()->count(); ``` -------------------------------- ### Get Request Download Data Count Source: https://pestphp.com/docs/stress-testing Returns the total count of data downloaded during requests, measured in bytes. ```php $result->requests()->download()->data()->count(); ``` -------------------------------- ### Visit Multiple Pages and Perform Global Assertions Source: https://pestphp.com/docs/browser-testing Test multiple pages concurrently by passing an array of URLs to the `visit()` method. Perform assertions across all visited pages before accessing individual page objects. ```php $pages = visit(['/', '/about']); $pages->assertNoSmoke() ->assertNoAccessibilityIssues() ->assertNoConsoleLogs() ->assertNoJavaScriptErrors(); [$homePage, $aboutPage] = $pages; $homePage->assertSee('Welcome to our website'); $aboutPage->assertSee('About Us'); ``` -------------------------------- ### Browser Testing with Laravel Helpers Source: https://pestphp.com/docs/pest-v4-is-here-now-with-browser-testing Demonstrates using Pest's browser testing features with Laravel's testing API, including database traits, model factories, and navigation 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); }); ``` -------------------------------- ### Specify Method Arguments with Exact Values Source: https://pestphp.com/docs/mocking Use the `with()` method to specify the exact arguments expected for a method call. An exception will be thrown if arguments do not match. ```php $client->shouldReceive('post') ->with($firstArgument, $secondArgument); ``` -------------------------------- ### Get Request Upload Data Rate Source: https://pestphp.com/docs/stress-testing Returns the data rate for uploads during requests, measured in bytes per second. ```php $result->requests()->upload()->data()->rate(); ``` -------------------------------- ### waitForKey Source: https://pestphp.com/docs/browser-testing 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(); // Useful for debugging ``` ``` -------------------------------- ### Get Request Download Data Rate Source: https://pestphp.com/docs/stress-testing Returns the data rate for downloads during requests, measured in bytes per second. ```php $result->requests()->download()->data()->rate(); ``` -------------------------------- ### Define Multiple Global Hooks in Pest.php Source: https://pestphp.com/docs/global-hooks Configure various global hooks like `beforeAll`, `beforeEach`, `afterEach`, and `afterAll` within your `Pest.php` file for comprehensive test suite management. These hooks can be scoped to specific groups and directories. ```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'); ``` -------------------------------- ### Ensure Methods are Documented Source: https://pestphp.com/docs/arch-testing Use `toHaveMethodsDocumented()` to verify that all methods within a given namespace are documented. ```php arch('app') ->expect('App') ->toHaveMethodsDocumented(); ``` -------------------------------- ### Specify Method Arguments with Mockery::any() Source: https://pestphp.com/docs/mocking Use `Mockery::any()` as a matcher to accept any value for a specific argument. This increases flexibility in argument matching. ```php $client->shouldReceive('post') ->with($firstArgument, Mockery::any()); ``` -------------------------------- ### Configure Browser Host Source: https://pestphp.com/docs/browser-testing Set a custom host for your browser tests in the Pest.php configuration file. This is useful for testing applications served from specific subdomains. ```php pest()->browser()->withHost('some-subdomain.localhost'); ``` -------------------------------- ### Get Element Value Source: https://pestphp.com/docs/browser-testing Retrieves the current value of an input element or similar form control. Requires a CSS selector for the element. ```php $value = $page->value('input[name=email]'); ``` -------------------------------- ### Configure CI Sharding with GitHub Actions Matrix Source: https://pestphp.com/docs/pest-v4-is-here-now-with-browser-testing Easily set up test sharding in your CI configuration using the `matrix` strategy in GitHub Actions. Define jobs that run different shards of your test suite. ```yaml strategy: matrix: shard: [1, 2, 3, 4] name: Tests (Shard ${{ matrix.shard }}/4) steps: - name: Run tests run: pest --parallel --shard ${{ matrix.shard }}/4 ``` -------------------------------- ### Access Request Count Source: https://pestphp.com/docs/stress-testing Get the total number of requests made during the stress test using the `count()` method on the requests object. ```php $result->requests()->count(); ``` -------------------------------- ### Apply a Custom Arch Testing Preset Source: https://pestphp.com/docs/arch-testing Use a previously defined custom preset by chaining the `preset()` method with the custom preset's name. ```php arch()->preset()->silex(); ``` -------------------------------- ### Get Element Text Source: https://pestphp.com/docs/browser-testing Retrieves the text content of an element identified by a CSS selector. Useful for asserting or processing visible text on the page. ```php $text = $page->text('.header'); ``` -------------------------------- ### Get Test Run Duration Source: https://pestphp.com/docs/stress-testing Returns the total duration of the stress test. This value corresponds to the `--duration` option or the `for()->seconds()` method. ```php $result->testRun()->duration(); ``` -------------------------------- ### Generate Mutations for Specific Class Source: https://pestphp.com/docs/mutation-testing Generates mutations only for the specified class or namespace. For example, `--class=App\Models` targets all classes within the `App\Models` namespace. ```bash ./vendor/bin/pest --mutate --class=App\Models ``` -------------------------------- ### Ensure Files are Traits Source: https://pestphp.com/docs/arch-testing Use `toBeTraits()` to confirm that all files within a given namespace are traits. ```php arch('app') ->expect('App\Concerns') ->toBeTraits(); ``` -------------------------------- ### Access Failed Request Rate Source: https://pestphp.com/docs/stress-testing Get the rate of failed requests per second during the stress test using `failed()->rate()` on the requests object. ```php $result->requests()->failed()->rate(); ``` -------------------------------- ### Stop on First Failure (--bail) Source: https://pestphp.com/docs/filtering-tests.md Use the --bail option to halt test execution immediately after the first test failure or error. ```bash ./vendor/bin/pest --bail ``` -------------------------------- ### Run Pest Browser Tests Source: https://pestphp.com/docs/browser-testing Standard command to execute all Pest tests, including browser tests. Use the `--parallel` option for faster execution by running tests concurrently. ```bash ./vendor/bin/pest ./vendor/bin/pest --parallel ./vendor/bin/pest --debug ``` -------------------------------- ### Customize Stress Test Duration Source: https://pestphp.com/docs/stress-testing Modify the default 10-second duration of a stress test using the `for()->seconds()` method. This example sets the duration to 5 seconds. ```php $result = stress('example.com')->for(5)->seconds(); ``` -------------------------------- ### Define Custom `toBeWithinRange` Expectation Source: https://pestphp.com/docs/custom-expectations Create a reusable expectation to check if a number falls within a specified range. This example chains built-in Pest expectations. ```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); }); ``` -------------------------------- ### Basic Dataset Usage in PestPHP Source: https://pestphp.com/docs/datasets Use the `with` method to provide an array of simple values for a single test parameter. Pest will run the test once for each value in the array. ```php it('has emails', function (string $email) { expect($email)->not->toBeEmpty(); })->with(['enunomaduro@gmail.com', 'other@example.com']); ``` -------------------------------- ### Ensure Properties are Documented Source: https://pestphp.com/docs/arch-testing Use `toHavePropertiesDocumented()` to verify that all properties within a specified namespace are documented. ```php arch('app') ->expect('App') ->toHavePropertiesDocumented(); ``` -------------------------------- ### Get Test Run Concurrency Source: https://pestphp.com/docs/stress-testing Returns the number of concurrent requests made during the stress test. This value corresponds to the `--concurrency` option or the `concurrently` method. ```php $result->testRun()->concurrency(); ``` -------------------------------- ### Applying Traits to Test Directories Source: https://pestphp.com/docs/configuring-tests Configure Pest to use a specific trait for tests within a directory. This example applies the `RefreshDatabase` trait to tests in the 'Feature' directory. ```php extend(TestCase::class)->use(RefreshDatabase::class)->in('Feature'); ``` -------------------------------- ### Skip Tests Based on Environment Source: https://pestphp.com/docs/skipping-tests Use skipLocally() to skip tests when running on a local machine, or skipOnCi() to skip tests when running in a CI environment. ```php it('has home', function () { // })->skipLocally(); // or skipOnCi() ``` -------------------------------- ### Combine Options for Coverage Reporting Source: https://pestphp.com/docs/test-coverage Combine `--only-covered` with `--min` to hide files with no coverage while still enforcing a minimum coverage threshold for the rest of the project. ```bash ./vendor/bin/pest --coverage --only-covered --min=90 ``` -------------------------------- ### Limit class usage location with `toOnlyBeUsedIn()` Source: https://pestphp.com/docs/arch-testing Enforce that a specific class or set of classes are only used within particular application parts. For example, ensure models are only used by repositories. ```php arch('models') ->expect('App\Models') ->toOnlyBeUsedIn('App\Repositories'); ``` -------------------------------- ### Define Global beforeEach Hook for Entire Test Suite Source: https://pestphp.com/docs/global-hooks This hook runs before each test in your entire test suite, regardless of folder or group. Configure it in your `Pest.php` file. ```php pest()->beforeEach(function () { // Interact with your database... }); ``` -------------------------------- ### Press Button Source: https://pestphp.com/docs/browser-testing Simulates a button click. Use the button's visible text or its name attribute. ```php $page->press('Submit'); ``` -------------------------------- ### Mock a Class and Expect a Method Call Source: https://pestphp.com/docs/mocking Create a mock object for a class and define an expectation for a specific method call. The actual method will not be invoked. ```php use App\Repositories\BookRepository; use Mockery; it('may buy a book', function () { $client = Mockery::mock(PaymentClient::class); $client->shouldReceive('post'); $books = new BookRepository($client); $books->buy(); // The API is not actually invoked since `$client->post()` has been mocked... }); ``` -------------------------------- ### Configure Source Directories for Coverage Source: https://pestphp.com/docs/test-coverage Specify which directories should be included in code coverage reports by adding a `` section to your `phpunit.xml` file. ```xml ... ./app ... ``` -------------------------------- ### Attach Dataset to `describe` Block for All Tests Source: https://pestphp.com/docs/datasets Attach a dataset to a `describe()` block so that all tests within that block automatically receive the dataset values. ```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']); ``` -------------------------------- ### Get Request Upload Duration Source: https://pestphp.com/docs/stress-testing Retrieves the median upload duration for requests in milliseconds. Network latency can affect this metric. Access min, max, p90, and p95 values similarly. ```php $result->requests()->upload()->duration()->med(); // ->min(); // ->max(); // ->p90(); // ->p95(); ``` -------------------------------- ### Get Request Download Duration Source: https://pestphp.com/docs/stress-testing Retrieves the median download duration for requests in milliseconds. This metric is affected by network latency. Min, max, p90, and p95 values are also available. ```php $result->requests()->download()->duration()->med(); // ->min(); // ->max(); // ->p90(); // ->p95(); ``` -------------------------------- ### Basic Stress Test Command Source: https://pestphp.com/docs/stress-testing Quickly stress test a URL directly from the terminal. The default duration is 5 seconds. ```bash ./vendor/bin/pest stress example.com ``` -------------------------------- ### Write a Pest Test with `it()` Source: https://pestphp.com/docs/writing-tests Use the `it()` function for more readable test descriptions. It prefixes the description with 'it', making tests read like sentences. ```php it('performs sums', function () { $result = sum(1, 2); expect($result)->toBe(3); }); ``` -------------------------------- ### Get Request TLS Handshaking Duration Source: https://pestphp.com/docs/stress-testing Retrieves the median TLS handshaking duration for requests in milliseconds. Other statistical measures like min, max, p90, and p95 can also be accessed. ```php $result->requests()->tlsHandshaking()->duration()->med(); // ->min(); // ->max(); // ->p90(); // ->p95(); ``` -------------------------------- ### Create a 'Todo' Test Source: https://pestphp.com/docs/skipping-tests Use the todo() method to mark a test as a placeholder. This is useful for tests that need to be implemented later, ensuring they are not forgotten. ```php it('has home', function () { // })->todo(); ``` -------------------------------- ### Create a Todo Item Source: https://pestphp.com/docs/team-management Use the `todo()` method on a test to mark it as a task. Pest will highlight these in test results. Include the `--todos` option when running Pest to view only todo items. ```php it('has a contact page', function () { // })->todo(); ``` -------------------------------- ### Test Livewire Component Decrement Source: https://pestphp.com/docs/plugins Use the `livewire` namespaced function from the Pest Livewire plugin to test Livewire component methods like 'decrement'. Ensure the plugin is installed via Composer. ```php use function Pest\Livewire\livewire; it('can be decremented', function () { livewire(Counter::class) ->call('decrement') ->assertSee(-1); }); ``` -------------------------------- ### Access Request Duration Metrics Source: https://pestphp.com/docs/stress-testing Retrieve various duration metrics for requests made during a stress test, including median, min, max, p90, and p95. The `med()` method is shown as an example. ```php $result->requests()->duration()->med(); // ->min(); // ->max(); // ->p90(); // ->p95(); ``` -------------------------------- ### Define Architectural Rules Source: https://pestphp.com/docs/arch-testing Specify expectations for namespaces, function usage, and class types. Use 'not' to negate rules and 'ignoring' to exclude specific items. ```php arch() ->expect('App') ->toUseStrictTypes() ->not->toUse(['die', 'dd', 'dump']); arch() ->expect('App\Models') ->toBeClasses() ->toExtend('Illuminate\Database\Eloquent\Model') ->toOnlyBeUsedIn('App\Repositories') ->ignoring('App\Models\User'); arch() ->expect('App\Http') ->toOnlyBeUsedIn('App\Http'); arch() ->expect('App\*\Traits') ->toBeTraits(); arch()->preset()->php(); arch()->preset()->security()->ignoring('md5'); ``` -------------------------------- ### List All Flaky Tests (--flaky) Source: https://pestphp.com/docs/filtering-tests.md Display a list of all tests marked as flaky in the suite using the --flaky command-line option. ```bash ./vendor/bin/pest --flaky ```