phpのテストフレームワークであるPHPUnitを使って自動テスト環境を構築する手順をまとめます。
>> PHPUnitの公式ドキュメントはこちら
Contents
準備
// 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)