PHPな開発ではお馴染み SimpleTest を使ってUnitTestをしています。
自作ライブラリやフレームワークは規模が大きくなればなる程、テストはもちろんのことテストケースも相当な数になってきます。テストケースを格納するディレクトリ内にサブディレクトリが出来て更にまた階層構造を持つってな具合になると、テストを走らせるスクリプトもグチャグチャに。
なので、ディレクトリを再帰的に走査して見付けたテストケースを全部登録してイッキにテストする自作クラスを使っています。コマンドラインからもブラウザからもどっちから叩いてもokにする為、少し変な事をしていますが。
[code language=”php”]
< ?php
define('SIMPLETEST_DIR', '/path/to/simpletest');
require_once(SIMPLETEST_DIR.'/unit_tester.php');
require_once(SIMPLETEST_DIR.'/reporter.php');
/**
* 再帰的にテストケースを登録して全部実行するテストランナー
*
* newする時にコンソール引数($argv)を渡す。
* コンソールからかブラウザからかを判定して
* 指定されたディレクトリ以下のテストを全て一度に実行する支援クラス
*/
class SimpleTestRunner
{
private $reporter;
private $console;
private $group;
/**
* コンストラクタ
*
* @param string $argv コンソールから使うスクリプトの場合は引数群をそのまま渡す(省略可)
* @return void
* @author Yuichi Oishi
**/
function SimpleTestRunner($argv = null) {
// コンソールからかどうかを判定
$this->console = !isset($_SERVER[’HTTP_HOST’]);
// console からの実行かどうか調べてディレクトリとレポーターを指定する
if($this->console){
$testdir = isset($argv[1]) ? $argv[1] : ‘.’;
$this->reporter = ‘TextReporter’;
}
else{
$testdir = !is_null($_REQUEST[’dir’]) ? $_REQUEST[’dir’] : ‘.’;
$this->reporter = ‘HtmlReporter’;
}
$this->group = new GroupTest(’All of tests’);
//
$this->load($testdir);
}
/**
* ディレクトリ内のファイルを一覧してテストケースとして追加して行く再帰関数
*
* @param string $directory 対象とするディレクトリの絶対パス(相対パスではない)
* @return void
* @author Yuichi Oishi
**/
private function load($directory) {
// 指定されたディレクトリ配下を走査
$dh = opendir($directory);
while($filename = readdir($dh)){
// 隠しファイルは無視
if(preg_match(’|^\.+?|’, $filename)){continue;}
// ディレクトリであれば再帰的にファイルを辿る
if(is_dir($filename)){
$this->load($directory.’/’.$filename);
}
// Testで始まらないファイル名は無視
if(!preg_match(’|^Test.+$|’, $filename)){continue;}
// class名
$testcase = str_replace(’.php’, ”, $filename);
// テストケースのファイルを読み込む
require_once($directory.”/{$filename}”);
// テストケースを登録して
$this->group->addTestCase(new $testcase);
// ログ出力
echo “added test case : {$testcase}”.($this->console ? PHP_EOL : ‘
‘);
}
closedir($dh);
}
/**
* テストを実行する
*
* @return void
* @author Yuichi Oishi
**/
public function run() {
$this->group->run(new $this->reporter);
}
}
?>
[/code]
こんな感じのテスト実行用スクリプト(runner.php)を書いて
[code language=”php”]
< ?php
require_once("SimpleTestRunner.php");
$runner = new SimpleTestRunner($argv);
$runner->run();
?>
[/code]
coreディレクトリ以下をテストする場合は
$ php ./runner.php core
ブラウザからだったら http://path/to/test/runner.php?dir=core って感じで。パラメタ付けなければ runner.php のあるディレクトリ以下のサブディレクトリを全て走査します。
テストは重要ですね。今更感ありますけど。でも、思いのほかUnitTestなるものを知らない方に出会う事が時々ありビックリしてる今日この頃です。