なにを言ってるの?と思うかもしれないけど、この記事を読み終わるときには余裕で他人に語れる程度には説明しておくので安心されたし!!
というわけで早速行ってみよう。
君がプログラマだとするとよくあるパターンだろうけど、実行中のプログラムの変数の値を画面に表示させてみたりすることがあると思う。
JavaScriptならalert()を使ってみたり、PHPならvar_dump()、もしくはprint_r()だ。
頭のなかでは$fooは(int)100、$barが(string)"hogefuga"のはずなので、それを画面にプリントアウトして目で確認しようという感じだ。俺もよくやってた。むしろ今でもやってたりする。
その他にも、月末処理なんていう曖昧なメソッドを試したいんだけど、うるう年が考慮されてなかったり、されてても正しく動くのかどうか自信がないときなんか、いろいろなパラメータを与えてみて動きを確認したりすると思う。
とあるECショップで2週間に一度、烏龍茶のダンボールが届くとしよう。課金はクレジットカード。そして引き落としが、毎月購入した日と同じ日付なんて場合が過去にあった。
さて、1月30日に初回購入したら、次回は2月30日になるだろう。しかし2月は28日で終わりだ。だから2月30日なんて日付は存在しないので、2つのパターンが考えられる。
- 必ず翌月内に丸める(2月末、つまり28日にする)
- 月をまたぐ(3月2日にする)
- 常に初回購入日を意識し、都度日付を変更する
- 最後に変更された日付を維持する
前者は、例えば1月30日に購入したけど2月30日が無いので2月28日になるが、3月には30日が存在するので3月からは通常通り3月30日として引き落とされる、という意味。
後者は、1月30日の次が2月28日になり、3月も28日になり、4月も28日になるというパターンだ。
さらに、うるう年も考慮しないといけない。
さて、これらのパターンをいくつ試してみれば納得するだろうか。ちょっと途方に暮れてしまうよね。
テストケースにして条件を増やせるようにしよう
PHPUnitでテストケースを作っておけば、条件が増えた時も実装が楽だ。基本的に
- 期待する値(expected)
- 実際の値(actual)
を使い、それらを比べるのが基本的な使い方になる。
そして比較するメソッドがassertEquals()やassertTrue()、assertThat()などだ。
何らかの処理により、$actualに数値が入ってるとする。
$expected = 100; $this->assertEquals($actual, $expected);この場合、$actualが100であれば、assertEqualsは真、つまりtrueを返し、テストは成功となる。もし予測に反して$actualが50や0だったりすれば、100ではないのでテストは失敗となる。
つまり、alert()、var_dump()をつかった、ただ画面に値を表示するだけのオレオレテストとは違い、こうなってないとヤバイぜ!というところまでやってくれるわけだ。
ここでいう『こうなってないと』といのは仕様のことだ。仕様書があれば、そのとおりに値を入れてみればいいだろうね。まぁあくまで仕様書があればの話だけど。
で、上記スクリプトの断片をしっかりクラスに書いて実行するというのがPHPUnitのテストだ。
一度書いておけばいつでも実行できるし、テスト内容も増やせたりできる。関連するモジュールのテストはまとめておけるので便利だ。
PHPUnitの説明を更に詳しくするのは、Yiiの説明から大きくはみ出すと思うので、PHPUnitはここらへんを見て調べておくと良いと思う。
第1回 PHPUnit3で始めるユニットテスト
PHPUnit3.7(old, but stable)
何らかの処理を書くのが面倒
上記で『何らかの処理により』と書いたけど、おそらくこれはデータベースへクエリを発行してセレクトした結果だったり、または別のクラスの処理を行った結果だったり、いろいろな処理が想定される。$actualを作るためにわざわざそういった大げさなことをするとテストにかける時間が増え、本末転倒になってしまう。
そこで、予め『こうするとこうなる』関数をその場で即席で作ってしまえれば便利だと思う。
そしてそういう即席(実際には存在しないけどあたかも存在するかのような)関数を作れるのが、モックという仕組みだ。
PHPUnitにもモックを作るプラグインがあるけど、モック専用のライブラリがあるのでそれを使おうじゃないかと。
それがMockeryだ。読み方は『もっくりー』だったり『もっけりー』だったりするけど、『もっこりー』ではないと思うので、男性自身をアピールしないように心がけよう。
詳しくは次回。
facebook
twitter
google+
fb share