Laravel TDD 工作流
使用 PHPUnit 和 Pest 为 Laravel 应用程序进行测试驱动开发,覆盖率(单元 + 功能)达到 80% 以上。
使用时机
- Laravel 中的新功能或端点
- 错误修复或重构
- 测试 Eloquent 模型、策略、作业和通知
- 除非项目已标准化使用 PHPUnit,否则新测试首选 Pest
工作原理
红-绿-重构循环
- 编写一个失败的测试
- 实施最小更改以通过测试
- 在保持测试通过的同时进行重构
测试层级
- 单元:纯 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();
…