前のパートに戻る 完了して次のパートへ  

  1-1 PHPUnit の基本的な使い方

PHPUnit とは


PHP を使ったアプリケーションのためのデファクトスタンダードなテスティングフレームワークです。

現在(2020年4月)、9.1 が最新版ですが、Laravel の最新版(7.5)に同梱されているのは 8.5 です。

公式ドキュメントには日本語訳もありますが、最新版しかないので、もしお読みになる際はその点ご注意ください(この「最新版」は PHPUnit の最新版を指しているわけではなく、ドキュメントの最新版、という意味です。筆者が確認した範囲では、 廃止されたアサーションメソッドが含まれていたり、新たに追加になったアサーションメソッドがなかったりしたので、一度英語版にも目を通しておくことをおすすめします。 英語版は過去のバージョンのもあります)。

最新版(日本語版): https://phpunit.readthedocs.io/ja/latest/

8.5(英語版): https://phpunit.readthedocs.io/en/8.5/


設定ファイル


Laravel をインストールしたディレクトリに phpunit.xml というファイルがありますが、これが設定ファイルです。

testsuites

「テストスイート」というテストをグルーピングするためのリストです。それぞれの testsuite タグにある name 属性に書かれた文字列がテストスイート名で、これを実行時に下記のように指定すると、それぞれ directory タグで指定した条件に一致するテストのみを実行するようにできます。

# php artisan test --testsuite=Unit

filter - whitelist

カバレッジ計測の対象を directory タグで指定したディレクトリのみに限定します。

php - server

実行時に PHP の特殊変数 $_SERVER にキーと値のペアを登録します。

Laravel では内部で .env に書かれたキーと値のペアを環境変数として扱っていますが、同時にサーバ変数を使えるようにもなっているため、 server タグで .env に書かれた環境変数を上書きすることができます。


命名規則とアノテーション

テストクラスのファイル名は Test.php で終わるようにしてください

メソッド名は test で始めるか、そうでない場合は @test アノテーションを DocComment 内に記述してください

あるいは

テストメソッドの DocComment 内に @covers アノテーションを書くと、テスト対象のメソッドを明示的に指定することができます

テストクラスの DocComment 内に @coversDefaultClass アノテーションを書くと、テスト対象のクラスを明示的に指定することができます

@covers アノテーションのメソッド名の指定方法が簡素化されていることに注意してください。


本教材での命名規則

本教材では、原則的に以下の規則でクラス、メソッドを定義します。

  • クラス名は、アッパーキャメルケースで「テスト対象のクラス名 + Test」とする
  • 例)対象のクラスが SomeClass なら SomeClassTest
  • メソッド名はローワーキャメルケースで「test + テスト対象のメソッド名」とする
  • 例)対象のメソッドが someMethod なら testSomeMethod
  • 同一のメソッドに対するテストメソッドが複数のメソッドに分割される場合は _ (アンダースコア)で区切る
  • 例)testSomeMethod_Success, testSomeMethod_Failure
  • データプロバイダーのメソッド名は、テストメソッドの test を data に置き換えたものとする
  • 例)testSomeMethod のデータプロバイダーなら dataSomeMethod

実行方法

php artisan test と vendor/bin/phpunit は同じです。本教材では、前者を使いますが、出力が若干異なるので状況に応じて使い分けてください。具体的には、テストコードまたはプロダクションコードで dump, var_dump などで標準出力に出力したい場合は後者を使ってください。

全体を実行する

# php artisan test

ユニットテストまたはフィーチャーテストのみを実行する

# php artisan test --testsuite=Unit

フィーチャーテストの場合は Unit の代わりに Feature を記述してください。

特定のテストクラスのみを実行する

# php artisan test tests/Unit/ExampleTest.php

拡張子はなくても大丈夫です。

特定のメソッドのみを実行する

# php artisan test tests/Unit/ExampleTest.php --filter=testBasicTest

PhpStorm や Visual Studio Code をお使いの方は GUI から実行することもできますが、ここでは手順を解説しませんので、興味のある方は調べてみてください。

代表的なアサーション

引数を2つ取る場合は、1番目に「期待される値」、2番目に「実際の値」(関数からの戻り値など)を指定します。

また、個別には書きませんが、assert の後に Not を挟むと条件を反転させることができます。

例)assertEquals / assertNotEquals, assertNull / assertNotNull

assertSame

PHP では 1 == '1' は真ですが、このメソッドでは型が一致するかどうかもチェックします。つまり、 1 === '1' の厳格な比較になります(厳密にはまったく同じではないので、 assertTrue(1 === '1') とは書かずに assertSame を使うことをおすすめします)。

両者が配列の場合は、キーの順序も比較します。したがって以下の結果になります。

assertEquals

assertSame と異なり、緩やかな比較です(型が一致する必要はありません)。

両者が配列の場合は、キーの順序は比較しません。したがって以下の結果になります。

原則的に assertSame を使い、明確に緩やかな比較を使用したいときにのみ assertEquals を使うといいでしょう。

assertTrue / assertFalse

boolean を返すメソッドの戻り値をチェックしたいときに使います。

assertArrayHasKey

配列の中に指定したキーが含まれているかどうかをチェックします。値は見ずにキーだけチェックしたい場合に使います。

assertContains

配列の中に指定した値が含まれているかどうかをチェックします。

以前は文字列に対しても使えましたが、PHPUnit 9 で廃止されるため、非推奨になっています。文字列の場合は次の assertStringContainsString を使ってください。

assertStringContainsString

これは部分一致ですが、先頭あるいは末尾がマッチするかどうかを確認したい場合は、 assertStringStartsWith または assertStringEndsWith を使ってください。

assertRegExp

より柔軟に文字列の構造も含めてチェックしたい場合は、正規表現を使ったチェックができる assertRegExp が便利です。

よく使うアサーションメソッドはこんなところですが、他にもたくさんのアサーションメソッドがありますので、公式マニュアルを覗いてみてください。

また、Laravel が独自に追加しているアサーションメソッドもありますが、それは次節「Laravel アプリケーションにおけるテストの基本的な考え方」で紹介します。

議論

2 質問

このコースの評価は?