LoginSignup
136

More than 5 years have passed since last update.

PHPUnit 入門

Last updated at Posted at 2017-06-29

※6.3のドキュメントから引っ張ってきてます

規則

・クラス名は「対象名Test」
・テストを行うメソッド名は「test*」
・「PHPUnit\Framework\TestCase」を継承する
・テストはコードを上から下へなめていく

書き方

<?php
use PHPUnit\Framework\TestCase;

class HogeTest extends TestCase
{
    public function testHoge()
    {
        $stack = [];
        $this->assertEquals(0, count($stack));
    }
}

アサーション

テストの結果を判定するメソッド。
「$this->アサーションメソッド」「self::アサーションメソッド」のいずれかの方法で使用する。

引数にメッセージを指定すると、エラー時に出力してくれる。

下記で主に使うものを抜粋。

※引数で期待値と結果はどっち先に書くんだっけ ⇒ 先に期待値かく

メソッド 説明
assertEmpty(\$actual[, $message]) $actualが空なら正常
assertEquals(\$expected, \$actual[, $message]) \$expectedと$actualが一致すれば正常
assertSame(\$expected, \$actual[, $message]) assertEqualsで型もみる厳密版
assertNotSame(\$expected, \$actual[, $message]) assertSameの逆
assertTrue(\$actual[, $message]) $actualがtrueなら正常
assertFalse(\$actual[, $message]) $actualがfalseなら正常
assertNull(\$actual[, $message) $actualがnullなら正常

前処理、後処理

テストメソッド単位

各テストメソッドの実施の度に、その前後で呼ばれる。

protected function setUp()
{
  //前処理
}

protected function tearDown()
{
  //後処理
}

テストクラス単位

テストケースとして、最初のテストメソッド開始前に一度のみ、
最後のテストメソッド終了時に一度だけ実行される。

protected function setUpBeforeClass()
{
  //前処理
}

protected function tearDownAfterClass()
{
  //後処理
}

コマンド

実行

phpunit [options] テストクラス名 [テスト.php]

⇒「テストクラス名.php」を実施。
 テストクラス名とファイル名が不一致なら、ファイルも一緒に指定する。

phpunit [options] ディレクトリ

⇒ディレクトリ配下のテストを実施。

オプション

抜粋。
細かいオプションはコマンドではなく、phpunit.xmlにて設定したほうが良いので。

オプション 説明
--bootstrap phpファイル テストの前に実行される bootstrap.phpを指定します。
-c XMLファイル 設定を XML ファイルから読み込みます。

phpunit.xmlがカレントディレクトリにある場合、オプションなしでも読み込まれる。

テストの結果の見方

ステータス 説明
. 成功
F アサーション失敗
E テスト中にエラー発生
R テストが危険?
S テストを省略
I テストが未完成

テクニック

依存

@depends 依存メソッド名」をdocコメント用いると、
テストメソッドはdependsで指定したメソッドに依存しているとされ、
依存メソッドの結果を引数で受け取れる。

※テストの実施順序はかわらないため、記述順序は依存を解決するように書く

function testA()
{
  $hoge = 'hoge';
  return $hoge;
}

/*
 * @depends testA
 */
function testB($hoge)
{
}

データプロバイダ

1テストメソッドに対し、さまざまなテストデータを渡し、
複数のケースのテストをしたいときに使う。

public function addProvider() {
  return array(
    'test1' => (1, 2, 3),
    'test2' => (2, 3, 5),
  );
}

/**
 * @dataProvider addProvider
 */
public function testHoge($a, $b, $result) {
  $this->assertEquals($result, ($a + $b));
}

未完成を明記

テストメソッドを未完成としたい場合、markTestIncomplete([メッセージ])メソッドを記載しておけばよい。

public function testHoge()
{
  $this->markTestIncomplete(
    'このテストは、まだ実装されていません。'
  );
}

テストの省略

環境等の問題などでテストを省略したい場合に、
markTestSkipped([メッセージ])メソッドを記載しておけばよい。

public function testHoge()
{
  $this->markTestSkipped(
    '省略します'
  );
}

テストダブル

モックのこと。

createMockメソッド

いくつかのデフォルト設定を持ったモックを作成するメソッド。

$stub = $this->createMock(SomeClass::class);

主なデフォルト設定は

  • コンストラクタを実行しない
  • 全メソッドが、nullを返すだけのダミー実装になる
  • final,private,staticのメソッドは作られない

ちなみに、以下のgetMockBuilderメソッドと同等。

$stub = $this->getMockBuilder($originalClassName)
       ->disableOriginalConstructor()
       ->disableOriginalClone()
       ->disableArgumentCloning()
       ->disallowMockingUnknownTypes()
       ->getMock();

getMockBuilderメソッド

createMockの挙動をカスタマイズするときに使用するメソッド。

  • コンストラクタは置き換えない
  • 全メソッドが、nullを返すだけのダミー実装になる

設定用メソッド

メソッド 説明
getMock() モックの取得
disableOriginalConstructor() 元クラスのコンストラクタを無効にする
setMethods($array_methods) 置き換えたいメソッドを指定。

nullを指定すると置換しない。
setConstructorArgs(array $args) コンストラクタに渡す引数を指定
disableOriginalClone() 元クラスのクローンコンストラクタを無効にする
disableAutoload() __autoload()を無効にする

メソッドの戻り値を置き換える

$stub = $this->createMock(SomeClass::class);

$stub->method('hoge')->willReturn('foo');
$stub->method('fuga')->will($this->returnValue('foo'));

willReturnメソッド

戻り値を設定するだけ。

willメソッド

細かく戻り値を設定できる。

下記に抜粋。

メソッド 説明
will(\$this->returnValue($value)) 戻り値に指定値をセット
will(\$this->returnArgument($num)) メソッドに渡された$num番目の引数を戻り値にセット
will(\$this->returnSelf()) 戻り値に自オブジェクトをセット
will(\$this->throwException(new Exception)) 戻り値に例外をセット

ReflectionClassを使う

privateなメソッドやプロパティのアクセス権限を変えてテストをしたいとき、
もしくはそれをモック化して、テストで利用したいときに使う。

テスト対象のprivateなプロパティをモックで置換する
//プロパティに置換させたいモックを作成
$prop_mock = $this->getMock('HogeClass');

//テスト対象をモック化
$target = $this->getMockBuilder('Target')
  ->setConstructorArgs(array(array()))
  ->setMethods(array('Method1', 'Method2'))
  ->getMock();

//テスト対象のprivateプロパティを緩めて、モックで置換
$ref = new ReflectionClass($target); 

$prop = $ref ->getProperty('prop');
$prop->setAccessible(true); //アクセス権限をゆるくする
$prop->setValue($target, $prop_mock);

phpunit.xml

その他引っかかったこと

「headers already sent by」的なエラーが出たとき

対応
PHPのTestでheader関数によるエラーを回避する

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
136