Prev Next

第4章 PHPUnit 用のテストの書き方

例 4.1 は、PHPUnit を使用する形式で 例 1.4 の 2 つのテストを書き直したものです。

例 4.1: PHPUnit を使用した Array および sizeof() のテスト

<?php
require_once 'PHPUnit/Framework.php';

class ArrayTest extends PHPUnit_Framework_TestCase
{
public function testNewArrayIsEmpty()
{
// 配列を作成します。
$fixture = array();

// 配列のサイズは 0 です。
$this->assertEquals(0, sizeof($fixture));
}

public function testArrayContainsAnElement()
{
// 配列を作成します。
$fixture = array();

// 配列にひとつの要素を追加します。
$fixture[] = 'Element';

// 配列のサイズは 1 です。
$this->assertEquals(1, sizeof($fixture));
}
}
?>

 

Whenever you are tempted to type something into a print statement or a debugger expression, write it as a test instead.

何かを print 文やデバッガの式に書きたくなったときは、 代わりにその内容をテストに書くようにするんだ。

 
  --Martin Fowler

例 4.1 では、 PHPUnit を使用してテストを記述する基本手順を説明しています。

  1. Class という名前のクラスのテストは、ClassTest という名前のクラスに記述します。

  2. ClassTest は、(ほとんどの場合) PHPUnit_Framework_TestCase を継承します。

  3. テストは、test* という名前のパブリックメソッドとなります。

    あるいは、@test アノテーションをメソッドのコメント部で使用することで、それがテストメソッドであることを示すこともできます。

  4. テストメソッドの中で assertEquals() のようなアサーションメソッド (表 21.1 を参照ください) を使用して、期待される値と実際の値が等しいことを確かめます。

データプロバイダ

テストメソッドには任意の引数を渡すことができます。 この引数は、データプロバイダメソッド (例 4.2provider()) で指定します。使用するデータプロバイダメソッドを指定するには @dataProvider アノテーションを使用します。

データプロバイダメソッドは、public かつ static でなければなりません。また、 メソッドの返り値の型は、配列の配列あるいはオブジェクト (Iterator インターフェイスを実装しており、 反復処理の際に配列を返すもの) である必要があります。 この返り値の各要素に対して、その配列の中身を引数としてテストメソッドがコールされます。

例 4.2: データプロバイダの使用

<?php
class DataTest extends PHPUnit_Framework_TestCase
{
public static function provider()
{
return array(
array(0, 0, 0),
array(0, 1, 1),
array(1, 0, 1),
array(1, 1, 3)
);
}

/**
* @dataProvider provider
*/
public function testAdd($a, $b, $c)
{
$this->assertEquals($c, $a + $b);
}
}
?>
phpunit DataTest
PHPUnit 3.2.10 by Sebastian Bergmann.

...F

Time: 0 seconds

There was 1 failure:

1) testAdd(DataTest) with data (1, 1, 3)
Failed asserting that <integer:2> matches expected value <integer:3>.
/home/sb/DataTest.php:21

FAILURES!
Tests: 4, Failures: 1.

例外のテスト

例 4.3 は、テストするコード内で例外がスローされたかどうかを @expectedException アノテーションを使用して調べる方法を示すものです。

例 4.3: @expectedException アノテーションの使用法

<?php
require_once 'PHPUnit/Framework.php';

class ExceptionTest extends PHPUnit_Framework_TestCase
{
/**
* @expectedException InvalidArgumentException
*/
public function testException()
{
}
}
?>
phpunit ExceptionTest
PHPUnit 3.2.10 by Sebastian Bergmann.

F

Time: 0 seconds

There was 1 failure:

1) testException(ExceptionTest)
Expected exception InvalidArgumentException

FAILURES!
Tests: 1, Failures: 1.

一方、setExpectedException() メソッドを使用して、発生するであろう例外を指定することもできます。この方法を 例 4.4 に示します。

例 4.4: テスト対象のコードで発生するであろう例外の指定

<?php
require_once 'PHPUnit/Framework.php';

class ExceptionTest extends PHPUnit_Framework_TestCase
{
public function testException()
{
$this->setExpectedException('InvalidArgumentException');
}
}
?>
phpunit ExceptionTest
PHPUnit 3.2.10 by Sebastian Bergmann.

F

Time: 0 seconds

There was 1 failure:

1) testException(ExceptionTest)
Expected exception InvalidArgumentException

FAILURES!
Tests: 1, Failures: 1.

表 4.1 は、例外をテストするために用意されているメソッドをまとめたものです。

表4.1 例外のテスト用のメソッド

メソッド 意味
void setExpectedException(string $exceptionName) 発生することを期待する例外の名前を $exceptionName に設定します。
String getExpectedException() 発生することを期待する例外の名前を返します。

一方、 例 4.5 のような方法で例外をテストすることもできます。

例 4.5: 例外をテストするための、別の方法

<?php
require_once 'PHPUnit/Framework.php';

class ExceptionTest extends PHPUnit_Framework_TestCase {
public function testException() {
try {
// ... 例外が発生するであろうコード ...
}

catch (InvalidArgumentException $expected) {
return;
}

$this->fail('期待通りの例外が発生しませんでした。');
}
}
?>

例外が発生するはずの 例 4.5 のコードで例外が発生しなかった場合、それに続く fail() (表 21.3 を参照ください) によってテストが終了し、問題を報告します。期待通りに例外が発生すると、 catch ブロックが実行されてテストは正常終了します。

PHP のエラーのテスト

デフォルトでは、PHPUnit はテストの実行中に発生した PHP のエラーや警告そして notice を例外に変換します。これらの例外を用いて、たとえば 例 4.6 のように PHP のエラーが発生することをテストできます。

例 4.6: @expectedException を用いた、PHP エラーが発生することのテスト

<?php
class ExpectedErrorTest extends PHPUnit_Framework_TestCase
{
/**
* @expectedException PHPUnit_Framework_Error
*/
public function testFailingInclude()
{
include 'not_existing_file.php';
}
}
?>
phpunit ExpectedErrorTest
PHPUnit 3.2.21 by Sebastian Bergmann.

.

Time: 0 seconds

OK (1 test)

PHPUnit_Framework_Error_Notice および PHPUnit_Framework_Error_Warning は、 それぞれ PHP の notice と警告に対応します。

Prev Next
1. 自動テスト
2. PHPUnit の目標
3. PHPUnit のインストール
4. PHPUnit 用のテストの書き方
データプロバイダ
例外のテスト
PHP のエラーのテスト
5. コマンドラインのテストランナー
6. Fixtures
tearDown() よりも setUp()
バリエーション
Fixture の共有
7. テストの構成
スイートレベルのセットアップ
8. テストケースの拡張
出力内容のテスト
パフォーマンス低下のテスト
9. データベースのテスト
データセット
Flat XML データセット
XML データセット
操作
データベースのテストのコツ
10. 不完全なテスト・テストの省略
不完全なテスト
テストの省略
11. モックオブジェクト
自己シャント
スタブ
12. テストの進め方
開発中のテスト
デバッグ中のテスト
13. テストファーストプログラミング
銀行口座の例
14. コードカバレッジ解析
カバーするメソッドの指定
コードブロックの無視
ファイルのインクルードや除外
15. テストのその他の使用法
アジャイルな文書作成
複数チームでのテスト
16. ログ出力
XML 形式
コードカバレッジ (XML)
JavaScript Object Notation (JSON)
Test Anything Protocol (TAP)
GraphViz マークアップ
テストデータベース
17. 雛形ジェネレータ
アノテーション
18. PHPUnit と Selenium
Selenium RC
PHPUnit_Extensions_SeleniumTestCase
19. 継続的インテグレーション
CruiseControl
phpUnderControl
Apache Maven
20. PHPUnit の実装
21. PHPUnit API
概要
PHPUnit_Framework_Assert
PHPUnit_Framework_Test
PHPUnit_Framework_TestCase
PHPUnit_Framework_TestSuite
PHPUnit_Framework_TestResult
パッケージの構成
22. PHPUnit の拡張
PHPUnit_Framework_TestCase のサブクラスの作成
アサートクラスの作成
PHPUnit_Extensions_TestDecorator のサブクラスの作成
PHPUnit_Framework_Test の実装
PHPUnit_Framework_TestResult のサブクラスの作成
PHPUnit_Framework_TestListener の実装
新しいテストランナーの作成
A. アサーション
B. XML 設定ファイル
テストスイート
グループ
コードカバレッジ対象のファイルの追加や除外
ログ出力
PMD ルール
PHP INI 項目やグローバル変数の設定
C. PHP 4 用の PHPUnit
D. 目次
E. 参考文献
F. 著作権