Source profileQuality 72/100

affaan-m/ECC/docs/zh-CN/skills/laravel-tdd/SKILL.md

laravel-tdd

Review laravel-tdd's use cases, installation, workflow, and original source instructions.

Source repository stars
234,327
Declared platforms
0
Static risk flags
0
Last source update
2026-07-27
Source checked
2026-07-28

Decision brief

What it does—and where it fits

使用 PHPUnit 和 Pest 为 Laravel 应用程序进行测试驱动开发,覆盖率(单元 + 功能)达到 80% 以上。

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/affaan-m/ECC --skill "docs/zh-CN/skills/laravel-tdd"
    Safe inspection promptEditorial

    Inspect the Agent Skill "laravel-tdd" from https://github.com/affaan-m/ECC/blob/4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38/docs/zh-CN/skills/laravel-tdd/SKILL.md at commit 4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      使用时机

      Laravel 中的新功能或端点 错误修复或重构 测试 Eloquent 模型、策略、作业和通知 除非项目已标准化使用 PHPUnit,否则新测试首选 Pest

      Laravel 中的新功能或端点错误修复或重构测试 Eloquent 模型、策略、作业和通知
    2. 02

      工作原理

      1. 编写一个失败的测试 2. 实施最小更改以通过测试 3. 在保持测试通过的同时进行重构

      编写一个失败的测试实施最小更改以通过测试在保持测试通过的同时进行重构
    3. 03

      红-绿-重构循环

      1. 编写一个失败的测试 2. 实施最小更改以通过测试 3. 在保持测试通过的同时进行重构

      编写一个失败的测试实施最小更改以通过测试在保持测试通过的同时进行重构
    4. 04

      测试层级

      单元:纯 PHP 类、值对象、服务 功能:HTTP 端点、身份验证、验证、策略 集成:数据库 + 队列 + 外部边界

      单元:纯 PHP 类、值对象、服务功能:HTTP 端点、身份验证、验证、策略集成:数据库 + 队列 + 外部边界

    Permission review

    Static risk signals and limitations

    No configured static risk pattern was detected

    This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score72/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars234,327SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    affaan-m/ECC
    Skill path
    docs/zh-CN/skills/laravel-tdd/SKILL.md
    Commit
    4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38
    License
    MIT
    Collected
    2026-07-28
    Default branch
    main
    View the original SKILL.md

    Laravel TDD 工作流

    使用 PHPUnit 和 Pest 为 Laravel 应用程序进行测试驱动开发,覆盖率(单元 + 功能)达到 80% 以上。

    使用时机

    • Laravel 中的新功能或端点
    • 错误修复或重构
    • 测试 Eloquent 模型、策略、作业和通知
    • 除非项目已标准化使用 PHPUnit,否则新测试首选 Pest

    工作原理

    红-绿-重构循环

    1. 编写一个失败的测试
    2. 实施最小更改以通过测试
    3. 在保持测试通过的同时进行重构

    测试层级

    • 单元:纯 PHP 类、值对象、服务
    • 功能:HTTP 端点、身份验证、验证、策略
    • 集成:数据库 + 队列 + 外部边界

    根据范围选择层级:

    • 对纯业务逻辑和服务使用单元测试。
    • 对 HTTP、身份验证、验证和响应结构使用功能测试。
    • 当需要验证数据库/队列/外部服务组合时使用集成测试。

    数据库策略

    • 对于大多数功能/集成测试使用 RefreshDatabase(每次测试运行运行一次迁移,然后在支持时将每个测试包装在事务中;内存数据库可能每次测试重新迁移)
    • 当模式已迁移且仅需要每次测试回滚时使用 DatabaseTransactions
    • 当每次测试都需要完整迁移/刷新且可以承担其开销时使用 DatabaseMigrations

    RefreshDatabase 作为触及数据库的测试的默认选择:对于支持事务的数据库,它每次测试运行运行一次迁移(通过静态标志)并将每个测试包装在事务中;对于 :memory: SQLite 或不支持事务的连接,它在每次测试前进行迁移。当模式已迁移且仅需要每次测试回滚时使用 DatabaseTransactions

    测试框架选择

    • 新测试默认使用 Pest(当可用时)。
    • 仅在项目已标准化使用它或需要 PHPUnit 特定工具时使用 PHPUnit

    示例

    PHPUnit 示例

    use App\Models\User;
    use Illuminate\Foundation\Testing\RefreshDatabase;
    use Tests\TestCase;
    
    final class ProjectControllerTest extends TestCase
    {
        use RefreshDatabase;
    
        public function test_owner_can_create_project(): void
        {
            $user = User::factory()->create();
    
            $response = $this->actingAs($user)->postJson('/api/projects', [
                'name' => 'New Project',
            ]);
    
            $response->assertCreated();
            $this->assertDatabaseHas('projects', ['name' => 'New Project']);
        }
    }
    

    功能测试示例(HTTP 层)

    use App\Models\Project;
    use App\Models\User;
    use Illuminate\Foundation\Testing\RefreshDatabase;
    use Tests\TestCase;
    
    final class ProjectIndexTest extends TestCase
    {
        use RefreshDatabase;
    
        public function test_projects_index_returns_paginated_results(): void
        {
            $user = User::factory()->create();
            Project::factory()->count(3)->for($user)->create();
    
            $response = $this->actingAs($user)->getJson('/api/projects');
    
            $response->assertOk();
            $response->assertJsonStructure(['success', 'data', 'error', 'meta']);
        }
    }
    

    Pest 示例

    use App\Models\User;
    use Illuminate\Foundation\Testing\RefreshDatabase;
    
    use function Pest\Laravel\actingAs;
    use function Pest\Laravel\assertDatabaseHas;
    
    uses(RefreshDatabase::class);
    
    test('owner can create project', function () {
        $user = User::factory()->create();
    
        $response = actingAs($user)->postJson('/api/projects', [
            'name' => 'New Project',
        ]);
    
        $response->assertCreated();
        assertDatabaseHas('projects', ['name' => 'New Project']);
    });
    

    Pest 功能测试示例(HTTP 层)

    use App\Models\Project;
    use App\Models\User;
    use Illuminate\Foundation\Testing\RefreshDatabase;
    
    use function Pest\Laravel\actingAs;
    
    uses(RefreshDatabase::class);
    
    test('projects index returns paginated results', function () {
        $user = User::factory()->create();
        Project::factory()->count(3)->for($user)->create();
    
        $response = actingAs($user)->getJson('/api/projects');
    
        $response->assertOk();
        $response->assertJsonStructure(['success', 'data', 'error', 'meta']);
    });
    

    工厂和状态

    • 使用工厂生成测试数据
    • 为边缘情况定义状态(已归档、管理员、试用)
    $user = User::factory()->state(['role' => 'admin'])->create();
    

    数据库测试

    • 使用 RefreshDatabase 保持干净状态
    • 保持测试隔离和确定性
    • 优先使用 assertDatabaseHas 而非手动查询

    持久性测试示例

    use App\Models\Project;
    use Illuminate\Foundation\Testing\RefreshDatabase;
    use Tests\TestCase;
    
    final class ProjectRepositoryTest extends TestCase
    {
        use RefreshDatabase;
    
        public function test_project_can_be_retrieved_by_slug(): void
        {
            $project = Project::factory()->create(['slug' => 'alpha']);
    
            $found = Project::query()->where('slug', 'alpha')->firstOrFail();
    
            $this->assertSame($project->id, $found->id);
        }
    }
    

    副作用模拟

    • 作业使用 Bus::fake()
    • 队列工作使用 Queue::fake()
    • 通知使用 Mail::fake()Notification::fake()
    • 领域事件使用 Event::fake()
    use Illuminate\Support\Facades\Queue;
    
    Queue::fake();
    
    dispatch(new SendOrderConfirmation($order->id));
    
    Queue::assertPushed(SendOrderConfirmation::class);
    
    use Illuminate\Support\Facades\Notification;
    
    Notification::fake();
    
    $user->notify(new InvoiceReady($invoice));
    
    Notification::assertSentTo($user, InvoiceReady::class);
    

    身份验证测试(Sanctum)

    use Laravel\Sanctum\Sanctum;
    
    Sanctum::actingAs($user);
    
    $response = $this->getJson('/api/projects');
    $response->assertOk();
    

    HTTP 和外部服务

    • 使用 Http::fake() 隔离外部 API
    • 使用 Http::assertSent() 断言出站负载

    覆盖率目标

    • 对单元 + 功能测试强制执行 80% 以上的覆盖率
    • 在 CI 中使用 pcovXDEBUG_MODE=coverage

    测试命令

    • php artisan test
    • vendor/bin/phpunit
    • vendor/bin/pest

    测试配置

    • 使用 phpunit.xml 设置 DB_CONNECTION=sqliteDB_DATABASE=:memory: 以进行快速测试
    • 为测试保持独立的环境,以避免触及开发/生产数据

    授权测试

    use Illuminate\Support\Facades\Gate;
    
    $this->assertTrue(Gate::forUser($user)->allows('update', $project));
    $this->assertFalse(Gate::forUser($otherUser)->allows('update', $project));
    

    Inertia 功能测试

    使用 Inertia.js 时,使用 Inertia 测试辅助函数来断言组件名称和属性。

    use App\Models\User;
    use Inertia\Testing\AssertableInertia;
    use Illuminate\Foundation\Testing\RefreshDatabase;
    use Tests\TestCase;
    
    final class DashboardInertiaTest extends TestCase
    {
        use RefreshDatabase;
    
        public function test_dashboard_inertia_props(): void
        {
            $user = User::factory()->create();
    
            $response = $this->actingAs($user)->get('/dashboard');
    
            $response->assertOk();
            $response->assertInertia(fn (AssertableInertia $page) => $page
                ->component('Dashboard')
                ->where('user.id', $user->id)
                ->has('projects')
            );
        }
    }
    

    优先使用 assertInertia 而非原始 JSON 断言,以保持测试与 Inertia 响应一致。

    Alternatives

    Compare before choosing