Laravel通过PHPUnit提供单元测试和功能测试支持,单元测试验证类方法逻辑,如PriceCalculator计算折扣;功能测试模拟HTTP请求,验证接口行为,如用户注册;测试文件存于tests/目录,Unit为单元测试,Feature为功能测试;使用RefreshDatabase确保数据隔离,结合工厂模型、HTTP测试方法和断言提升效率。

在 Laravel 中进行单元测试和功能测试是保障应用质量的重要手段。Laravel 基于 PHPUnit 构建了完整的测试支持,开箱即用,开发者可以轻松编写测试用例来验证代码逻辑、路由行为、数据库交互等。
理解 Laravel 中的测试类型
Laravel 支持两种主要测试类型:单元测试和功能测试,它们各有侧重:
- 单元测试:针对单个类、方法或函数,验证其内部逻辑是否正确。例如测试一个计算订单总价的服务类方法。
- 功能测试:模拟用户行为,测试整个请求-响应流程,包括路由、中间件、控制器、数据库操作等。例如测试登录接口是否能正确返回 token。
Laravel 默认将测试文件放在 tests/ 目录下,其中 Unit/ 存放单元测试,Feature/ 存放功能测试。
编写单元测试
单元测试关注的是代码的最小可测单元,应尽量隔离外部依赖,如数据库、缓存、第三方服务等。
例如,假设有一个计算折扣价格的类:
class PriceCalculator{
public function applyDiscount(float $price, float $discount): float
{
return $price * (1 - $discount);
}
}
对应的单元测试可以这样写:
// tests/Unit/PriceCalculatorTest.phpuse Tests\TestCase;
use App\PriceCalculator;
class PriceCalculatorTest extends TestCase
{
/** @test */
public function it_calculates_discounted_price_correctly()
{
$calculator = new PriceCalculator();
$result = $calculator->applyDiscount(100, 0.1);
$this->assertEquals(90, $result);
}
}
使用 php artisan test --filter=PriceCalculatorTest 可单独运行该测试。
编写功能测试
功能测试模拟 HTTP 请求,验证实际接口行为。Laravel 提供了丰富的断言方法来检查响应状态、JSON 结构、数据库变化等。
例如测试用户注册接口:
// tests/Feature/UserRegistrationTest.phpuse Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class UserRegistrationTest extends TestCase
{
use RefreshDatabase;
/** @test */
public function user_can_register_via_api()
{
$response = $this->postJson('/api/register', [
'name' => 'John Doe',
'email' => 'john@example.com',
'password' => 'secret123',
'password_confirmation' => 'secret123',
]);
$response->assertStatus(201)
->assertJsonStructure(['user' => ['id', 'name', 'email']]);
$this->assertDatabaseHas('users', ['email' => 'john@example.com']);
}
}
RefreshDatabase Trait 确保每次测试前后数据库被清理,避免数据污染。
使用测试辅助工具
Laravel 提供了许多便利功能提升测试效率:
- 工厂模型(Model Factories):快速生成测试数据。通过 User::factory()->create() 创建用户记录。
- HTTP 测试方法:如 get()、post()、json() 模拟各种请求。
- 断言方法:如 assertStatus()、assertSee()、assertValid() 验证响应内容。
- 模拟(Mocking):使用 $this->mock() 或 Http::fake() 模拟外部服务调用。
基本上就这些。只要坚持写测试,配合 Laravel 强大的测试支持,就能有效提升代码健壮性和开发效率。测试不是负担,而是对代码信心的投资。









