第十一章 きちんとコードが動くことをテストする
担当: honeniq honeniq.icon
11.1 なぜそんなにもRubyではテストが大事なのか
他の言語とは違って、Ruby ではオブジェクトの型はそれほ ど重視されません。大事なのはオブジェクトがどんなメソッドに応答できるかです。 この柔軟性こそが Ruby プログラミングの醍醐味です。
せやなと思いつつ、「型はそれほど重視しない」とまで言っちゃうのは中々力強い。
11.2 さまざまなテスト手法
1つは「開発 後テスト(TAD:Test After Development)」です。
(略)
他の自動テスト手法の支持者からは見下されがち ですが、おおむねうまくいくテスト手法です。
いいこと言うなあ。
3種類の自動テスト手法を載せて、どれかに偏るわけでもなくフラットに評価していて良い本だと思った。
むしろ、よそで下げられてる分、TADの評価が高く感じる。
TDD と BDD では、複雑 すぎたり、テストや仕様にバグがあったり、入力が足りなくて正しい答えを得るのが 不可能だったりすると、実装不能なテストになることがあります。TAD では、テスト が書かれるのはライブラリが開発されてからです。大抵のプログラマーはライブラリ を開発しながら基本的なテストを手動で実施しているので、必要のないテストは省略 されることになります。
トレードオフの一例。
TDD で開発すると、「システムをテストする」という目的にとっては適したイ ンターフェイスになるかもしれませんが、通常のユーザーの行動には沿っていないイ ンターフェイスになるおそれがあります。
TDDの本には「先にテストを書くことで、テストしやすい綺麗なコードが書ける」的なことが書かれているけど、
ライブラリから取り除かれた複雑性 がユーザーに押し付けられたわけです。
気をつけないとこういうことも起こり得る。
TAD のもうひとつの利点は、ライブラリの実装はすでに完了しているので、最もエ ラーが発生しやすい複雑な実装箇所が判明していることです。
当たり前だけど確かにその通り。
11.3 テストをどこまで複雑にするか
事前準備のためのコードが どれも同じか、少なくとも互いによく似ているのであれば、テストにおける事前準備 のコードとして抽象化することに問題はないでしょう。しかし、事前準備ではなく実 際にテストとして実行するテストケースの部分を抽象化するのは避けましょう。
抽象化が楽しくなってきて必要以上にやっちゃわないように。
11.4 さまざまなレベルでのテスト
ユニットテストは「テスト対象メソッドが依存するあらゆるオブジェクトをモックやスタブに置き換える」ように設計される
こう定義されてみると、正しいユニットテストを書くのってめっちゃ大変じゃない?
多くの場合、「他のオブジェクトにどんなメッセージを送信して いるか」はメソッドの実装の詳細です。これはあまりテストする価値がありません。
メソッドが外部に依存している箇所のすべてをモックやスタブで置き換え るのをやめることで回避できます。置き換えるのは、「そうしないとかえって厄介な ことになるもの」に限定しましょう。その場合、テストは純粋なユニットテストでは なく、ユニットテストとモデルテストのハイブリッドなテストになります。
自分がいつも書いているのはこれだと思う。
11.5 カバレッジ 100% に意味はない
100%のカバレッジは何も伝えませんが、100%未満のカバレッジは何かを伝えています。少なくとも、コードカバレッジが100%未満という情報からは、コードのなかに未テストの部分があることがわかります。
カバレッジのためのテストコードにはあまり価値を感じられな いかもしれません。しかし、テストされていないコードを調べていくプロセスには非 常に価値があります。
なんか分かったような分からなかったような。
大事なことに気づいた気がしてメモしたけど、うまく伝えられない。