LaravelDocs(中文)

測試:入門 (Getting Started)

Laravel 從一開始就考慮到測試,內建對 Pest 和 PHPUnit 的支援

測試:入門

介紹 (Introduction)

Laravel 從一開始就考慮到測試。事實上,內建就支援使用 PestPHPUnit 進行測試,並且已經為您的應用程式設定好了 phpunit.xml 檔案。框架還附帶了方便的輔助方法,讓您可以有效地測試您的應用程式。

預設情況下,您的應用程式的 tests 目錄包含兩個目錄:FeatureUnit。單元測試 (Unit tests) 是專注於程式碼中非常小、獨立部分的測試。事實上,大多數單元測試可能專注於單一方法。「Unit」測試目錄中的測試不會啟動您的 Laravel 應用程式,因此無法存取您的應用程式的資料庫或其他框架服務。

功能測試 (Feature tests) 可能會測試更大部分的程式碼,包括多個物件如何相互作用,甚至是完整的 HTTP request 到 JSON endpoint。一般來說,您的大多數測試應該是功能測試。這些類型的測試最能確保您的系統整體按預期運作。

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

環境 (Environment)

執行測試時,Laravel 會自動將 設定環境 設定為 testing,因為 phpunit.xml 檔案中定義了環境變數。Laravel 也會自動將 session 和 cache 設定為 array 驅動程式,這樣在測試時就不會保留任何 session 或 cache 資料。

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

.env.testing 環境檔案 (The Env Testing Environment File)

此外,您可以在專案的根目錄中建立一個 .env.testing 檔案。當執行 Pest 和 PHPUnit 測試或使用 --env=testing 選項執行 Artisan 命令時,將使用此檔案代替 .env 檔案。

建立測試 (Creating Tests)

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

php artisan make:test UserTest

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

php artisan make:test UserTest --unit

[!NOTE] 測試 stubs 可以使用 stub 發布 來自訂。

測試產生後,您可以像平常一樣使用 Pest 或 PHPUnit 定義測試。要執行您的測試,請從終端機執行 vendor/bin/pestvendor/bin/phpunitphp 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()

執行測試 (Running Tests)

如前所述,撰寫測試後,您可以使用 pestphpunit 執行它們:

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

除了 pestphpunit 命令外,您還可以使用 test Artisan 命令來執行測試。Artisan 測試執行器提供詳細的測試報告,以便於開發和除錯:

php artisan test

任何可以傳遞給 pestphpunit 命令的參數也可以傳遞給 Artisan test 命令:

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

平行執行測試 (Running Tests In Parallel)

預設情況下,Laravel 和 Pest / PHPUnit 會在單一 process 中依序執行您的測試。但是,您可以透過跨多個 processes 同時執行測試來大幅減少執行測試所需的時間。首先,您應該安裝 brianium/paratest Composer 套件作為「dev」依賴項。然後,在執行 test Artisan 命令時加入 --parallel 選項:

composer require brianium/paratest --dev

php artisan test --parallel

預設情況下,Laravel 會建立與您機器上可用 CPU 核心數量相同的 processes。但是,您可以使用 --processes 選項來調整 processes 的數量:

php artisan test --parallel --processes=4

[!WARNING] 平行執行測試時,某些 Pest / PHPUnit 選項(例如 --do-not-cache-result)可能無法使用。

平行測試與資料庫 (Parallel Testing And Databases)

只要您已設定主要資料庫連線,Laravel 會自動為執行測試的每個平行 process 建立和遷移測試資料庫。測試資料庫會加上 process token 作為後綴,每個 process 都是唯一的。例如,如果您有兩個平行測試 processes,Laravel 會建立並使用 your_db_test_1your_db_test_2 測試資料庫。

預設情況下,測試資料庫會在 test Artisan 命令呼叫之間保留,以便後續的 test 呼叫可以再次使用它們。但是,您可以使用 --recreate-databases 選項來重新建立它們:

php artisan test --parallel --recreate-databases

平行測試 Hooks (Parallel Testing Hooks)

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

使用 ParallelTesting facade,您可以指定在 process 或測試案例的 setUptearDown 上執行的程式碼。給定的 closures 會接收 $token$testCase 變數,分別包含 process token 和目前的測試案例:

<?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 (Accessing The Parallel Testing Token)

如果您想從應用程式測試程式碼的任何其他位置存取目前的平行 process「token」,您可以使用 token 方法。此 token 是單個測試 process 的唯一字串識別碼,可用於跨平行測試 processes 分隔資源。例如,Laravel 會自動將此 token 附加到每個平行測試 process 建立的測試資料庫末尾:

$token = ParallelTesting::token();

報告測試覆蓋率 (Reporting Test Coverage)

[!WARNING] 此功能需要 XdebugPCOV

執行應用程式測試時,您可能想要確定您的測試案例是否實際覆蓋了應用程式程式碼,以及在執行測試時使用了多少應用程式程式碼。要達成這一點,您可以在呼叫 test 命令時提供 --coverage 選項:

php artisan test --coverage

強制執行最低覆蓋率門檻 (Enforcing A Minimum Coverage Threshold)

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

php artisan test --coverage --min=80.3

分析測試 (Profiling Tests)

Artisan 測試執行器還包含一個方便的機制,用於列出應用程式最慢的測試。使用 --profile 選項呼叫 test 命令,將會顯示十個最慢的測試列表,讓您可以輕鬆調查哪些測試可以改進以加速您的測試套件:

php artisan test --profile

設定快取 (Configuration Caching)

執行測試時,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;

    // ...
}