laravel-testing

SkillAI & models

Use when testing controllers, services, or models, or implementing TDD on Laravel 13 with Pest 4 / PHPUnit 12.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the laravel-testing skill

What this skill tells your AI

The instructions your AI receives, as published by fusengine/agents in plugins/laravel-expert/skills/laravel-testing/SKILL.md and read by ahel’s review.

Laravel Testing

Agent Workflow (MANDATORY)

Before ANY implementation, spawn 3 agents in parallel, one Agent call each with a name:

  1. fuse-ai-pilot:explore-codebase - Analyze existing test patterns
  2. fuse-ai-pilot:research-expert - Verify Pest/PHPUnit docs via Context7
  3. mcp__context7__query-docs - Check assertion and mocking patterns

After implementation, run fuse-ai-pilot:sniper for validation.


Overview

TypePurposeLocation
FeatureHTTP, full stacktests/Feature/
UnitIsolated classestests/Unit/
ArchCode architecturetests/Arch.php

Decision Guide: Test Type

What to test?
├── HTTP endpoint → Feature test
├── Service/Policy logic → Unit test
├── Code structure → Arch test
├── External API → Mock with Http::fake()
├── Mail/Queue/Event → Use Fakes
└── Database state → assertDatabaseHas()

Decision Guide: Test Strategy

Coverage strategy?
├── Feature tests (70%) → Critical flows
├── Unit tests (25%) → Business logic
├── E2E tests (5%) → User journeys
└── Arch tests → Structural rules

Critical Rules

  1. Use RefreshDatabase for database isolation
  2. Use factories for test data (never raw inserts)
  3. Mock external services - Never call real APIs
  4. Test edge cases - Empty, null, boundaries
  5. Run parallel - pest --parallel for speed

Reference Guide

Pest Basics

TopicReferenceWhen to Consult
Pest Syntaxpest-basics.mdit(), test(), describe()
Datasetspest-datasets.mdData providers, hooks
Architecturepest-arch.mdarch() tests

HTTP Testing

TopicReferenceWhen to Consult
Requestshttp-requests.mdGET, POST, headers
JSON APIhttp-json.mdAPI assertions
Authenticationhttp-auth.mdactingAs, guards
Assertionshttp-assertions.mdStatus, redirects

Database Testing

TopicReferenceWhen to Consult
Basicsdatabase-basics.mdRefreshDatabase
Factoriesdatabase-factories.mdFactory patterns
Assertionsdatabase-assertions.mdDB assertions

Mocking

TopicReferenceWhen to Consult
Servicesmocking-services.mdMock, spy
Fakesmocking-fakes.mdMail, Queue, Event
HTTP & Timemocking-http.mdHttp::fake, travel

Other

TopicReferenceWhen to Consult
Consoleconsole-tests.mdArtisan tests
Troubleshootingtroubleshooting.mdCommon errors

Templates

TemplateWhen to Use
FeatureTest.php.mdHTTP feature test
UnitTest.php.mdService unit test
ArchTest.php.mdArchitecture test
ApiTest.php.mdREST API test
PestConfig.php.mdPest configuration

Quick Reference

// Feature test
it('creates a post', function () {
    $user = User::factory()->create();

    $this->actingAs($user)
        ->postJson('/api/posts', ['title' => 'Test'])
        ->assertCreated()
        ->assertJsonPath('data.title', 'Test');

    $this->assertDatabaseHas('posts', ['title' => 'Test']);
});

// With dataset
it('validates emails', function (string $email, bool $valid) {
    // test logic
})->with([
    ['valid@test.com', true],
    ['invalid', false],
]);

// Mock facade
Mail::fake();
// ... action ...
Mail::assertSent(OrderShipped::class);

Commands

# Run all tests
php artisan test

# Pest directly
./vendor/bin/pest

# Parallel execution
./vendor/bin/pest --parallel

# Filter by name
./vendor/bin/pest --filter "user can"

# Coverage
./vendor/bin/pest --coverage --min=80

# Profile slow tests
./vendor/bin/pest --profile

Best Practices

DO

  • Use RefreshDatabase trait
  • Follow AAA pattern (Arrange-Act-Assert)
  • Name tests descriptively
  • Test one thing per test
  • Use factories for data

DON'T

  • Create test dependencies
  • Call real external APIs
  • Use production database
  • Skip edge cases

Laravel 13 Notes

PHPUnit 12 + Pest 4

Laravel 13 requires PHPUnit 12 and supports Pest 4. PHP attributes replace docblock annotations.

use PHPUnit\Framework\Attributes\Test;
use Illuminate\Foundation\Testing\Attributes\Seed;
use Illuminate\Foundation\Testing\Attributes\Seeder;

#[Seed]                          // runs DatabaseSeeder
#[Seeder(UserSeeder::class)]     // runs a targeted seeder
final class UserTest extends TestCase
{
    #[Test]
    public function it_creates_user(): void { /* ... */ }
}

Str cache reset

Laravel 13 automatically resets Str caches (random, slug) between tests to avoid state leak. No manual setup required.

Migration from Pest 3

  • pest --init regenerates Pest.php with the new API
  • Datasets now support native PHP generators
  • expect()->toBeInstanceOf() → strict typing required

Signals

GitHub stars
25
Forks
4
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
laravel-testing-fusengine
Source
github.com/fusengine/agents