Quality

laravel-testing

Generates Pest PHP tests - unit, feature, API, browser

Overview

The laravel-testing agent generates comprehensive test suites using Pest PHP. It analyzes your code and creates tests covering happy paths, edge cases, validation, authorization, and database interactions.

Test Types Generated

Type Location Use Case
Unit Tests tests/Unit/ Isolated class testing, services, helpers
Feature Tests tests/Feature/ HTTP endpoints, middleware, full request cycle
API Tests tests/Feature/Api/ JSON API assertions, authentication flows
Livewire Tests tests/Feature/Livewire/ Component interactions, wire:model, events
Browser Tests tests/Browser/ Laravel Dusk end-to-end testing

Pest PHP Features Used

Generated tests leverage modern Pest PHP syntax:

<?php

use App\Models\User;
use App\Models\Order;

uses(\Illuminate\Foundation\Testing\RefreshDatabase::class);

describe('Order Management', function () {

    beforeEach(function () {
        $this->user = User::factory()->create();
    });

    describe('creating orders', function () {

        it('creates an order with valid data', function () {
            $response = $this->actingAs($this->user)
                ->postJson('/api/orders', [
                    'product_id' => 1,
                    'quantity' => 2,
                ]);

            $response->assertCreated();

            expect(Order::count())->toBe(1);
        });

        it('validates required fields', function () {
            $response = $this->actingAs($this->user)
                ->postJson('/api/orders', []);

            $response->assertUnprocessable()
                ->assertJsonValidationErrors(['product_id', 'quantity']);
        });

    });

    describe('authorization', function () {

        it('prevents guests from creating orders', function () {
            $response = $this->postJson('/api/orders', [
                'product_id' => 1,
            ]);

            $response->assertUnauthorized();
        });

        it('prevents users from viewing others orders', function () {
            $otherUser = User::factory()->create();
            $order = Order::factory()->for($otherUser)->create();

            $response = $this->actingAs($this->user)
                ->getJson("/api/orders/{$order->id}");

            $response->assertForbidden();
        });

    });

});

Test Coverage Areas

The agent automatically generates tests for:

  • Happy paths - Standard successful operations
  • Validation - Required fields, formats, uniqueness
  • Authorization - Policies, gates, role checks
  • Database state - assertDatabaseHas/Missing
  • Edge cases - Null values, boundaries, empty inputs
  • Relationships - Cascade deletes, constraints

Factory Integration

Tests use model factories for realistic data:

// Generated factory usage
it('lists orders with pagination', function () {
    Order::factory()
        ->count(25)
        ->for($this->user)
        ->create();

    $response = $this->actingAs($this->user)
        ->getJson('/api/orders');

    $response->assertOk()
        ->assertJsonCount(15, 'data')
        ->assertJsonPath('meta.total', 25);
});

// With specific states
it('shows only pending orders', function () {
    Order::factory()->pending()->count(3)->for($this->user)->create();
    Order::factory()->completed()->count(2)->for($this->user)->create();

    $response = $this->actingAs($this->user)
        ->getJson('/api/orders?status=pending');

    $response->assertJsonCount(3, 'data');
});

Mocking External Services

The agent generates mocks for external dependencies:

use App\Services\PaymentGateway;

it('processes payment successfully', function () {
    $mock = Mockery::mock(PaymentGateway::class);
    $mock->shouldReceive('charge')
        ->once()
        ->with(100.00, Mockery::any())
        ->andReturn(['status' => 'success', 'transaction_id' => 'txn_123']);

    $this->app->instance(PaymentGateway::class, $mock);

    $response = $this->actingAs($this->user)
        ->postJson('/api/checkout', ['amount' => 100.00]);

    $response->assertOk()
        ->assertJsonPath('transaction_id', 'txn_123');
});

Invoked By Commands

Best Practices

  • One concept per test - Test one behavior at a time
  • Descriptive names - it('creates order with valid data')
  • Arrange-Act-Assert - Clear test structure
  • Factories for data - Never hardcode test data
  • Mock external services - Don't hit real APIs in tests

Guardrails

The testing agent follows strict rules:

  • ALWAYS use RefreshDatabase trait for database tests
  • ALWAYS mock external services (payment gateways, APIs)
  • ALWAYS test authorization (403 responses)
  • NEVER share state between tests
  • NEVER test private methods directly

See Also