翻譯進度
50.98% 已翻譯
更新時間:
2024年6月30日 上午8:27:00 [世界標準時間]
翻譯人員:
幫我們翻譯此頁

測試:入門

簡介

Laravel 在設計時就已將測試考慮進去。而且,Laravel 有內建 PHPUnit 支援,且 Laravel 還隨附了一個已設定好可在專案內使用的 phpunit.xml 。在 Laravel 中,也有許多方便的輔助函式,能讓我們精準地對專案進行測試。

預設情況下,專案的 tests 目錄內包含了兩個目錄:FeatureUnitUnit Test(單元測試) 是專注於測試一些小部分、與其他部分獨立的程式碼。其實,單元測試可能會只專注於測試單一方法。在「Unit」測試目錄下的測試不會啟用 Laravel 專案,因此無法存取專案的資料庫或其他 Laravel 的服務。

Feature Test(功能測試)可用來測試較大部分的程式碼 —— 測試各個物件要如何互相使用、測試 JSON Endpoint 的完整 HTTP Request 等。一般來說,大多數的測試應該都是 Feature Test。使用 Feature Test 有助於確保整體系統如期運作。

FeatureUnit 測試目錄下都有提供了一個 ExampleTest.php 檔。安裝好新的 Laravel 專案後,執行 vendor/bin/phpunitphp artisan test 指令即可執行測試。

環境

When running tests, Laravel will automatically set the configuration environment to testing because of the environment variables defined in the phpunit.xml file. Laravel also automatically configures the session and cache to the array driver so that no session or cache data will be persisted while testing.

若有需要,也可以自行定義其他的測試環境設定值。testing 環境變數可以在專案的 phpunit.xml 檔案中修改。不過,在執行測試前,請記得使用 config:clear Artisan 指令來清除設定快取!

.env.testing 環境檔

除此之外,也可以也可以在專案根目錄上建立一個 .env.testing 檔案。在執行 PHPUnit 測試或使用 --env=testing 選項執行 Artisan 指令時,會使用這個檔案來代替 .env 檔案。

CreatesApplication Trait

Laravel 中包含了一個 CreatesApplication Trait。在專案的基礎 TestCase 類別中有套用這個 Trait。CreatesApplication 裡包含了一個 createApplication 方法,用來在執行測試前啟動 Laravel 程式。需注意要將該 Trait 保留在原位,因為某些 Laravel 的功能 —— 如平行測試 —— 需要仰賴於該 Trait。

建立測試

若要建立新測試例,請使用 make:test Artisan 指令。預設情況下,測試會被放在 tests/Feature 目錄下:

1php artisan make:test UserTest
1php artisan make:test UserTest

若要在 tests/Unit 目錄下建立測試,可在執行 make:test 指令時使用 --unit 選項:

1php artisan make:test UserTest --unit
1php artisan make:test UserTest --unit

若要建立 Pest PHP 測試,可在 make:test 指令上使用 --pest 選項:

1php artisan make:test UserTest --pest
2php artisan make:test UserTest --unit --pest
1php artisan make:test UserTest --pest
2php artisan make:test UserTest --unit --pest
lightbulb

可以安裝 Stub 來自訂測試的 Stub。

產生好測試後,即可如平常使用 PHPUnit 一般來定義測試方法。若要執行測試,請在終端機內執行 vendor/bin/phpunitphp artisan test 指令:

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}
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}
lightbulb

If you define your own setUp / tearDown methods within a test class, be sure to call the respective parent::setUp() / parent::tearDown() methods on the parent class. Typically, you should invoke parent::setUp() at the start of your own setUp method, and parent::tearDown() at the end of your tearDown method.

執行測試

就像剛才提到的,寫好測試後,可使用 phpunit 來執行測試:

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

除了 phpunit 指令外,我們也可以使用 test Artisan 指令來執行測試。Artisan 的測試執行程式會提供較多輸出的測試報告,以讓我們能更輕鬆地進行開發與偵錯:

1php artisan test
1php artisan test

所有可傳給 phpunit 指令的引數都可傳給 Artisan test 指令:

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

Running Tests in Parallel

By default, Laravel and PHPUnit execute your tests sequentially within a single process. However, you may greatly reduce the amount of time it takes to run your tests by running tests simultaneously across multiple processes. To get started, you should install the brianium/paratest Composer package as a "dev" dependency. Then, include the --parallel option when executing the test Artisan command:

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

預設情況下,Laravel 會以機器上可用的 CPU 核心數來建立處理程序。不過,我們也可以使用 --processes 選項來調整處理程序的數量:

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

平行執行測試時,可能無法使用部分 PHPUnit 的選項 (如 --do-not-cache-result)。

Parallel Testing and Databases

只要你有設定主要的資料庫連線,Laravel 就會自動為每個執行測試的平行處理程序建立並 Migrate 測試資料庫。Laravel 會使用每個處理程序都不同的處理程序 Token 來作為資料庫的前置詞。舉例來說,若有兩個平行的測試處理程序,則 Laravel 會建立並使用 your_db_test_1your_db_test_2 測試資料庫。

預設情況下,在不同的 test Artisan 指令間,會共用相同的測試資料庫,以在連續呼叫 test 指令時使用這些資料庫。不過,我們也可以使用 --create-databases 選項來重新建立測試資料庫:

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

平行測試的 Hook

有時候,我們會需要為一些專案所使用的特定資源做準備,好讓我們能在多個測試處理程序中使用這些資源。

只要使用 ParallelTesting Facade,就可指定要在處理程序或測試例的 setUptearDown 內要執行的特定程式碼。給定的閉包會收到 $token$testCase 變數,著兩個變數中分別包含了處理程序的 Token,以及目前的測試例:

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}
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}

Accessing the Parallel Testing Token

若想從測試程式碼中的任何地方存取目前平行處理程序的「Token」,我們可以使用 token 方法。對於各個測試處理程序來說,平行處理程序的「Token」是一個不重複的字串,可用來在多個平行測試處理程序上為資源分段。舉例來說,Laravel 會自動將該 Token 放在各個由平行測試處理程序所建立的測試資料庫名稱後方:

1$token = ParallelTesting::token();
1$token = ParallelTesting::token();

回報測試覆蓋率

lightbulb

要使用該功能,需安裝 XdebugPCOV

在執行專案測試時,我們可能會想判斷測試例是否有實際涵蓋到專案的程式碼、或是想知道在執行測試時到底使用到專案中多少的程式碼。若要瞭解測試覆蓋率,可在叫用 test 指令時提供 --coverage 選項:

1php artisan test --coverage
1php artisan test --coverage

Enforcing a Minimum Coverage Threshold

可使用 --min 選項來為專案定義最低測試覆蓋率門檻。若未符合該門檻,測試套件會執行失敗:

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

測試分析

Artisan 的測試執行程式中也包含了一個方便的機制,能讓我們列出專案中最慢的測試。執行 test 指令時提供 --profile 選項,就可以看到一組列表中列出了 10 個最慢的測試,讓我們能輕鬆調查可以改善哪些測試來讓測試套件執行更快:

1php artisan test --profile
1php artisan test --profile
翻譯進度
50.98% 已翻譯
更新時間:
2024年6月30日 上午8:27:00 [世界標準時間]
翻譯人員:
幫我們翻譯此頁

留言

尚無留言

“Laravel” is a Trademark of Taylor Otwell.
The source documentation is released under MIT license. See laravel/docs on GitHub for details.
The translated documentations are released under MIT license. See cornch/laravel-docs-l10n on GitHub for details.