PHP入門:PHPUnitで任意の引数を受け取ってテストする

スポンサーリンク
PHP入門:PHPUnitで任意の引数を受け取ってテストする ノウハウ
PHP入門:PHPUnitで任意の引数を受け取ってテストする
この記事は約13分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

今日は、PHPUnitで任意の引数を受け取ってテストするテストケースについてご紹介します。

スポンサーリンク

前提

この記事は下記の記事をベースにしています。

背景

先日、PHPUnitのデータプロバイダメソッドを使用したテストの実施方法を示しています。

修正内容

下記のファイルを更新、もしくは、作成します。下記の各セクションに各ファイルの修正内容を記載しています。

        new file:   19_learn_phpunit/tests/NumericDataSetsTest.php

tests/NumericDataSetsTest.php

下記の内容で新規作成します。

<?php declare(strict_types=1);
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

final class NumericDataSetsTest extends TestCase
{
    public static function additionProvider(): array
    {
        return [
            [0, 0, 0],
            [0, 1, 1],
            [1, 0, 1],
            [1, 1, 3],
        ];
    }

    #[DataProvider('additionProvider')]
    public function testAdd(int $a, int $b, int $expected): void
    {
        $this->assertSame($expected, $a + $b);
    }
}

動作確認

下記のコマンドを実施します。

docker compose run -it --rm php-cmd ./vendor/bin/phpunit tests/NumericDataSetsTest.php

下記の結果になれば成功です。

% docker compose run -it --rm php-cmd ./vendor/bin/phpunit tests/NumericDataSetsTest.php
[+] Building 0.0s (0/0)                                                                                                                            
[+] Building 0.0s (0/0)                                                                                                                            
PHPUnit 10.2.6 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.1.12-1ubuntu4.2

...F                                                                4 / 4 (100%)

Time: 00:00.079, Memory: 8.00 MB

There was 1 failure:

1) NumericDataSetsTest::testAdd with data set #3
Failed asserting that 2 is identical to 3.

/work/tests/NumericDataSetsTest.php:20

FAILURES!
Tests: 4, Assertions: 4, Failures: 1.

解説

tests/NumericDataSetsTest.php

このPHPコードは、PHPUnitを使用してテストケースを作成する方法を示しています。特に、データプロバイダを使用して異なるデータセットで同じテストメソッドを繰り返し実行する方法を示しています。

以下がコードの詳細です:

  1. <?php declare(strict_types=1);: これはPHPのオープニングタグで、strict typeの宣言を含んでおり、厳密な型チェックが有効になっています。
  2. use PHPUnit\Framework\Attributes\DataProvider;: この行は、DataProvider属性を使うために必要なクラスをインポートしています。
  3. use PHPUnit\Framework\TestCase;: この行は、PHPUnitのTestCaseクラスをインポートしています。これは、テストケースを記述するための基本的な機能を提供します。
  4. final class NumericDataSetsTest extends TestCase: この行は、NumericDataSetsTestクラスを定義しています。これは、PHPUnitのTestCaseクラスを継承したテストクラスです。
  5. public static function additionProvider(): array: この行は、データプロバイダメソッドadditionProviderを定義しています。データプロバイダは、テストメソッドに渡すテストデータを提供する役割を担います。このメソッドは、配列として複数のテストデータセットを返します。各データセットは、引数$a$b(整数)と、期待される結果$expected(整数)からなります。
  6. #[DataProvider('additionProvider')]: この行は、データプロバイダをtestAddメソッドに結び付けるための属性を示しています。testAddメソッドは、additionProviderメソッドから提供された各データセットで繰り返し実行されます。
  7. public function testAdd(int $a, int $b, int $expected): void: この行は、テストメソッドtestAddを定義しています。このメソッドは、データプロバイダから提供されたデータセットを受け取り、$a$bを足し算して、結果が$expectedと同じであることを検証します。

テストはadditionProviderメソッドが返す複数のデータセットに対して実行されます。各データセットは、testAddメソッドで指定されたパラメータとして渡され、その結果が期待される結果($expected)と一致するかどうかを確認します。

なお、このコードのスニペットでは、$a + $bが誤って$a$bの和が$expectedと一致すると想定していますが、正しい結果は$a + $bです。したがって、[1, 1, 3]のデータセットはテストに失敗するはずです。修正する場合は、[1, 1, 2]のように$expectedを正しい値に変更する必要があります。

外部データ・プロバイダの使用

下記のように外部データ・プロバイダを使用することもできます。

<?php declare(strict_types=1);
use PHPUnit\Framework\Attributes\DataProviderExternal;
use PHPUnit\Framework\TestCase;

final class NumericDataSetsTestUsingExternalDataProvider extends TestCase
{
    #[DataProviderExternal(ExternalDataProvider::class, 'additionProvider')]
    public function testAdd(int $a, int $b, int $expected): void
    {
        $this->assertSame($expected, $a + $b);
    }
}

final class ExternalDataProvider
{
    public static function additionProvider(): array
    {
        return [
            [0, 0, 0],
            [0, 1, 1],
            [1, 0, 1],
            [1, 1, 3],
        ];
    }
}

このPHPコードは、PHPUnitのデータプロバイダを外部クラスで定義して使用する方法を示しています。外部データプロバイダを使用すると、テストデータを別のクラスに分離し、テストケースクラスをよりシンプルに保つことができます。

以下がコードの詳細です:

  1. <?php declare(strict_types=1);: これはPHPのオープニングタグで、strict typeの宣言を含んでおり、厳密な型チェックが有効になっています。
  2. use PHPUnit\Framework\Attributes\DataProviderExternal;: この行は、DataProviderExternal属性を使うために必要なクラスをインポートしています。
  3. use PHPUnit\Framework\TestCase;: この行は、PHPUnitのTestCaseクラスをインポートしています。これは、テストケースを記述するための基本的な機能を提供します。
  4. final class NumericDataSetsTestUsingExternalDataProvider extends TestCase: この行は、NumericDataSetsTestUsingExternalDataProviderクラスを定義しています。これは、PHPUnitのTestCaseクラスを継承したテストクラスです。
  5. #[DataProviderExternal(ExternalDataProvider::class, 'additionProvider')]: この行は、外部データプロバイダをtestAddメソッドに結び付けるための属性を示しています。ExternalDataProviderクラスのadditionProviderメソッドから提供されたデータセットで、testAddメソッドが繰り返し実行されます。
  6. public function testAdd(int $a, int $b, int $expected): void: この行は、テストメソッドtestAddを定義しています。このメソッドは、外部データプロバイダから提供されたデータセットを受け取り、$a$bを足し算して、結果が$expectedと同じであることを検証します。
  7. final class ExternalDataProvider: この行は、ExternalDataProviderクラスを定義しています。これは、外部データプロバイダのクラスです。
  8. public static function additionProvider(): array: この行は、ExternalDataProviderクラス内のデータプロバイダメソッドadditionProviderを定義しています。データプロバイダは、テストメソッドに渡すテストデータを提供する役割を担います。このメソッドは、配列として複数のテストデータセットを返します。各データセットは、引数$a$b(整数)と、期待される結果$expected(整数)からなります。

テストは、ExternalDataProviderクラスのadditionProviderメソッドが返す複数のデータセットに対して実行されます。各データセットは、testAddメソッドで指定されたパラメータとして渡され、その結果が期待される結果($expected)と一致するかどうかを確認します。

なお、このコードのスニペットでも、$a + $bが誤って$a$bの和が$expectedと一致すると想定していますが、正しい結果は$a + $bです。したがって、[1, 1, 3]のデータセットはテストに失敗するはずです。修正する場合は、[1, 1, 2]のように$expectedを正しい値に変更する必要があります。

データセットに名前をつける

それぞれに文字列のキーで名前をつけることもできます。テストに失敗したデータセットの名前を含むので、出力はより冗長になりますが、どのデータかが分かりやすくなるメリットがあります。

<?php declare(strict_types=1);
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

final class NamedDataSetsTest extends TestCase
{
    public static function additionProvider(): array
    {
        return [
            'adding zeros'  => [0, 0, 0],
            'zero plus one' => [0, 1, 1],
            'one plus zero' => [1, 0, 1],
            'one plus one'  => [1, 1, 3],
        ];
    }

    #[DataProvider('additionProvider')]
    public function testAdd(int $a, int $b, int $expected): void
    {
        $this->assertSame($expected, $a + $b);
    }

データプロバイダーについて

テストメソッドは任意の引数を受け取ることができます。これらの引数は、ひとつあるいは複数のデータプロバイダメソッド (下に示す例では addProvider()) で指定します。使用するデータプロバイダメソッドは、PHPUnitFramework 属性か PHPUnitFramework 属性で指定します。

データプロバイダメソッドは public で static でなければなりません。反復可能な値、つまり配列か Traversable インターフェースを実装したオブジェクトを返さなければなりません。各反復ステップでは、配列を返さなければなりません。これらの配列のそれぞれについて、配列の内容を引数としてテスト・メソッドが呼び出されます。

PHPUnitのデータプロバイダーは、同じテストメソッドを複数回実行し、異なるデータセットでテストするための機能です。データプロバイダーを使用することで、同じテストコードを再利用して、さまざまなテストケースを効率的に実行できます。

データプロバイダーの利点は次のとおりです:

  1. 複数のテストケースをシンプルに記述できる: 同じテストケースを複数回実行する必要がある場合でも、データプロバイダーを使用すると、同じテストコードを簡潔に保ちながら、異なるデータセットでテストを行うことができます。
  2. テストデータを別のクラスに分離: データプロバイダーを外部クラスに定義することで、テストケースクラスを読みやすく保ち、テストデータを別の場所に集約することができます。
  3. データプロバイダーの再利用: 同じデータプロバイダーを複数のテストケースクラスで使用できます。これにより、同じテストデータを異なるテストケースで共有できます。

データプロバイダーを作成するには、テストケースクラス内にプライベートまたはプロテクテッドのデータプロバイダーメソッドを定義します。このメソッドは、通常は配列として複数のテストデータセットを返します。各データセットは、テストメソッドの引数として渡されます。

おわりに

今日は、PHPUnitで任意の引数を受け取ってテストするテストケースについてご紹介しました。

本記事でご紹介したソースは、下記のリポジトリにあります。

https://github.com/Gate-Yossi/Ran/releases/tag/v2023.08.08
よっしー
よっしー

何か質問や相談があれば、遠慮なくコメントしてください。また、エンジニア案件についても、いつでも相談にのっていますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました