AgentSkillsCN

laravel-testing

使用 Pest 3/PHPUnit 编写测试,包括功能测试、单元测试、模拟、假数据和工厂模式。适用于测试控制器、服务、模型或实施 TDD 时。

SKILL.md
--- frontmatter
name: laravel-testing
description: Write tests with Pest 3/PHPUnit, feature tests, unit tests, mocking, fakes, and factories. Use when testing controllers, services, models, or implementing TDD.
versions:
  laravel: "12.46"
  pest: "3.0"
  php: "8.5"
user-invocable: false
references: references/pest-basics.md, references/pest-datasets.md, references/pest-arch.md, references/http-requests.md, references/http-json.md, references/http-auth.md, references/http-assertions.md, references/database-basics.md, references/database-factories.md, references/database-assertions.md, references/mocking-services.md, references/mocking-fakes.md, references/mocking-http.md, references/console-tests.md, references/troubleshooting.md, references/templates/FeatureTest.php.md, references/templates/UnitTest.php.md, references/templates/ArchTest.php.md, references/templates/ApiTest.php.md, references/templates/PestConfig.php.md
related-skills: laravel-architecture, laravel-eloquent

Laravel Testing

Agent Workflow (MANDATORY)

Before ANY implementation, use TeamCreate to spawn 3 agents:

  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

code
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

code
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

php
// 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

bash
# 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