laravel-testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseLaravel Testing
Laravel 测试
Agent Workflow (MANDATORY)
Agent工作流(必填)
Before ANY implementation, use to spawn 3 agents:
TeamCreate- fuse-ai-pilot:explore-codebase - Analyze existing test patterns
- fuse-ai-pilot:research-expert - Verify Pest/PHPUnit docs via Context7
- mcp__context7__query-docs - Check assertion and mocking patterns
After implementation, run fuse-ai-pilot:sniper for validation.
在开始任何实现工作前,使用生成3个Agent:
TeamCreate- fuse-ai-pilot:explore-codebase - 分析现有测试模式
- fuse-ai-pilot:research-expert - 通过Context7验证Pest/PHPUnit文档
- mcp__context7__query-docs - 检查断言和模拟模式
实现完成后,运行fuse-ai-pilot:sniper进行验证。
Overview
概述
| Type | Purpose | Location |
|---|---|---|
| Feature | HTTP, full stack | |
| Unit | Isolated classes | |
| Arch | Code architecture | |
| 类型 | 用途 | 位置 |
|---|---|---|
| 功能测试 | HTTP、全栈测试 | |
| 单元测试 | 独立类测试 | |
| 架构测试 | 代码架构检查 | |
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()要测试什么?
├── HTTP端点 → 功能测试
├── 服务/策略逻辑 → 单元测试
├── 代码结构 → 架构测试
├── 外部API → 使用Http::fake()模拟
├── 邮件/队列/事件 → 使用假对象(Fakes)
└── 数据库状态 → 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覆盖率策略?
├── 功能测试(70%) → 核心流程
├── 单元测试(25%) → 业务逻辑
├── 端到端测试(5%) → 用户旅程
└── 架构测试 → 结构规则Critical Rules
核心规则
- Use RefreshDatabase for database isolation
- Use factories for test data (never raw inserts)
- Mock external services - Never call real APIs
- Test edge cases - Empty, null, boundaries
- Run parallel - for speed
pest --parallel
- 使用RefreshDatabase 实现数据库隔离
- 使用工厂(factories) 生成测试数据(绝不要直接插入原始数据)
- 模拟外部服务 - 绝不调用真实API
- 测试边缘情况 - 空值、Null、边界值
- 并行运行 - 使用提升速度
pest --parallel
Reference Guide
参考指南
Pest Basics
Pest基础
| Topic | Reference | When to Consult |
|---|---|---|
| Pest Syntax | pest-basics.md | it(), test(), describe() |
| Datasets | pest-datasets.md | Data providers, hooks |
| Architecture | pest-arch.md | arch() tests |
| 主题 | 参考文档 | 适用场景 |
|---|---|---|
| Pest语法 | pest-basics.md | it()、test()、describe() 语法使用 |
| 数据集 | pest-datasets.md | 数据提供者、钩子使用 |
| 架构测试 | pest-arch.md | arch() 测试编写 |
HTTP Testing
HTTP测试
| Topic | Reference | When to Consult |
|---|---|---|
| Requests | http-requests.md | GET, POST, headers |
| JSON API | http-json.md | API assertions |
| Authentication | http-auth.md | actingAs, guards |
| Assertions | http-assertions.md | Status, redirects |
| 主题 | 参考文档 | 适用场景 |
|---|---|---|
| 请求处理 | http-requests.md | GET、POST、请求头设置 |
| JSON API | http-json.md | API断言验证 |
| 身份认证 | http-auth.md | actingAs、守卫使用 |
| 断言方法 | http-assertions.md | 状态码、重定向验证 |
Database Testing
数据库测试
| Topic | Reference | When to Consult |
|---|---|---|
| Basics | database-basics.md | RefreshDatabase |
| Factories | database-factories.md | Factory patterns |
| Assertions | database-assertions.md | DB assertions |
| 主题 | 参考文档 | 适用场景 |
|---|---|---|
| 基础用法 | database-basics.md | RefreshDatabase 特性使用 |
| 工厂模式 | database-factories.md | 工厂类编写与使用 |
| 数据库断言 | database-assertions.md | 数据库状态验证 |
Mocking
模拟(Mocking)
| Topic | Reference | When to Consult |
|---|---|---|
| Services | mocking-services.md | Mock, spy |
| Fakes | mocking-fakes.md | Mail, Queue, Event |
| HTTP & Time | mocking-http.md | Http::fake, travel |
| 主题 | 参考文档 | 适用场景 |
|---|---|---|
| 服务模拟 | mocking-services.md | Mock、Spy 使用 |
| 假对象(Fakes) | mocking-fakes.md | Mail、Queue、Event 模拟 |
| HTTP与时间模拟 | mocking-http.md | Http::fake、travel 方法使用 |
Other
其他
| Topic | Reference | When to Consult |
|---|---|---|
| Console | console-tests.md | Artisan tests |
| Troubleshooting | troubleshooting.md | Common errors |
| 主题 | 参考文档 | 适用场景 |
|---|---|---|
| 控制台测试 | console-tests.md | Artisan 命令测试 |
| 故障排查 | troubleshooting.md | 常见错误解决 |
Templates
模板
| Template | When to Use |
|---|---|
| FeatureTest.php.md | HTTP feature test |
| UnitTest.php.md | Service unit test |
| ArchTest.php.md | Architecture test |
| ApiTest.php.md | REST API test |
| PestConfig.php.md | Pest configuration |
| 模板 | 适用场景 |
|---|---|
| FeatureTest.php.md | HTTP功能测试编写 |
| UnitTest.php.md | 服务单元测试编写 |
| ArchTest.php.md | 架构测试编写 |
| ApiTest.php.md | REST API测试编写 |
| PestConfig.php.md | Pest配置 |
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);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
undefinedbash
undefinedRun all tests
Run all tests
php artisan test
php artisan test
Pest directly
Pest directly
./vendor/bin/pest
./vendor/bin/pest
Parallel execution
Parallel execution
./vendor/bin/pest --parallel
./vendor/bin/pest --parallel
Filter by name
Filter by name
./vendor/bin/pest --filter "user can"
./vendor/bin/pest --filter "user can"
Coverage
Coverage
./vendor/bin/pest --coverage --min=80
./vendor/bin/pest --coverage --min=80
Profile slow tests
Profile slow tests
./vendor/bin/pest --profile
---./vendor/bin/pest --profile
---Best Practices
最佳实践
DO
✅ 建议
- Use trait
RefreshDatabase - Follow AAA pattern (Arrange-Act-Assert)
- Name tests descriptively
- Test one thing per test
- Use factories for data
- 使用trait
RefreshDatabase - 遵循AAA模式(准备-执行-断言)
- 给测试起描述性名称
- 每个测试只验证一个点
- 使用工厂生成测试数据
DON'T
❌ 避免
- Create test dependencies
- Call real external APIs
- Use production database
- Skip edge cases
- 创建测试依赖
- 调用真实外部API
- 使用生产数据库
- 忽略边缘情况