PHPUnit とかで assertTrue とか面倒だから at とかにするライフハック
いや,多分ハックしてるのはライフじゃないとおもうんですけど,まーライフハックしつつハックするってかんじで.
まーテスティングフレームワークっていろいろあるとおもうんですけど,PHPUnitがなんかカッコイイから使ってみている最近です.
で,やっぱり色々面倒なのは, assertTrue とかですよね?
最小のテストコードって以下のようになってると思うんですよ.(マニュアルから抜粋)
<?php require_once 'PHPUnit/Framework.php'; class StackTest extends PHPUnit_Framework_TestCase { public function testPushAndPop() { $stack = array(); $this->assertEquals(0, count($stack)); array_push($stack, 'foo'); $this->assertEquals('foo', $stack[count($stack)-1]); $this->assertEquals(1, count($stack)); $this->assertEquals('foo', array_pop($stack)); $this->assertEquals(0, count($stack)); } }
$this->assertEquels とか省略したい
で,この assertEquals とかいちいち打ってられないから,とりあえず ae とかにエイリアスを作りたいと思います.
<?php require_once 'PHPUnit/Framework.php'; class TestBase extends PHPUnit_Framework_TestCase { protected $aliases = array( 'at' => 'assertTrue', 'af' => 'assertFalse', 'ae' => 'assertEquals', // ... ); public function __call($name, $args) { if (array_key_exists($name, $this->aliases)) { call_user_func_array(array($this, $this->aliases[$name]), $args); } } }
こんなものを用意してあげて,これを継承してテストケースをつくれば,以下のようにできますね.alias を 連想配列で定義してあげるのは手動ですけど ... まあ一度書いてしまえばらくちんですね.
<?php class StackTest extends TestBase { public function testPushAndPop() { $stack = array(); $this->ae(0, count($stack)); array_push($stack, 'foo'); $this->ae('foo', $stack[count($stack)-1]); $this->ae(1, count($stack)); $this->ae('foo', array_pop($stack)); $this->ae(0, count($stack)); } }
うん,少しマシになりました.
もっと省略したい
でもこれも使ってると, $this->ae とかが鬱陶しくなってきます.$this-> とかいらないですよねえ.
というわけで,さらに以下のように,関数を定義します.debug_backtrace でオブジェクトをとれるのが素敵ですね.
<?php function ae ($v1, $v2) { $bt = debug_backtrace(); $bt[1]['object']->assertEquals($v1, $v2); } function at ($v) { $bt = debug_backtrace(); $bt[1]['object']->assertTrue($v); } function af ($v) { $bt = debug_backtrace(); $bt[1]['object']->assertFalse($v); }
うおおおこれをassert関数分用意するのはめんどくさいいいメタプログラミングしたいところですね!!!
と思ったけどまーこれも一度書いてしまえばいい話なので,ヨシとしましょう.
これによって,テストケースでは,以下のようにかけるようになりました.
<?php class StackTest extends TestBase { public function testPushAndPop() { $stack = array(); ae(0, count($stack)); array_push($stack, 'foo'); ae('foo', $stack[count($stack)-1]); ae(1, count($stack)); ae('foo', array_pop($stack)); ae(0, count($stack)); } }
うん,これならいっぱいテスト書きたくなりますね.