快速入门

未匹配的标注
本文档最新版为 12.x,旧版本可能放弃维护,推荐阅读最新版!

测试:入门

简介

Laravel 在设计时就考虑了测试。事实上,框架开箱即支持使用 Pest 和 PHPUnit 进行测试,并已为你的应用配置好 phpunit.xml 文件。框架还提供了便捷的辅助方法,让你能够以清晰易读的方式测试应用。

默认情况下,应用的 tests 目录包含两个子目录:Feature 和 Unit。单元测试专注于代码中很小且独立的一部分。事实上,大多数单元测试可能只针对一个方法。「Unit」测试目录中的测试不会启动 Laravel 应用,因此无法访问应用的数据库或其他框架服务。

功能测试可以测试更大范围的代码,包括多个对象之间的交互,甚至是向 JSON 端点发送的完整 HTTP 请求。通常,你的大多数测试都应该是功能测试。这类测试最能让你确信整个系统按预期运行。

Feature 和 Unit 测试目录中都提供了一个 ExampleTest.php 文件。安装新的 Laravel 应用后,执行 vendor/bin/pest、vendor/bin/phpunit 或 php artisan test 命令即可运行测试。

环境

运行测试时,Laravel 会根据 phpunit.xml 文件中定义的环境变量,自动将配置环境设为 testing。Laravel 还会自动将会话和缓存的驱动设为 array,确保测试期间不会持久化任何会话或缓存数据。

你可以根据需要定义其他测试环境配置值。testing 环境的变量可以在应用的 phpunit.xml 文件中配置,但运行测试前,请务必使用 config:clear Artisan 命令清除配置缓存!

.env.testing 环境文件

此外,你可以在项目根目录创建一个 .env.testing 文件。运行 Pest 和 PHPUnit 测试,或使用 --env=testing 选项执行 Artisan 命令时,该文件将替代 .env 文件。

创建测试

要创建新的测试用例,可以使用 make:test Artisan 命令。默认情况下,测试文件会放在 tests/Feature 目录中:

php artisan make:test UserTest

如果你想在 tests/Unit 目录中创建测试,可以在执行 make:test 命令时使用 --unit 选项:

php artisan make:test UserTest --unit

如果某个测试类中的大多数测试依赖 Laravel 的测试功能,但其中某个测试方法无需启动框架,你可以为该方法添加 #[UnitTest] 特性,仅在运行这个测试时跳过应用启动。

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\Attributes\UnitTest;
use Tests\TestCase;

class LocationServiceTest extends TestCase
{
    public function test_get_coordinates_resolves_address(): void
    {
        // 此测试使用 Laravel 的测试功能……
    }

    #[UnitTest]
    public function test_get_state_returns_state_from_abbreviation(): void
    {
        // 此测试运行时不会启动应用……
    }
}

[!NOTE]
你可以通过发布 stub 文件来自定义测试模板。

生成测试后,你就可以像平常一样使用 Pest 或 PHPUnit 定义测试。要运行测试,请在终端执行 vendor/bin/pest、vendor/bin/phpunit 或 php artisan test 命令:

<?php

test('basic', function () {
    expect(true)->toBeTrue();
});
<?php

namespace Tests\Unit;

use PHPUnit\Framework\TestCase;

class ExampleTest extends TestCase
{
    /**
     * 一个基本的测试示例。
     */
    public function test_basic_test(): void
    {
        $this->assertTrue(true);
    }
}

[!WARNING]
如果你在测试类中自定义了 setUp / tearDown 方法,请务必分别调用父类的 parent::setUp() / parent::tearDown() 方法。通常,你应该在自定义的 setUp 方法开头调用 parent::setUp(),并在 tearDown 方法末尾调用 parent::tearDown()。

运行测试

如前所述,编写好测试后,你可以使用 pest 或 phpunit 来运行测试:

./vendor/bin/pest
./vendor/bin/phpunit

除了使用 pest 或 phpunit 命令,你还可以使用 test Artisan 命令来运行测试。Artisan 测试运行器会提供详细的测试报告,方便开发和调试:

php artisan test

所有可以传递给 pest 或 phpunit 命令的参数,也都可以传递给 Artisan 的 test 命令:

php artisan test --testsuite=Feature --stop-on-failure

并行运行测试

默认情况下,Laravel 和 Pest / PHPUnit 会在单个进程中依次执行测试。不过,你可以通过在多个进程中同时运行测试,大幅缩短测试耗时。首先,将 brianium/paratest Composer 包安装为开发依赖。然后,在执行 test Artisan 命令时添加 --parallel 选项:

composer require brianium/paratest --dev

php artisan test --parallel

默认情况下,Laravel 创建的进程数量与你的机器上可用的 CPU 核心数相同。不过,你可以使用 --processes 选项调整进程数量:

php artisan test --parallel --processes=4

[!WARNING]
并行运行测试时,某些 Pest / PHPUnit 选项(如 --do-not-cache-result)可能无法使用。

并行测试与数据库

只要你配置了主数据库连接,Laravel 就会自动为每个运行测试的并行进程创建测试数据库并执行迁移。这些测试数据库的名称会加上各进程独有的标识符作为后缀。例如,如果你有两个并行测试进程,Laravel 就会创建并使用 your_db_test_1 和 your_db_test_2 测试数据库。

默认情况下,测试数据库会在多次调用 test Artisan 命令之间保留,以便后续运行 test 时再次使用。不过,你可以使用 --recreate-databases 选项重新创建它们:

php artisan test --parallel --recreate-databases

并行测试钩子

有时,你可能需要为应用测试准备某些资源,以便多个测试进程能够安全地使用它们。

你可以使用 ParallelTesting facade,指定在进程或测试用例的 setUp 和 tearDown 阶段执行的代码。传入的闭包会接收 $token 和 $testCase 变量,分别表示进程标识符和当前测试用例:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\ParallelTesting;
use Illuminate\Support\ServiceProvider;
use PHPUnit\Framework\TestCase;

class AppServiceProvider extends ServiceProvider
{
    /**
     * 启动应用服务。
     */
    public function boot(): void
    {
        ParallelTesting::setUpProcess(function (int $token) {
            // ...
        });

        ParallelTesting::setUpTestCase(function (int $token, TestCase $testCase) {
            // ...
        });

        // 创建测试数据库时执行……
        ParallelTesting::setUpTestDatabase(function (string $database, int $token) {
            Artisan::call('db:seed');
        });

        ParallelTesting::tearDownTestCase(function (int $token, TestCase $testCase) {
            // ...
        });

        ParallelTesting::tearDownProcess(function (int $token) {
            // ...
        });
    }
}

获取并行测试标识符

如果你想在应用测试代码的其他位置访问当前并行进程的标识符(token),可以使用 token 方法。这个标识符是各个测试进程独有的字符串,可用于在并行测试进程之间划分资源。例如,Laravel 会自动将这个标识符追加到每个并行测试进程创建的测试数据库名称末尾:

$token = ParallelTesting::token();

生成测试覆盖率报告

[!WARNING]
此功能需要 Xdebug 或 PCOV。

运行应用测试时,你可能想知道测试用例是否真正覆盖了应用代码,以及运行测试时实际执行了多少应用代码。为此,你可以在调用 test 命令时添加 --coverage 选项:

php artisan test --coverage

强制要求最低覆盖率

你可以使用 --min 选项为应用定义最低测试覆盖率。如果覆盖率未达到该阈值,测试套件将失败:

php artisan test --coverage --min=80.3

测试性能分析

Artisan 测试运行器还提供了便捷的方式来列出应用中最慢的测试。使用 --profile 选项调用 test 命令时,会列出耗时最长的十个测试,方便你找出可以优化的测试,加快测试套件的运行速度:

php artisan test --profile

配置缓存

运行测试时,Laravel 会为每个测试方法单独启动应用。如果没有缓存的配置文件,每个测试开始时都必须加载应用中的所有配置文件。要在一次测试运行中只构建一次配置,并让所有测试复用它,你可以使用 Illuminate\Foundation\Testing\WithCachedConfig trait:

<?php

use Illuminate\Foundation\Testing\WithCachedConfig;

pest()->use(WithCachedConfig::class);

// ...
<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\WithCachedConfig;
use Tests\TestCase;

class ConfigTest extends TestCase
{
    use WithCachedConfig;

    // ...
}

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/laravel/13.x/te...

译文地址:https://learnku.com/docs/laravel/13.x/te...

上一篇 下一篇
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
贡献者:1
讨论数量: 0
发起讨论 只看当前版本


暂无话题~