Laravel 在设计之初就考虑到了测试。事实上,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 将自动把 配置环境 设置为 testing 因为 phpunit.xml 文件中定义了相应的环境变量。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 目录下创建测试,您可以使用 --unit 选项在执行 make:test 命令时:
php artisan make:test UserTest --unit[!NOTE]
测试桩可以通过使用 存根发布 进行自定义。
测试生成后,你可以像往常一样使用 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
{
/**
* A basic test example.
*/
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 包作为 "dev" 依赖安装。然后,在执行 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
{
/**
* Bootstrap any application services.
*/
public function boot(): void
{
ParallelTesting::setUpProcess(function (int $token) {
// ...
});
ParallelTesting::setUpTestCase(function (int $token, TestCase $testCase) {
// ...
});
// Executed when a test database is created...
ParallelTesting::setUpTestDatabase(function (string $database, int $token) {
Artisan::call('db:seed');
});
ParallelTesting::tearDownTestCase(function (int $token, TestCase $testCase) {
// ...
});
ParallelTesting::tearDownProcess(function (int $token) {
// ...
});
}
}如果您想从应用程序测试代码中的任何其他位置访问当前并行进程的“令牌”,您可以使用 token 方法。此令牌是单个测试进程的唯一字符串标识符,并且可用于在并行测试进程之间划分资源。例如,Laravel 会自动将此令牌附加到由每个并行测试进程创建的测试数据库的末尾:
$token = ParallelTesting::token();
在运行您的应用程序测试时,您可能希望确定您的测试用例是否实际覆盖了应用程序代码,以及在运行测试时使用了多少应用程序代码。为了实现这一点,您可以在调用 test 命令时提供 --coverage 选项:
php artisan test --coverage您可以使用 --min 选项为您的应用程序定义一个最低测试覆盖率阈值。如果未达到此阈值,测试套件将失败:
php artisan test --coverage --min=80.3Artisan 测试运行器还包含一个便捷机制,用于列出应用程序中运行最慢的测试。使用 --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;
// ...
}