跳轉至內容

測試:入門指南

簡介

Laravel 在設計時就考慮到了測試。事實上,它開箱即用支援 PestPHPUnit 測試,並且你的應用程式中已經預置了 phpunit.xml 檔案。該框架還提供了便捷的輔助方法,讓你可以直觀地測試應用程式。

預設情況下,你的應用程式 tests 目錄包含兩個子目錄:FeatureUnit。單元測試(Unit tests)專注於程式碼中極小且獨立的部分。實際上,大多數單元測試可能只針對單個方法。“Unit”測試目錄下的測試不會啟動完整的 Laravel 應用程式,因此無法訪問資料庫或其他框架服務。

功能測試(Feature tests)可以測試更大範圍的程式碼,包括多個物件之間的互動,甚至是傳送到 JSON 端點的完整 HTTP 請求。通常情況下,大部分測試應該是功能測試。這類測試最能確保整個系統按預期執行。

FeatureUnit 測試目錄中都提供了一個 ExampleTest.php 檔案。安裝新的 Laravel 應用程式後,執行 vendor/bin/pestvendor/bin/phpunitphp artisan test 命令即可執行測試。

環境

執行測試時,由於 phpunit.xml 檔案中定義了環境變數,Laravel 會自動將配置環境設定為 testing。Laravel 還會自動將 Session 和快取配置為 array 驅動,這樣測試過程中就不會持久化任何 Session 或快取資料。

你可以根據需要自由定義其他測試環境配置值。testing 環境變數可以在應用程式的 phpunit.xml 檔案中進行配置,但在執行測試之前,請務必使用 config:clear Artisan 命令清除配置快取!

.env.testing 環境檔案

此外,你還可以在專案根目錄下建立 .env.testing 檔案。在執行 Pest 和 PHPUnit 測試或使用 --env=testing 選項執行 Artisan 命令時,該檔案將取代 .env 檔案被使用。

建立測試

要建立新的測試用例,請使用 make:test Artisan 命令。預設情況下,測試將被放置在 tests/Feature 目錄中。

1php artisan make:test UserTest

如果你想在 tests/Unit 目錄中建立測試,可以在執行 make:test 命令時使用 --unit 選項。

1php artisan make:test UserTest --unit

可以透過釋出存根 (stub) 來自定義測試存根。

測試生成後,你可以像平時一樣使用 Pest 或 PHPUnit 定義測試。要執行測試,請在終端執行 vendor/bin/pestvendor/bin/phpunitphp artisan test 命令。

1<?php
2 
3test('basic', function () {
4 expect(true)->toBeTrue();
5});
1<?php
2 
3namespace Tests\Unit;
4 
5use PHPUnit\Framework\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic test example.
11 */
12 public function test_basic_test(): void
13 {
14 $this->assertTrue(true);
15 }
16}

如果你在測試類中定義了自己的 setUp / tearDown 方法,請務必在父類上呼叫相應的 parent::setUp() / parent::tearDown() 方法。通常,你應該在自己的 setUp 方法開頭呼叫 parent::setUp(),並在 tearDown 方法末尾呼叫 parent::tearDown()

執行測試

如前所述,編寫完測試後,可以使用 pestphpunit 執行它們。

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

除了 pestphpunit 命令外,你還可以使用 test Artisan 命令來執行測試。Artisan 測試執行器提供了詳細的測試報告,以簡化開發和除錯過程。

1php artisan test

所有可以傳遞給 pestphpunit 命令的引數,同樣可以傳遞給 Artisan 的 test 命令。

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

並行執行測試

預設情況下,Laravel 和 Pest / PHPUnit 會在單個程序中按順序執行測試。但是,你可以透過在多個程序中同時執行測試,大大縮短測試時間。首先,你需要安裝 brianium/paratest Composer 包作為“dev”依賴。然後,在執行 test Artisan 命令時加上 --parallel 選項。

1composer require brianium/paratest --dev
2 
3php artisan test --parallel

預設情況下,Laravel 將建立與機器 CPU 核心數相當的程序數量。你也可以使用 --processes 選項來調整程序數。

1php artisan test --parallel --processes=4

並行執行測試時,某些 Pest / PHPUnit 選項(例如 --do-not-cache-result)可能不可用。

並行測試與資料庫

只要你配置了主資料庫連線,Laravel 就會自動為每個並行執行測試的程序處理測試資料庫的建立和遷移。測試資料庫將帶有一個程序識別符號字尾,該識別符號在每個程序中都是唯一的。例如,如果你有兩個並行測試程序,Laravel 將建立並使用 your_db_test_1your_db_test_2 作為測試資料庫。

預設情況下,測試資料庫在呼叫 test Artisan 命令後會持久存在,以便後續的 test 呼叫可以再次使用。不過,你可以使用 --recreate-databases 選項重新建立它們。

1php artisan test --parallel --recreate-databases

並行測試鉤子

有時,你可能需要準備應用程式測試所需的某些資源,以便它們能被多個測試程序安全使用。

使用 ParallelTesting 門面(facade),你可以指定在程序或測試用例的 setUptearDown 時執行的程式碼。提供的閉包會接收 $token$testCase 變數,分別包含程序識別符號和當前測試用例。

1<?php
2 
3namespace App\Providers;
4 
5use Illuminate\Support\Facades\Artisan;
6use Illuminate\Support\Facades\ParallelTesting;
7use Illuminate\Support\ServiceProvider;
8use PHPUnit\Framework\TestCase;
9 
10class AppServiceProvider extends ServiceProvider
11{
12 /**
13 * Bootstrap any application services.
14 */
15 public function boot(): void
16 {
17 ParallelTesting::setUpProcess(function (int $token) {
18 // ...
19 });
20 
21 ParallelTesting::setUpTestCase(function (int $token, TestCase $testCase) {
22 // ...
23 });
24 
25 // Executed when a test database is created...
26 ParallelTesting::setUpTestDatabase(function (string $database, int $token) {
27 Artisan::call('db:seed');
28 });
29 
30 ParallelTesting::tearDownTestCase(function (int $token, TestCase $testCase) {
31 // ...
32 });
33 
34 ParallelTesting::tearDownProcess(function (int $token) {
35 // ...
36 });
37 }
38}

獲取並行測試識別符號(Token)

如果你想在應用程式測試程式碼的其他任何位置訪問當前的並行程序“識別符號”,可以使用 token 方法。該識別符號是一個用於區分單個測試程序的唯一字串,可用於在並行測試程序之間劃分資源。例如,Laravel 會自動將此識別符號追加到每個並行測試程序建立的測試資料庫名稱末尾。

1$token = ParallelTesting::token();

報告測試覆蓋率

此功能需要 XdebugPCOV

在執行應用程式測試時,你可能需要確定測試用例是否確實覆蓋了應用程式程式碼,以及執行測試時使用了多少應用程式程式碼。為此,你可以在呼叫 test 命令時提供 --coverage 選項。

1php artisan test --coverage

強制執行最小覆蓋率閾值

你可以使用 --min 選項為應用程式定義最低測試覆蓋率閾值。如果未達到此閾值,測試套件將失敗。

1php artisan test --coverage --min=80.3

測試效能分析

Artisan 測試執行器還包含一個方便的機制來列出應用程式中最慢的測試。使用 --profile 選項呼叫 test 命令,它將展示最慢的十個測試列表,讓你輕鬆排查哪些測試可以最佳化,從而加快測試套件的執行速度。

1php artisan test --profile

配置快取

執行測試時,Laravel 會為每個獨立的測試方法啟動應用程式。如果沒有快取的配置檔案,應用程式中的每個配置檔案都必須在測試開始時載入。要構建一次配置並在單次執行的所有測試中重用它,你可以使用 Illuminate\Foundation\Testing\WithCachedConfig trait。

1<?php
2 
3use Illuminate\Foundation\Testing\WithCachedConfig;
4 
5pest()->use(WithCachedConfig::class);
6 
7// ...
1<?php
2 
3namespace Tests\Feature;
4 
5use Illuminate\Foundation\Testing\WithCachedConfig;
6use Tests\TestCase;
7 
8class ConfigTest extends TestCase
9{
10 use WithCachedConfig;
11 
12 // ...
13}