単体テストの考え方/使い方を読む(WIP)
単体テストの考え方/使い方を読む(WIP)
読書メモ、思考の整理として書く。
羅率とテストスイートの質との関係
コード網羅率が上がっても品質が上がってるわけじゃない。網羅率自体は簡単に算出結果が変わるものなのでテスト対象自体をコンパクトにすれば網羅率は上がる。その結果コードベースの保守性が高まるわけでもないのでコード網羅率だけを追いかけるのは違うという話。
分岐網羅率。コードの行数ではなく分岐に目を向けたもの。プロダクションコードに含まれている分岐経路がいくつ軽油されるのかを計測することで算出される。
これらの網羅率は以下の理由でテストスイートの品質を評価するのには使えない
-網羅率からは実際にテスト対象のコードが検証されたのかを保証できない
-網羅率を算出する際、使用するライブラリ内のコードは計測の対象から外れる
部分的にしか検証されないテストを極端にしたものが確認不在のテスト。verifyしてないものということらしい。
高い網羅率を維持できることが開発にとって良いことなのは確かだがそのことを強要することは間違いになる。テストスイートの質をよくするための足掛かりと考えるべき。
それはそうなのだが網羅率の位置づけについて、AIコーディングが当たり前の今アップデートは不要なのだろうか。
何がテストスイートの質を良くするのか
-テストすることが開発サイクルのの中に組み込まれている -コードベースの特に重要な部分のみがテスト対象になっている -最小限の保守コストで最大限の価値を生み出すようになっている
価値のあるテストケースを認識、作成できることが大切。
単体テストとは何か
古典学派とロンドン学派が出てくる。
単体テストの定義
- 単体と呼ばれる少量のコードを検証する
- 実行時間が短い
- 隔離された状態で事項される
- 学派によって議論がわかれるところ
- 隔離が意味することは何なのかという視点
ロンドン学派が考える隔離
テスト対象システムから協力者オブジェクトを隔離すること。テスト対象となるクラスがほかのクラスに依存しているのであれば、その依存をすべてエストダブルに置き換えなくてはならない。
テストダブルの利点は失敗したときにどこで問題があったのかを明確にできることと、オブジェクトグラフを分離できるようになること。後者は循環依存に有効。この方針により一つのテストケースは一つのクラススカ検証しないという指針がプロジェクトに普及しやすくなる。
古典学派が考える隔離
単体テストの定義のうち三つめだけじゃなく一つ目も解釈の余地があり、どれだけ小さければ単体といえるのかという点。 単体テストにおいて隔離する必要があるのはコードではなくテストケースで各テストケースをお互いに影響を与えることなく個別に実行できるようにしなくてはならない。ほかのテストケースに影響が出るような依存のことをプロセス外依存と呼ぶ。
テストダブルが使われるのはテストケース間で共有される状態を持つ依存に対してのみ。テスト対象となるクラス間での共有を意味せず、テストケース間で共有される依存のこと。この場合シングルトンパターンを採用しているオブジェクトはエストケースごとに新しいインスタンスを作成していれば共有依存ではない。この場合はプライベート依存と呼べる。
古典学派およびロンドン学派が考える単体テスト
ロンドン学派のテストダブルを使うかの判断は対象の依存が可変かどうかによって下され、不変であれば置き換える必要はない。
ロンドン学派は以下が特徴
- より細かな粒度で検証できる
- 依存関係が複雑になっていても簡単にテストすることができる
- テストが失敗した際どの機能に問題があったのかを正確に見つけられるようになる
この粒度はOOPからきている。単体テストは一単位のコードを検証するのではなく一単位のふるまいをテストするもので、問題領域で意味のあるものを検証する。使用するクラスの数には関連性はない。
無理に分割してふるまいがあいまいになるなら質の低いテストが量産される。関わる人達に対象のコードが解決しようとしている問題が何か理解できる必要がある。伝えるためには凝集度を高める必要がある。
複雑な依存関係を持つ者に対するテスト
協力者オブジェクトをモックに置き換えることはテスト対象となるクラスの検証を簡単にする。複数層の複雑な依存関係を築いているときにテストダブルに置き換えることでテスト可能になるが、そもそもそうしなくても良いようにするための単体テスト。準備フェーズが大きくなるようであれば見直すサイン。
古典学派のスタイルのテストではテスト対象システムの依存に不具合があってもテストがこける。一見バグがどこにあるのか調査の必要があるが、イテレーティブにテストが実行できていたらその直前の変更が不具合の原因であることが多い。そもそも一つの問題が複数のテストケースに影響を与えるのであればその問題のあったコードは多くのクラスに依存される重要な価値があることも表す。
統合テスト
改めて古典学派目線で単体テストの定義。
- 一単位のふるまいを検証すること
- 実行時間が短いこと
- ほかのテストケースから隔離された状態で事項されること
統合テストの定義
- ロンドン学派
- 協力者オブジェクトを使って行うテストをすべて統合テストとみなす
- 古典学派
- 古典学派目線の単体テストの定義以外のテスト