モダンなテストレベル設計(ユニットテスト~システムテスト等をどう設計するか)の原則
現代のテストについて網羅的に解説されており、とても丁寧で良い記事だったkoushisa.icon プロジェクト全体のテストを組み立てる際に重要な課題になるのが、テストレベル設計です。テストレベル設計は、ユニットテスト、結合テスト、システムテストといったテストレベルを、どのような責務・段取りで行うか分析・設計する活動です。
このテストレベル設計ですが、ここ10年程度の間に望ましいアプローチが変わってきたと感じています。今回はこの変化と、変化後のモダンなテストレベル設計の原則について、考えていることを記述したいと思います。
いくつか引用
---
旧来のテストレベル設計のアプローチ
旧来、このテストレベル設計では、Vモデルをベースしたアプローチや、自工程完結・品質積み上げをベースとしたアプローチがよく見られました。
一つ目のVモデルをベースとしたアプローチは、要求定義から設計までの上流工程への対応を観点に、テストレベルを設計するものです。 二つ目の自工程完結・品質積み上げをベースとしたアプローチは、「自分たちチームの成果物の品質は自分たちが責任をもって確保・保証する」「構成要素ごとに品質を確保・保証する」という考え方でテストレベルを設計するものです。 ~
チームが実装工程を担当するならば、ユニットテスト工程を確保し、実装仕様の実現性保証や、実装に起因するバグの取りきりをチーム内で行います。
---
開発技術やプロセスの発展とテストレベル設計
上記のアプローチは現在でも陳腐化したわけではありません。ただ開発技術やプロセスの発展で、より柔軟なアプローチを加えることが可能になっていると感じています。
その発展の一つが、自動テスト手段の充実です。
~
結果、Vモデルや自工程完結のアプローチだけでテストレベルを設計するだけでなく、費用対効果の高いテストレベルの責務を増やし、費用対効果の低いテストレベルの責務を減らす設計アプローチが、開発の生産性を高めるのに有効になりました。
~
この開発プロセスにとっては、旧来の大規模な手動テストは、遅すぎ・コストがかかりすぎで、リードタイムを大きく悪化させ、プロダクトの価値を棄損します。
そこで、リードタイムの短いテストレベルでなるべくテストを済ませ、遅いテストレベルはできるだけ排除するアプローチが採用されやすくなりました。
最後の発展は、CI/CDによるデプロイメントパイプラインの充実です。
~
これにより、テストレベルの本来の能力に基づいて、テストの責務を移動させるアプローチを柔軟に取れるようになりました。
---
モダンなテストレベル設計の原則
もっとも効果的なテストレベルの責務を最大化する
それぞれのテストレベルの強みを最大化し、弱みを最小化・補完する
テストレベル間のテストの重複は、全体が良くなる方向で削除する
~
このようなデメリットを加味して、注力するテストレベルを選択すべきといえます。テストピラミッドでなく、APIテスト等結合テストを主体としたテストトロフィーを志向したほうが良い開発も少なくありません。 ---
テストレベル間でのテストの責務の移動を支える基礎
契約による設計(またはそれと同等の責務設計)を推進する
システムテストの責務を結合テストに移動させる場合に重要になるのが、システムの機能や処理を、コンポーネントのどこが責務として担っているのか明確にすることです。 例えば以下の事例を考えます。
~
しかし入力バリデーションの責務が曖昧だったり、レイヤ横断的に実装されている場合は、システムテストから結合テストへの移動は、リスクができず実施できなくなります。
ですので、 契約による設計、またはそれと同等のアーキテクチャレベルの責務設計は、テスト責務を柔軟に移動させるアプローチにとって不可欠になります。
ここはボトムアップな設計手法を取ろうとすると難しい
関連
テストを意識した方法論はTDD, BDDなどの文化がチームに浸透している必要性があると感じる デプロイメントパイプラインの信頼性を挙げる
CI/CDのデプロイメントパイプラインの信頼性を挙げて、安全にテストレベル間でテストの責務を移動できるようにするのも重要です。
例えば各テストレベルで、各テストレベルのテスト条件(例えば対象のブランチ、バージョン、インテグレーション状態)を一致させるようにパイプラインを組むのは有効です。またテストレベルを移行する間のバグ混入を最小化するのも有効です。
例えば「コンポーネント間の結合部の並行処理のリスクを下げることで、システムを結合しないと再現できないバグを減らす」「コンポーネントの凝集度を上げ責務を明確化することで、多数のコンポーネントを横断させないとテストできない機能を減らす」といった設計の工夫の積み重ねが、テスト責務の移動を安全にします。 koushisa.iconの感想
語彙が増えたkoushisa.icon*2
---
以下はTLからの引用
モダンな開発スタイルの課題の本質はテストレベル設計にあるのかも。 @miwa719: どういう仕組みでシステムが動いているのか知らないとテストなんかできないんだぜ? というメッセージを受け取りました。わたしもそう思ってるからそう読んでしまうのかもしれないけど、テスターは設計や実装を知らなくてもいい(むしろ知るとよくない)みたいな考え方はこの記事によって滅びてくれ!! 仕方なく独自対応
とても分からりやすく書かれてますし重要なご指摘だと思います。
@hide_ramen_san: たぶん似たような問題意識はあるなかで、goyokiさんは現状を丁寧に分析して原則を説明してくれてますが、私のツイートはかなり雑に技術の進歩によってこっちの方向に進めるべきじゃないかと提案する感じですね。 @hide_ramen_san: なるほどとは思うんですが、入力バリデーションをシステムテストから結合テストに移行するメリットはあまりよくわからない。 ハッピーパスはシステムテストでやってバリデーションチェックを結合テストでやると二重管理になるデメリットもあるし、実行頻度もハッピーパスの方が多くなるべきはず。