Rubyベストプラクティスで学ぶ Test::Unitの基礎
例外をテストする
- 例外が発生することをテスト
assert_raises(KeyError) do hash.fetch(:doesnt_exists) end
- 例外が発生しないことをテスト
assert_nothing_raised do hash.fetch(:key_exists) end
メソッドが意図的にエラーを発生させる時は、エラーを発生させる場合とさせない場合の両方をテストすること。
こうすると、無条件にエラーが発生する訳ではないこと、条件が合えばエラーが発生すること、の両方をテストできる。
高度なテストテクニック
モックとスタブを使う
- IOを伴うような、ユーザーインターフェース部分と、ロジックを出来る限る分離する
- ロジックが分離できれば、その部分のテストは簡単になる
ユーザー入力への応答をテストしたければ、スタブを使う
class Questioner def method_want_to_test ask("Are you happy?") ? "Good I'm Glad" : "That's Too Bad" end def ask(question) # ユーザーからの入力を受け取るなど何か処理をする ... response = simple_logic ... # ロジックで判定した結果を元になにか答えを返す ... end def simple_logic # 何かシンプルなロジックで答えを返す end end
user_interactionを含む ask
メソッドの戻り値をテストしたい場合
特異メソッドを使ってaskの戻り値をスタブする
テストケース
def setup @questioner = Questioner.new end def test_yes_response do def @questioner.ask(question); true; end assert_equal "Good I'm glad", @questioner.method_want_to_test end
テストケース内で@questionerインスタンスに特異メソッドを定義している。
元々あるaskをこのインスタンスだけに対して上書きし、必ずtrueを返すようにしている。
その結果テストしたかった"yes"が返って来た場合のレスポンスを簡単にテストできている。
対象のインスタンスのみ、メソッドを上書きしている。 特異メソッド・・すご〜い。。
こんなことして良いんだ。。自由だな〜Ruby
複雑な出力をテストする時
XML等、複雑な出力をテストしたい時、パーサーの利用を検討する。
nokogiriなど、有名なパーサーを用いて、出力結果をパースする。
テスト対象にするのはパーサーの出力。
出力をパースする道具を信用する必要があるが、信頼できるライブラリであれば、出力が単なる文字の固まりではなく、何か意味のある結果を作り出していることの現れである。
Rubyベストプラクティス 1章 テストでコードを駆動する まとめ より
テストに慣れる最善の方法は、まずテストを書き始めるだけだ。それ以外のことは、自然と後からついてくるだろう。
正直、後半の高度なテストに関するところは、自分で繰り出せるほど会得出来たわけじゃないけど、まとめ、の言葉に従ってやり続けていくしかない。