以下のTwitterをみて、自分でもこのへんの言葉ちゃんと説明できないな、と思ったのでちょっと整理しようとしてみました。
さらっと書かれているけれど、特に「単体テスト」「結合テスト」についてはフェーズとレベル、どちらも同じ単語で表現されることが多いので混乱が生じがち。
— しましま(偽) (@shimashima35) October 17, 2019
JSTQBの用語集を見ておくとこの辺りの違いが理解できて良いです。 https://t.co/QGEEetcyzL
こちらのTweetで言及されている、用語集というのは、おそらくこの2つ。
ソフトウェアテスト標準用語集: http://jstqb.jp/dl/JSTQB-glossary.V2.3.J01.pdf
JSTQBシラバス: http://jstqb.jp/dl/JSTQB-SyllabusFoundation_Version2018.J03.pdf
引用もこの2つから行っています。
テストレベルとしての考え方
Twitterで言及されている順序と違いますが、まずはテストレベルから整理してみましょう。
テストレベルとは、以下のように説明されています。
系統的にまとめ、管理していくテストの活動のグループ。各テストレベルはプロジェクトの特定の責務と対応付けができる。テストレベルの例には、コンポーネントテスト、統合テスト、システムテスト、受け入れテストがある。
まさにテストの「レベル」、あえて日本語にするとすれば、段階とかそういう概念なのかな、と思います。
そして引用中にあるように、テストのレベルの中には、単体テスト/結合テストという言葉はありません。
それに対応するのは、用語集を見る限り、コンポーネントテスト、統合テストという言葉になりますね。
ではそれぞれどういう物を指すのでしょうか。
コンポーネントテスト
コンポーネントテスト(component testing): 個々のソフトウェアコンポーネントのテスト。
ふむ。個々のコンポーネントに対するテスト、というのはわかります。しかし、コンポーネントとは具体的にはどのようなものを指すんでしょうね。他の用語からヒントを探ってみましょう。以下はシラバスでのコンポーネントテストの解説になります。
コンポーネントテスト(ユニットテストまたはモジュールテストとも呼ばれる)は、個別にテスト可能なコンポーネントに焦点をあてる。コンポーネントテストの目的は以下の通りである。
- リスクの軽減
- コンポーネントの機能的/非機能的振る舞いが設計および仕様通りであることの検証
- コンポーネント品質に対する信頼の積み上げ
- コンポーネントに存在する欠陥の検出
- 欠陥がより高いテストレベルまで見逃されることの防止
特にコード変更が継続して行われるインクリメンタル開発モデルやイテレーティブ開発モデル(アジャイルなど)では、コンポーネントテストのリグレッションテストを自動化して、変更が既存のコンポーネントを破壊していないという信頼を積み重ねていくことが重要である。
長めに引用しましたが、重要なことは**「個別にテスト可能なコンポーネント」**という言葉。つまり個別にテスト可能なソフトウェアの部分であればそれはコンポーネント足りうる、ということです。
一見言葉遊びみたいになっていますけれど、テストができるということは、つまりそのコンポーネントの振る舞いを定められる、すなわち仕様を定義できる、ということになります。
関数、クラス、モジュールなど様々な単位が考えられますが、仕様を定義可能な範囲がコンポーネントであり、そのコンポーネントに対するテストがコンポーネントテスト、ということですね。
統合テスト
では結合テストとはどのようなテストでしょうか。まずは定義を見てみましょう。
統合テスト(integration testing): 統合したコンポーネントやシステムのインターフェースや相互作用の欠陥を摘出するためのテスト。component integration testing, system integration testing も参照のこと。
コンポーネント統合テスト(component integration testing): 統合したコンポーネント間のインターフェースや相互作用の欠陥を検出するためのテスト。
システム統合テスト(system integration testing): システムやパッケージを統合して行なうテスト。
外部機構とのインターフェース(たとえば、電子データ交換やインターネット)をテストすること。
と、かなり広い概念です。
これはコンポーネントの粒度がテスト対象によってバラバラなのですから、その統合レベルも自然とブレが発生してしまうわけですね。
というわけで、レベルとしてコンポーネントテストと統合テストという段階があるのがわかりましたが、実際の粒度はテスト対象のシステムや組織の体制によって異なる、と言えるのではないでしょうか。
テストフェーズとしての考え方
では、テストフェーズとしては、単体テストや結合テストに対応する概念はあるのでしょうか。定義を見てみましょう。
テストフェーズ(test phase): テスト活動をプロジェクト中で管理(マネジメント)しやすいフェーズにまとめたセット。たとえば、あるテストレベルの実行活動。
この言葉からわかるように、テストフェーズというのはあくまで管理上の視点にすぎません。そして実際には、そのフェーズではどのレベルの実行をどの程度やるのか、ということが重要になります。
結局はテスト設計
このあたりの議論を突き詰めていくと、結局は「どのような単位でテストを管理してフェーズにまとめ、各々のフェーズでどのようなテストレベルの活動をするのか」というテスト設計が重要になってくるわけですね。
最終的に結合するシステム全体の複雑度から逆算して、コミットごとのごく細かいレベルでのテスト、イテレーション毎のある程度大きなテストイベント、最後のQAフェーズと、各段階でどのようなテストを行うのか。
そのように考えると、じつは最終のシステム全体以外は、全てテスト可能なコンポーネントごとにテストしているわけで、ある種のコンポーネントテストですし、直前のテスト段階よりも大きな塊の結合をしているので、ある種の統合テストである、といえます。
テストフェーズという観点でまずテストするチェックポイントをある程度見定めて、各チェックポイントにおいて何をテストするのか。
このあたりを考えないといけない、ということですね。