初めてでも分かるPHPUnitの備忘録

Featured image of the post

概要

テストの自動化について初めて学習したときの備忘録🔰

ユニットテストとは
  • 日本語で単体テストのこと。
  • ある機能だけに焦点をおいてテストする。

    →関数ごとにテストしたりする✅

テスト自動化とは
  • ユニットテストを自動化する。
  • 主に取得している値は意図した値か?を自動テストする。

メリット⭕️
  • 一度自動化するといつでも自動テストが呼び出せる
  • 修正したときのテストが楽。

デメリット❌
  • テストコードを書く必要がある。
  • 一度きりのテストなら手動のテストのほうが早い

PHPUnitとは

PHPのテスト自動化の便利機能が詰まったテストフレームワーク✅

「実際のプログラム」と「テスト用のコード」が別ファイルに分かれているので、実際の動作には影響を出さずにテストできる。

【補足】PHP標準のassert関数との違い

PHPUnitではassert〇〇という関数が出てくる(後述)。

これらの関数はassertと似た動作をするが用途が異なる。

PHP標準のassert
  • デバッグのサポートとして使う。
  • 画面操作中にエラーが発生したときにアサートが発生して原因特定がしやすい。

PHPUnit
  • テスト自動化に使う。
  • 画面操作しなくてもコマンド1つでテストができる。
  • コマンド1つでいつでも同じテストが実行できる。

事前に必要なもの

PHPUnitを使うためcomposerが必要✅

composerのインストール方法は以下を参照。

PHPUnitをインストール

※プロジェクトごとにPHPUnitをインストールすること。

※Laravelの場合、標準でPHPUnitがインストールされているためこの手順は不要。

詳細な説明は公式サイトに記載されているので、ここでは要点だけ説明する✅

インストール

プロジェクトディレクトリで、以下のコマンドを実行する✅

composer require phpunit/phpunit --dev

インストールしたphpUnitはvendor/bin/phpunitにある。

確認

以下のコマンドでバージョンが表示されればインストールが成功している✅

vendor/bin/phpunit --version

おまじない

テストするクラスで毎回requireを書かずに済むよう、オートロード機能を設定する。

composer.json

{
	"autoload": {
        "psr-4": {
            "App\\": "テストするディレクトリ名/"
        }
    }
}

その後、以下のコマンドを実行して設定を反映させる。

composer dump

【必要な場合のみ】

「テスト実行時に指定するオプション」をあらかじめ指定しておくことができる。

(毎回オプションを指定する必要がなくなる)

phpunit.xml(プロジェクト直下に新規作成)

<phpunit
    bootstrap="vendor/autoload.php"
    colors="true"
>
    <testsuites>
        <testsuite name="Example Test Suite">
            <directory>tests</directory>
        </testsuite>
    </testsuites>
</phpunit>

上記の例では、以下の設定が行われている。

  • bootstrap="vendor/autoload.php"

    テストを実行する前に自動的に読み込まれるファイルを指定する。

    ここでは、vendor/autoload.phpファイルを指定しています。

  • colors="true"

    PHPUnitがカラーの出力を使用するかどうかを指定する。

  • <testsuite name="Example Test Suite">

    テストスイートを定義するために使用する。

    ここでは、Example Test Suiteという名前のテストスイートを定義し、testsディレクトリにあるテストを含めるように指定している。

💡
phpunit.xmlファイルを使用すると、PHPUnitの設定をカスタマイズして、より効率的にテストができる。

テストコードを書く

自動テストするために「何をテストするのか」を書く必要がある✅

【前提】今回テストするもの

Hogeクラスにある関数をテストする!

Hoge.php

<?php
class Hoge
{
    // サンプルの関数
    public function Sample01(){
        return 'これはSample01です';
    }
    
    // サンプルの関数
    public function Sample02( $x, $y ){
        $sum = $x + $y;
        return $sum;
    }
}
?>

フォルダ構成

プロジェクトフォルダ
     |
     |----Hoge.php(👈作成)
     |
     |----vendor(PHPUnitをインストールしたらできているはず)

ファイルの作成

テストコードを書くファイルを新規作成する。

保存場所

どこでもOK!

一般的にはtestフォルダなど分かりやすい場所に作成しておく。

ファイル名

〇〇Test.phpにすること!

今回はHogeをテストするのでHogeTest.phpとする。

フォルダ構成

プロジェクトフォルダ
     |
     |----Hoge.php
     |
     |----vendor
     |
     |----test(👈作成)
     |      |
     |      |----HogeTest.php(👈作成)

💡
ファイル名は命名規則が決まっているので注意!

テストコードを書く

自動テストするために「何をテストするのか」を書く✅

ここが一番大事!

HogeTest.php

<?php 
// テストで使う関数をインポート
use PHPUnit\Framework\TestCase;

// テストしたいクラスをインポート
require_once 'Hoge.php';

// ✅テストクラス
class HogeTest extends TestCase
{
    // ---------------------------------------------------------------------
    // 準備
    // ---------------------------------------------------------------------

    // ✅テストで使う変数の準備
    private $hoge;
    public function setUp() :void{
        // 必ず親クラスのsetUpを呼んでおくこと
        parent::setUp();

        // Hogeインスタンスを準備(各関数でインスタンスを生成せずに済む)
        $this->hoge = new Hoge();
    }
    
    // ---------------------------------------------------------------------
    // テスト
    // ---------------------------------------------------------------------

    // ✅Sample01関数のテスト
    public function testSample01(){
        // ✅'これはSample01です'が返ってくるか?
        $this->assertEquals( 'これはSample01です', $this->hoge->Sample01() );
    }

    // Sample02関数のテスト
    public function testSample02(){
        // 2が返ってくるか?
        $this->assertEquals( 2, $this->hoge->Sample02( 1, 1 ) );
        
        // 4が返ってくるか?
        $this->assertEquals( 4, $this->hoge->Sample02( 2, 2 ) );

        // 10が返ってくるか?
        $this->assertEquals( 10, $this->hoge->Sample02( 4, 6 ) );
    }
}

?>

解説✅
  • class HogeTest extends TestCase{ ... }

    テストをするためのクラスを定義する。

    必ずTestCaseを継承すること。

  • public function setUp() :void{ ... }

    テスト前に実行したい処理を書く関数。

    関数名は必ずsetUp()にすること。

  • public function testSample01(){ ... }

    テストを書く関数。

    関数名は必ずtest〇〇にすること。

  • $this->assertEquals( 'これはSample01です', $this->hoge->Sample01() );

    具体的なテスト内容。

    assertEqualsは引数1, 2が等しいかテストする。

💡
テストにはassert〇〇という関数を使う。

自動テストを実行する

以下のコマンドを実行するだけ✅

vendor/bin/phpunit テストファイルがあるフォルダ

testフォルダにあるテストを実行したい場合は以下のようになる。

vendor/bin/phpunit test

フォルダ構成

プロジェクトフォルダ
     |
     |----test
     |      |
     |      |----HogeTest.php(👈テストが実行される)

💡
testフォルダにある〇〇Test.phpがすべて実行される!
(ファイル名の指定は不要)

他のテスト関数

先ほどの例ではassertEqualsを使って引数1, 2が等しいかどうかテストした。

他にもテスト関数があるのでよく使うものを紹介する✅

関数名説明使用例
assertEquals2つの値が等しいことを検証するassertEquals(41, $actualValue, 'メッセージ');
assertGreaterThan / assertGreaterThanOrEqual 1つの値が別の値より大きい / 大きいか等しいことを検証するassertGreaterThan(5, $actualValue, 'メッセージ');
assertGreaterThanOrEqual(5, $actualValue, 'メッセージ');
assertLessThan / assertLessThanOrEqual 1つの値が別の値より小さい / 小さいか等しいことを検証するassertLessThan(10, $actualValue, 'メッセージ');
assertLessThanOrEqual(10, $actualValue, 'メッセージ');
assertTrue /
assertFalse
条件が / であることを検証するassertTrue($isTrue, 'メッセージ');
assertFalse($isFalse, 'メッセージ');
assertNull /
assertNotNull
値がnull / nullでないことを検証するassertNull($nullValue, 'メッセージ');
assertNotNull($notNullValue, 'メッセージ');
assertSame2つの値が同じオブジェクトであることを検証するassertSame($obj1, $obj2, 'メッセージ');
assertCount配列やカウント可能なオブジェクトの要素数が同じであることを検証するassertCount(3, $countableArray, 'メッセージ');
assertInstanceOf値が特定のクラスのインスタンスであることを検証するassertInstanceOf(ExpectedClass::class, $actualValue, 'メッセージ');
assertArrayHasKey配列に特定のキーが存在することを検証するassertArrayHasKey('key', $array, 'メッセージ');
assertStringContainsString文字列に特定の文字列が含まれることを検証するassertStringContainsString('needle', $haystack, 'メッセージ');
assertFileExists /
assertFileNotExists
ファイルが存在する / 存在しないことを検証するassertFileExists($filePath, 'メッセージ');
assertFileNotExists($filePath, 'メッセージ');

💡
最後の引数はテスト失敗時のメッセージ。省略可能!

テストコードを書くコツ

✅主に関数データベースのテスト自動化に使う
  • データベースのテスト自動化について今回触れていないので別途調べる。

1つのテスト関数でテストしすぎない
  • どこでエラーが出ているか分かりにくくなる。
  • 複数の関数を実行するとテスト結果に影響が出る危険性が増す。

    特にテストする値が関数内で加工される場合は注意。

さまざまなパターンのテストを用意しておく
  • 正常系を複数テスト
  • 異常系を複数テスト
  • 境界値を複数テストなど

以下でテストコードのアンチパターンについて書かれていて参考になる。

参考サイト

インストール部分を参考にした。

setUp関数を参考にした。