Claude-skill-registry laravel-testing

Write tests with Pest 3/PHPUnit, feature tests, unit tests, mocking, fakes, and factories. Use when testing controllers, services, models, or implementing TDD.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/laravel-testing" ~/.claude/skills/majiayu000-claude-skill-registry-laravel-testing && rm -rf "$T"
manifest: skills/data/laravel-testing/SKILL.md
source content

Laravel Testing

Agent Workflow (MANDATORY)

Before ANY implementation, launch in parallel:

  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 stack
tests/Feature/
UnitIsolated classes
tests/Unit/
ArchCode architecture
tests/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