主题
测试:入门
简介
Laravel 从一开始就考虑了测试。事实上,框架开箱即支持使用 Pest 和 PHPUnit 进行测试,并且已经为你的应用程序预先配置好了 phpunit.xml 文件。框架还附带了便捷的辅助方法,让你能够优雅地测试应用程序。
默认情况下,应用程序的 tests 目录包含两个子目录:Feature 和 Unit。单元测试专注于代码中非常小的、独立的部分。实际上,大多数单元测试可能只关注单个方法。Unit 测试目录中的测试不会启动 Laravel 应用程序,因此无法访问应用程序的数据库或其他框架服务。
功能测试可以测试代码中更大的部分,包括多个对象之间的交互,甚至是完整的 HTTP 请求到 JSON 端点。通常,你的大部分测试应该是功能测试。这类测试能最大程度地确保你的整个系统按预期运行。
Feature 和 Unit 测试目录中都提供了一个 ExampleTest.php 文件。安装新的 Laravel 应用程序后,执行 vendor/bin/pest、vendor/bin/phpunit 或 php artisan test 命令即可运行测试。
环境
运行测试时,Laravel 会自动将配置环境设置为 testing,因为 phpunit.xml 文件中定义了相应的环境变量。Laravel 还会自动将 session 和 cache 配置为 array 驱动,这样在测试过程中不会持久化任何 session 或缓存数据。
你可以根据需要自由定义其他测试环境配置值。testing 环境变量可以在应用程序的 phpunit.xml 文件中配置,但请确保在运行测试之前使用 config:clear Artisan 命令清除配置缓存!
.env.testing 环境文件
此外,你可以在项目根目录下创建一个 .env.testing 文件。当运行 Pest 和 PHPUnit 测试或使用 --env=testing 选项执行 Artisan 命令时,该文件将替代 .env 文件使用。
创建测试
要创建新的测试用例,请使用 make:test Artisan 命令。默认情况下,测试将被放置在 tests/Feature 目录中:
shell
php artisan make:test UserTest如果你想在 tests/Unit 目录中创建测试,可以在执行 make:test 命令时使用 --unit 选项:
shell
php artisan make:test UserTest --unitNOTE
测试桩文件可以通过桩文件发布来自定义。
测试生成后,你可以像平常一样使用 Pest 或 PHPUnit 编写测试。要运行测试,请在终端中执行 vendor/bin/pest、vendor/bin/phpunit 或 php artisan test 命令:
php
<?php
test('basic', function () {
expect(true)->toBeTrue();
});php
<?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 来运行它们:
shell
./vendor/bin/pestshell
./vendor/bin/phpunit除了 pest 或 phpunit 命令外,你还可以使用 test Artisan 命令来运行测试。Artisan 测试运行器提供了详细的测试报告,以便于开发和调试:
shell
php artisan test任何可以传递给 pest 或 phpunit 命令的参数也可以传递给 Artisan test 命令:
shell
php artisan test --testsuite=Feature --stop-on-failure并行运行测试
默认情况下,Laravel 和 Pest / PHPUnit 在单个进程中按顺序执行测试。但是,你可以通过在多个进程中同时运行测试来大大减少运行测试所需的时间。首先,你需要安装 brianium/paratest Composer 包作为 "dev" 依赖。然后,在执行 test Artisan 命令时加上 --parallel 选项:
shell
composer require brianium/paratest --dev
php artisan test --parallel默认情况下,Laravel 会创建与机器上可用 CPU 核心数量相同的进程。但是,你可以使用 --processes 选项来调整进程数量:
shell
php artisan test --parallel --processes=4WARNING
并行运行测试时,某些 Pest / PHPUnit 选项(例如 --do-not-cache-result)可能不可用。
并行测试与数据库
只要你配置了主数据库连接,Laravel 就会自动为每个运行测试的并行进程创建和迁移测试数据库。测试数据库会以进程令牌为后缀,该令牌对每个进程都是唯一的。例如,如果你有两个并行测试进程,Laravel 将创建并使用 your_db_test_1 和 your_db_test_2 测试数据库。
默认情况下,测试数据库在多次调用 test Artisan 命令之间会保持持久化,以便后续的 test 调用可以复用。但是,你可以使用 --recreate-databases 选项重新创建它们:
shell
php artisan test --parallel --recreate-databases并行测试钩子
有时,你可能需要准备应用程序测试使用的某些资源,以便它们可以被多个测试进程安全地使用。
使用 ParallelTesting facade,你可以指定在进程或测试用例的 setUp 和 tearDown 时执行的代码。给定的闭包接收 $token 和 $testCase 变量,分别包含进程令牌和当前测试用例:
php
<?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();
测试覆盖率报告
运行应用程序测试时,你可能想确定测试用例是否实际覆盖了应用程序代码,以及运行测试时使用了多少应用程序代码。为此,你可以在调用 test 命令时提供 --coverage 选项:
shell
php artisan test --coverage强制最低覆盖率阈值
你可以使用 --min 选项为应用程序定义最低测试覆盖率阈值。如果未达到此阈值,测试套件将失败:
shell
php artisan test --coverage --min=80.3测试性能分析
Artisan 测试运行器还包含一个便捷机制,用于列出应用程序中最慢的测试。使用 --profile 选项调用 test 命令,将显示最慢的十个测试列表,让你可以轻松排查哪些测试可以改进以加快测试套件的运行速度:
shell
php artisan test --profile配置缓存
运行测试时,Laravel 会为每个测试方法单独启动应用程序。如果没有缓存的配置文件,每次测试开始时都必须加载应用程序中的每个配置文件。要构建一次配置并在单次运行的所有测试中复用,你可以使用 Illuminate\Foundation\Testing\WithCachedConfig trait:
php
<?php
use Illuminate\Foundation\Testing\WithCachedConfig;
pest()->use(WithCachedConfig::class);
// ...php
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\WithCachedConfig;
use Tests\TestCase;
class ConfigTest extends TestCase
{
use WithCachedConfig;
// ...
}