11.5 テストは仕様だ
内容
11.2-4までの中で、3つのアサーションを定義した。
- 1から200までの値が必要で、MINIMUM_AGE – 1もしくは0を渡した場合は例外がスローされる
- 有効値はMINIMUM_AGE以上MAXIMUM_AGE以下である。この場合は、エラーなしで戻り値を返す
- MAXIMUM_AGE + 1もしくは201を渡した場合は例外がスローされる
これらの3つはすべて独立しており、同じ理由では失敗しない。
そしてすべてが通らないとOKにならない。
このテストコードは独立した3つの要件そのものである。
通常の要求のドキュメントが最新かどうかは担保するのがむずかしいが、テストは実行すればOKかNGがわかるため、OKが出れば最新だし、NGが出るのであれば最新ではない。
11.6 完全であれ
ふるまいを書くときは常にテストを先に書く。
そうすることで、完全で漏れのないテストスイートが出来上がる。
そうすれば最終的には品質が劇的に向上する。
テスト駆動開発をすればテスト容易性とコード品質が上がるが、テスト用意性が高いからといってQAも同時にやればいいというわけではない。
テスト駆動開発と同時にQAをやろうとすると、たぶん、QAのためにとても多くのテストを書く羽目になる。最悪、コードがぐちゃぐちゃになり、あとから直しにくくなる。
QAの役割は、開発の段階で考えていないようなケースについても確実にカバーできるようにすることだから、開発者はまずふるまいを作ることに集中しよう。
そしてQAで発生したものは必要に応じてあとからクリーンアップする。
その方が遥かに効率が良い。
マネジメント側がQAをテスト駆動開発を含めるように言い出した場合、QA(システムが停止する可能性のある箇所の調査、非機能要件の検討、その他)は、テスト駆動開発には含めずに、後でやり、必要に応じて修正するほうが、コードが良い保守性になりやすいと言ったほうが良い。
11.7 テストを一意にする
テストファースト開発は設計方法論であり、テストが一意になる設計をしながら進めるためのものだ。
良いテストの基準は
- テストが未知の理由ではなく既知の理由で失敗すること
- テストは一意であること
であるが、テストに重複を許すと、何かの失敗で複数の失敗が起き、以下の理由で著しくスピードが下がる。
- すべての失敗が本当に同じ原因で落ちているかどうかを調べなければいけなくなる
- リファクタリング箇所が多くなる
11.8 コードをテストでカバーする
コードカバレッジ(テスト網羅率)は100%以外は意味がどんどん薄れる。
テストを仕様として書き、テストが難しい仕様はテストができるように設計を工夫する必要がある。
難易度が高い、且つテストできなくない状態を続けることは、コード品質が低いことを意味し、後の負債となる。
11.9 バグにはテストがない
すべてのバグはテストがないゆえに存在する。
テスト駆動開発を用いてバグを修正するには、まずバグを再現させるような失敗するテストを書く。次に、テストがグリーンに変わるように、バグを修正する。
そのため、すべての仕様に対して理論上はテストがあるようになる。
学び
- テストコードはプログラムの正しさを検証するとともに、仕様ドキュメントである必要がある。
- テストコードは運用していかないと効果を発揮しない。
- ドキュメントをテストコードによって表現するスキルが必要だ。
- QAとテスト駆動開発は同時にやるとコードの保守性が悪くなる可能性が高い。
- テスト駆動開発では機能要件にフォーカスし、非機能要件にはフォーカスしないほうが効率が良い。
- テストは一意となるようにしなければ、開発効率がかなり落ちる。
- テストを一意にするということはふるまいを一意にするということ
- コードカバレッジは100%を基準とするべし。信憑性がなくなる。
- テストがしづらい仕様が設計のしどころ
- バグはテストしなかったから顕在化した
- テスト出来ない箇所は設計の問題がある可能性があるから見直す必要がある
学びを活かすアイディア・行動
- 現場のユニットテストのコーディング規約づくり
- テストコードの目的のための事前知識整理
- エッジケースを含めたふるまいがテストに網羅されているかチェックする必要がある
- 業務要件のフローとスマホ独自の中断操作をかけ合わせたケースで考える必要もある