Skip to content

第 2.8 章:API 测试

学习时间: 1 小时


1. 为什么需要测试?

想象一下您建造了一艘宇宙飞船。在将其送往火星之前,您会在地球上进行数千次检查。编程中的测试也是如此。它们:

  • 提供信心: 您可以更改代码,如果测试通过,就意味着您没有破坏任何东西。
  • 节省时间: 无需在每次更改后手动在 Postman 中“点击”所有内容,您只需运行一个命令,它就会在几秒钟内为您检查所有内容。
  • 充当文档: 良好的测试会显示您的 API 应该如何工作。

2. 设置测试“实验室”

Laravel 让测试设置变得异常简单。默认情况下,它使用独立的配置,以避免影响您的主数据库。

测试数据库: 默认情况下,Laravel 使用内存中的数据库 (:memory:)。这是最快的方式,因为无需写入磁盘。数据库在测试前创建,并在测试后销毁。我们甚至不需要为此进行任何配置!

创建测试文件: 让我们创建一个专门用于行星相关测试的文件。

php artisan make:test PlanetApiTest

此命令将创建文件 tests/Feature/PlanetApiTest.php。单词 Feature 意味着我们将测试整体功能(例如,“用户能否创建行星?”),而不是单个小类。


3. 测试剖析:准备、执行、验证

打开 tests/Feature/PlanetApiTest.php。我们将在其中编写第一个测试。一个好的测试总是由三部分组成(Arrange, Act, Assert)。

<?php

namespace Tests\Feature;

use App\Models\Planet; // 不要忘记导入模型
use Illuminate\Foundation\Testing\RefreshDatabase; // 最重要的工具!
use Tests\TestCase;

class PlanetApiTest extends TestCase
{
    // 这个 trait “神奇地”清除并重新创建
    // 我们的测试数据库在每个测试之前。
    // 这确保了测试之间互不影响。
    use RefreshDatabase;

    /**
     * 测试:获取行星列表的端点是否正常工作。
     * 测试名称应该有意义!
     */
    public function test_can_get_all_planets(): void
    {
        // 1. 准备 (Arrange)
        // 在我们的测试数据库中创建 3 个模拟行星
        // 使用我们之前创建的工厂。
        Planet::factory()->count(3)->create();

        // 2. 执行 (Act)
        // 模拟对我们 API 的真实 GET 请求。
        $response = $this->getJson('/api/planets');

        // 3. 验证 (Assert)
        // 检查一切是否按预期进行。
        $response->assertStatus(200); // 期望服务器响应 "200 OK"
        $response->assertJsonCount(3); // 期望响应中正好有 3 个行星
    }
}
关键点:

  • use RefreshDatabase:这个 trait 是您最好的朋友。它确保每个测试都从“干净的画布”开始,拥有一个空的数据库。
  • Planet::factory():工厂非常适合创建测试数据。
  • $this->getJson():这是 Laravel 用于在测试内部发送 API 请求的特殊方法。
  • assert...():这些是“断言”或“检查”。如果其中任何一个没有执行,测试就会失败。

4. 测试基本操作 (CRUD)

让我们编写用于创建、更新和删除行星的测试。

A. 创建行星测试 (POST)

<?php
public function test_can_create_a_planet(): void
{
    // 1. 准备:准备新行星的数据
    $planetData = [
        'name' => 'Kepler-186f',
        'description' => 'Первая экзопланета размером с Землю в обитаемой зоне.',
        'size_km' => 14000,
        'solar_system' => 'Kepler-186'
    ];

    // 2. 执行:发送带有数据的 POST 请求
    $response = $this->postJson('/api/planets', $planetData);

    // 3. 验证
    $response->assertStatus(201); // 期望状态 "201 Created"
    $response->assertJsonFragment(['name' => 'Kepler-186f']); // 检查响应中是否存在创建的名称

    // 最重要的检查:数据是否真的进入了数据库?
    $this->assertDatabaseHas('planets', [
        'name' => 'Kepler-186f'
    ]);
}

B. 删除行星测试 (DELETE)

<?php
public function test_can_delete_a_planet(): void
{
    // 1. 准备:创建要删除的行星
    $planet = Planet::factory()->create();

    // 2. 执行:发送 DELETE 请求
    $response = $this->deleteJson("/api/planets/{$planet->id}");

    // 3. 验证
    $response->assertStatus(204); // 期望 "204 No Content" - 成功删除

    // 检查记录是否确实从数据库中消失
    $this->assertDatabaseMissing('planets', [
        'id' => $planet->id
    ]);
}


5. 测试“糟糕”场景

测试成功案例是好事。但更重要的是测试错误!

A. 验证错误测试

<?php
public function test_creation_fails_with_invalid_data(): void
{
    // 2. 执行:发送明显不正确的数据
    $response = $this->postJson('/api/planets', ['name' => '']); // 空名称

    // 3. 验证
    $response->assertStatus(422); // 期望 "422 Unprocessable Entity"
    $response->assertJsonValidationErrors('name'); // 期望错误出现在 'name' 字段中
}

B. “未找到”测试 (404)

<?php
public function test_returns_404_for_non_existent_planet(): void
{
    // 2. 执行:请求一个不存在 ID 的行星
    $response = $this->getJson('/api/planets/99999');

    // 3. 验证
    $response->assertStatus(404); // 期望 "404 Not Found"
}


6. 运行测试

现在,测试已编写完成,运行它们非常简单。在终端中执行:

php artisan test

Laravel 将找到您所有的测试并逐一执行。如果一切顺利,您将看到绿色的输出。如果某个测试失败,您将看到红色的输出以及详细的错误描述,这将使您能够快速修复它。

要仅运行一个特定文件:

php artisan test tests/Feature/PlanetApiTest.php


8. 代码覆盖率 (Code Coverage)

步骤 1:安装 Xdebug

为了收集代码覆盖率信息,需要 PHP 扩展 — Xdebug

将您的 php -i 发送到向导并按照说明进行操作。

步骤 2:配置 phpunit.xml

<phpunit ... >
    <coverage processUncoveredFiles="true">
        <include>
            <directory suffix=".php">./app</directory>
        </include>
    </coverage>
</phpunit>

步骤 3:运行并生成报告

php artisan test --coverage-html=coverage
报告:在浏览器中打开 coverage/index.html


9. 与 Postman 集成

通过 Newman 自动化:

  1. 将 Postman 集合导出到 tests/Postman/SpaceApi.postman_collection.json
  2. 安装 Newman:
    npm install -g newman
    
  3. 将脚本添加到 composer.json
    "scripts": {
        "test:postman": "newman run tests/Postman/SpaceApi.postman_collection.json"
    }
    
  4. 运行:
    composer test:postman
    

巩固测验

1. 创建测试类的命令:

2. RefreshDatabase trait 用于:

3. 检查 JSON 结构的方法:

4. Laravel 中的工厂用于:

5. 从 CLI 运行 Postman 集合的工具:


🚀 本章总结: 您已完成完整的飞行前测试周期!现在您的API可以:

  • ✅ 轻松配置测试环境
  • 🛡️ 按照“准备-操作-验证”原则编写测试
  • 📊 测试成功场景 (CRUD) 和错误 (验证, 404)
  • 🔁 使用一条命令运行测试,并对代码充满信心

宇宙飞船已准备就绪,可以发射! 您已完成Laravel API创建部分。

📌 最终检查:

  1. 运行 php artisan test
  2. 确保所有测试通过(绿灯!)
  3. 检查覆盖率报告

⚠️ 如果测试失败:

  • 通过 Postman 检查 API 的运行情况
  • 确保测试数据库已配置
  • 使用 dd($response->content()) 进行调试

恭喜您完成第2章! 您不仅创建了一个 API,还创建了一个可靠且经过验证的“宇宙飞船”,可用于未来的任务。

🌌 后续步骤:

  1. 配置认证 (Sanctum)
  2. 使用 Swagger 文档化 API
  3. 在服务器上部署 (Forge, VPS)
  4. 使用 Vue/React 编写前端

祝您的太空任务发射成功!在下一章中,我们将从头开始编写 API 🚀