Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Pest Laravel Package

pestphp/pest

Pest is an elegant PHP testing framework focused on simplicity and developer joy. Write expressive, modern tests with a clean syntax, powerful expectations, and a great DX for PHP projects—built for fast feedback and readable suites.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require pestphp/pest --dev --with-all-dependencies
    

    Replace phpunit.xml with Pest’s stub (php artisan pest:init if using Laravel).

  2. First Test: Create tests/Feature/ExampleTest.php:

    use Pest\Test;
    
    test('the application returns a successful response', function () {
        $response = $this->get('/');
        $response->assertStatus(200);
    });
    
  3. Run Tests:

    ./vendor/bin/pest
    

Where to Look First

  • Official Docs (focus on "Getting Started" and "Testing Concepts").
  • Laravel Preset: If using Laravel, check tests/Pest.php for preset helpers (e.g., actingAs(), assertDatabaseHas()).
  • Assertions: Explore Pest’s assertions (e.g., toBeCasedCorrectly(), toUseTrait()).

First Use Case

Unit Testing a Service Class:

use App\Services\UserService;
use Pest\Test;

test('UserService creates a user', function () {
    $service = new UserService();
    $user = $service->create(['name' => 'John', 'email' => 'john@example.com']);

    expect($user)->toBeInstanceOf(\App\Models\User::class);
});

Implementation Patterns

Core Workflows

  1. Test Organization:

    • Use describe() for grouping related tests:
      describe('User Authentication', function () {
          test('fails with invalid credentials')->expectException(\InvalidArgumentException::class);
          test('succeeds with valid credentials')->expect(...);
      });
      
    • Nested it(): For edge cases within a describe block.
  2. Data-Driven Testing:

    • Datasets: Use with() for parameterized tests:
      test('math operations', function (int $a, int $b, int $expected) {
          expect($a + $b)->toEqual($expected);
      })->with([
          [1, 2, 3],
          [5, -3, 2],
      ]);
      
    • Dynamic Datasets: Combine with beforeEach:
      beforeEach(function (array $data) {
          $this->user = User::factory()->create($data);
      });
      
      test('user attributes', function (string $name, string $email) {
          expect($this->user->name)->toBe($name);
      })->with([
          ['John', 'john@example.com'],
          ['Jane', 'jane@example.com'],
      ]);
      
  3. Laravel Integration:

    • HTTP Tests: Leverage preset helpers:
      test('GET /dashboard redirects guests', function () {
          $response = $this->get('/dashboard');
          $response->assertRedirect('/login');
      });
      
    • Database Testing: Use assertDatabaseHas() or assertDatabaseMissing():
      test('user is created in the database', function () {
          $this->post('/register', ['name' => 'Test', 'email' => 'test@example.com']);
          $this->assertDatabaseHas('users', ['email' => 'test@example.com']);
      });
      
  4. Browser Testing (Pest v4+):

    • Playwright-Powered: Test UI interactions:
      test('login form submits correctly', function () {
          $this->browse()
              ->visit('/login')
              ->fill('email', 'user@example.com')
              ->fill('password', 'password')
              ->press('Login')
              ->assertPathIs('/dashboard');
      });
      
    • Visual Regression: Use assertScreenshot() for pixel-perfect checks.
  5. Architecture Testing:

    • Dependency Rules: Enforce layer separation:
      test('App\Services\PaymentService does not use App\Models\User directly')
          ->expect($this->class(App\Services\PaymentService::class))
          ->not->toUse(App\Models\User::class);
      

Integration Tips

  • Parallel Testing: Speed up CI with --parallel:

    ./vendor/bin/pest --parallel --workers=4
    
    • Time-Based Sharding (v4.6+): Optimize slow suites:
      ./vendor/bin/pest --update-shards  # Generate shards.json
      ./vendor/bin/pest --shard=1/5      # Run shard 1 of 5
      
  • CI/CD Optimization:

    • Filter Tests: Run specific files/groups:
      ./vendor/bin/pest tests/Feature/AuthTest.php
      
    • Coverage: Generate reports:
      ./vendor/bin/pest --coverage --only-covered
      
  • Debugging:

    • dd(): Dump variables in tests (works in parallel):
      test('debug user data', function () {
          $user = User::find(1);
          dd($user->toArray());  // Works even in parallel
      });
      
  • Flaky Tests: Mark and retry:

    test('flaky test example')->flaky();
    

    Run with:

    ./vendor/bin/pest --flaky
    

Gotchas and Tips

Pitfalls

  1. Parallel Testing Quirks:

    • dd() Output: May appear out of order in parallel runs (fixed in v4.7.3). Use --no-parallel for debugging.
    • Shared State: Avoid static variables or singleton services that leak between tests. Use beforeEach for setup.
  2. Laravel Preset Gaps:

    • Missing Helpers: If actingAs() or assertDatabaseHas() are unavailable, ensure:
      • use Pest\Laravel\LaravelTestCase; is imported.
      • The Pest.php preset is properly configured (check tests/Pest.php).
    • Architecture Testing: Some classes (e.g., App\Http) may be excluded by default. Adjust rules in tests/ArchitectureTest.php.
  3. Dataset Issues:

    • Nested Datasets: Ensure with() is called on the correct scope (e.g., describe()->with() vs. test()->with()).
    • Parameter Closures: Use fn() for complex data:
      test('dynamic data', function (array $data) {
          // ...
      })->with(fn () => [
          ['key' => 'value1'],
          ['key' => 'value2'],
      ]);
      
  4. Browser Testing:

    • Headless Mode: Defaults to headless. Use --headed for debugging:
      ./vendor/bin/pest --headed
      
    • Slow Tests: Add delays with waitFor():
      $this->browse()->waitFor(1000)->assertSomething();
      
  5. CI-Specific Bugs:

    • GitLab CI: Custom URLs may not work (fixed in v4.7.3). Use:
      variables:
        CI_SERVER_URL: "https://gitlab.example.com"
      
    • TeamCity: Output duplication (fixed in v4.5.0). Ensure --teamcity is used with --parallel.

Debugging Tips

  1. Test Isolation:

    • Database Transactions: Pest auto-rolls back transactions by default. Disable with:
      test('without rollback', function () {
          $this->withoutExceptionHandling();
          // ...
      })->uses('App\Tests\NoRollbackTestCase');
      
  2. Slow Tests:

    • Profile: Use --profile to identify bottlenecks:
      ./vendor/bin/pest --profile
      
    • Sharding: Generate shards.json and commit it to the repo for consistent CI performance.
  3. Assertion Failures:

    • Diff Output: Use expect($actual)->toBe($expected)->dump() for detailed diffs.
    • Custom Matchers: Extend assertions in tests/Extensions.php:
      use Pest\Extension;
      
      Extension::macro('toBeEven', function (int $value) {
          return expect($value)->toBeEven();
      });
      

Extension Points

  1. Custom Assertions:

    • Add to tests/Extensions.php:
      use Pest\Extension;
      
      Extension::macro('toBeJsonApi', function (array $expected) {
          return expect(json_encode($this))->toBeJsonApi($expected);
      });
      
  2. Test Templates:

    • Use pest:init to scaffold custom templates (e.g., for API tests):
      php artisan pest:init --template=api
      
  3. Plugins:

    • Pest Plugins: Install via Composer (e.g., `pestphp/pest-plugin
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony