Code PHP

【PHPUnit】PHPの自動テスト実装する

2023年2月11日

phpのテストフレームワークであるPHPUnitを使って自動テスト環境を構築する手順をまとめます。
>> PHPUnitの公式ドキュメントはこちら

準備

// php
$ php -V
PHP 8.2.1 (cli) (built: Jan 12 2023 15:19:18) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.1, Copyright (c) Zend Technologies
with Zend OPcache v8.2.1, Copyright (c), by Zend Technologies
// 2023年2月時点の最新バージョンPHPUnit10を使用する場合は、PHP8.1以上の利用が推奨

// composer 
$ composer --version
Composer version 2.5.3 2023-02-10 13:23:52

PHPUnitの環境構築

PHPUnitのインストール

PHPUnitを使いたいプロジェクト直下で以下のコマンドを実行します。

composer require --dev phpunit/phpunit

設定ファイル(phpunit.xml)

PHPUnitの設定はphpunit.xmlというファイルで管理します。
Laravelなどの最近のWebフレームワークでは、プロジェクト作成時にデフォルトでphpunit.xmlが作成してくれます。

<phpunit colors="true"
         verbose="true"
         bootstrap="vendor/autoload.php"
>
    <testsuites>
        <testsuite name="Unit">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>
        <testsuite name="Feature">
            <directory suffix="Test.php">./tests/Feature<directory>
        </testsuite>
    </testsuites>
</phpunit>

PHPUnitの機能

アサーション

PHPUnitでは、アサーションメソッドを使用しテストの合否判定を行います。

アサーションメソッドの一覧

よく使うアサーションメソッドのを抜粋で示します。

アサーションメソッド名 判定内容
assertEquals($expected, $actual) $expectedと$actualが等しい
assertNotEquals($expected, $actual) $expectedと$actualが等しくない
assertSame($expected, $actual) $expectedと$actualが型も含めて等しい
assertTrue($condition) $conditionがtrue
assertFalse($condition) $conditionがfalse
assertFileExists($filename) $filenameで指定されたファイルが存在する
assertIsArray($actual) $actualがarrayである
assertInstanceOf($expected, $actual) $expectedが$actualのインスタンスである

アサーションメソッドの実装例

assertEquals

<?php
declare(strict_types=1);

use PHPUnit\Framework\TestCase;

class EqualsTest extends TestCase
{
    public function testEqualsSuccess(): void
    {
        $expected = '太郎';
        $this->assertEquals($expected, '太郎');
    }

    public function testEqualsFailure(): void
    {
        $expected = '次郎';
        $this->assertNotEquals($expected, '太郎');
    }
}

assertIsArray

<?php
declare(strict_types=1);

use PHPUnit\Framework\TestCase;

class IsArrayTest extends TestCase
{
    public function testIsArraySuccess(): void
    {
        $this->assertIsArray(['cat', 'dog', 'elephant']);
    }

    public function testIsArrayFailure(): void
    {
        $this->assertIsNotArray('cat');
    }
}

assertInstanceOf

<?php
declare(strict_types=1);

use PHPUnit\Framework\TestCase;

class InstanceOfTest extends TestCase
{
    public function testInstanceOfSuccess(): void
    {
        $this->assertInstanceOf(RuntimeException::class, new Exception);
    }

    public function testInstanceOfFailure(): void
    {
        $this->assertNotInstanceOf(RuntimeException::class, new TypeError);
    }
}

アノテーション

@dataProvider

テストに必要なデータを別メソッドとして定義し、変数に与えることができます。
特にロジックは変更せずに引数を少しずつ変更するテストを実装する場合に有効です。

<?php
declare(strict_types=1);

use PHPUnit\Framework\TestCase;

class SampleTest extends TestCase
{
    /**
     * 足し算のテスト
     * @param $data
     * @return void
     *
     * @dataProvider calSumDataProvider
     */
    public function testCalcSum($data)
    {
        $sum = $data[0] + $data[1];
        $this->assertEquals($data[2], $sum);
    }
    public function calcSumDataProvider(): array
    {
        return [
            '1+1=2' => [1, 1, 2],
            '2+3=5' => [2, 3, 5] ,
            '5+6=11' => [5, 6, 11]
        ];
    }
}

1つのtestメソッドで、dataProviderに定義されている複数のテストを実行することができます。

@testWith

テストに使用するデータをPHPDocに含めて記述することができます。

データプロバイダに比べると処理とデータを1つのメソッドにまとめることができる一方、データが複雑になると逆に可読性が落ちてしまいます。

<?php
declare(strict_types=1);

use PHPUnit\Framework\TestCase;

class SampleTest extends TestCase
{
    /**
     * 足し算のテスト
     * @testWith [1, 1, 2]
     *           [2, 3, 5]
     *           [5, 6, 11]
     */
    public function testCalcSum($a, $b, $c)
    {
        $sum = $a + $b;
        $this->assertEquals($c, $sum);
    }
}

@testdox

テストケースの説明をPHPDocに記述することができます。

<?php
declare(strict_types=1);

use PHPUnit\Framework\TestCase;

class SampleTest extends TestCase
{
    /**
     * @testdox 足し算のテスト
     * @testWith [1, 1, 2]
     *           [2, 3, 5]
     *           [5, 6, 11]
     */
    public function testCalcSum($a, $b, $c)
    {
        $sum = $a + $b;
        $this->assertEquals($c, $sum);
    }

--testdoxオプションをつけて実行することでテストの実行結果に説明文を表示することができます。
実行時にどのようなテストか瞬時に判断することができます。

./vendor/bin/phpunit --testdox

PHPUnit 9.5.26 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.1.12
Configuration: /path/to/phpunit.xml

 ✔ 足し算のテスト with data set 0  4 ms
 ✔ 足し算のテスト with data set 0  1 ms
 ✔ 足し算のテスト with data set 0  1 ms

Time: 00:00.005, Memory: 6.00 MB

OK (3 tests, 3 assertions)

-Code, PHP

© 2024 トンボのようにまっすぐ進んでいたい Powered by AFFINGER5