| Prev | Next |
PHPUnit の実装はちょっと見慣れないものでしょう。 通常のアプリケーションでは保守しづらくなるようなテクニックを使用したりしています。 PHPUnit がテストを実行する仕組みを知っておくと、 あなたがテストを書く際に役立つこともあるでしょう。
個々のテストは PHPUnit_Framework_Test のオブジェクトで表され、テストを実行するには PHPUnit_Framework_TestResult のオブジェクトが必要です。PHPUnit_Framework_TestResult オブジェクトが PHPUnit_Framework_Test オブジェクトの run() メソッドに渡され、 このメソッドが実際のテストメソッドを実行します。そこで発生した例外を PHPUnit_Framework_TestResult オブジェクトに報告します。 これは、Smalltalk の世界では Collecting Parameter と呼ばれているお決まりのパターンです。複数のメソッドの結果 (ここでは、各テストを起動する run() メソッドの結果) を一箇所にまとめたい場合は、メソッドにパラメータを追加すればそれが結果を集めてくれるのです。 Erich Gamma と Kent Beck の "JUnit: A Cook's Tour" [GammaBeck1999] や Kent Beck の "Smalltalk Best Practice Patterns" [Beck1997] [Beck1997-ja] を参照ください。
PHPUnit がテストを実行するしくみをより深く探るため、 例 20.1 のようなテストクラスを考えてみましょう。
例 20.1: The EmptyTest class
<?php
require_once 'PHPUnit/Framework.php';
class EmptyTest extends PHPUnit_Framework_TestCase
{
private $emptyArray = array();
public function testSize()
{
$this->assertEquals(0, sizeof($this->emptyArray));
}
public function testIsEmpty()
{
$this->assertTrue(empty($this->emptyArray));
}
}
?>
テストが実行されるときに PHPUnit がまず行うのは、テストクラスを PHPUnit_Framework_Test オブジェクトに変換することです。 ここでは、PHPUnit_Framework_TestSuite には 図 20.1 に見られるように 2 つの EmptyTest インスタンスが含まれます。
PHPUnit_Framework_TestSuite の実行時には、各 EmptyTest が順に実行されます。その中では各自の setUp() メソッドが実行され、各テストについて 図 20.2 に見られるような新しい $emptyArray を作成します。 こうすることで、あるテストが配列を変更したとしても それが他のテストに影響を及ぼさないようになります。 仮にグローバル変数やスーパーグローバル変数 ($GLOBALS など) を変更したとしても、それは他のテストには影響を及ぼしません。
グローバル変数やスーパーグローバル変数の保存と復元には serialize() および unserialize() を使用しています。 PHP 自体が提供する一部のクラス、たとえば PDO などのオブジェクトはシリアライズできないので、 このようなオブジェクトが $GLOBALS 配列に格納されている場合は保存に失敗します。
グローバル変数やスーパーグローバル変数の保存と復元を無効にするには、 このようにします。
class MyTest extends PHPUnit_Framework_TestCase
{
protected $backupGlobals = FALSE;
// ...
}
$backupGlobals 属性をたとえば setUp() メソッドの中で設定したとしても、 なんの効果もないことに注意しましょう。
つまり、テストが実行される際には、ひとつのテストケースクラスが 2 段階のオブジェクトツリーになるということです。各テストは setUp() で作成された自分自身のコピーの上で実行され、テストは完全に独立して実行されます。
PHPUnit は、リフレクションを使用してインスタンス変数 $name からメソッド名を取得し、そのテストメソッドを実行します。これは、Smalltalk の世界では Pluggable Selector と呼ばれているお決まりのパターンです。 Pluggable Selector を使用することでテストをよりシンプルに書くことができますが、 その代わりコードを見ただけではどのメソッドが実行されるのかがわからなくなります。 実行されるメソッドを知るには、実行時のデータの値を調べなければならないのです。
| Prev | Next |
Copyright © 2005-2011 Sebastian Bergmann.