テストレベルってなんなの?
はじめに
本記事は以下の記事からインスパイアされ作成されています。
また、ソフトウェアテストAdvent Calendar 2024の参加記事でもあります。
こちらに記載する記事は筆者が考える「オレオレ定義」であり、「正しい定義」を知りたい場合は各規約を参照してください。
それでもzennで書く意味は、読者の方がこの記事を読むことによって「テストレベル」に対する理解や思考が深まることを期待するからです。
この記事を元に、「自分はどうだろう」と考えたり、議論していただければ嬉しいです。
テストレベルとは
テストレベルの定義
「テストレベル」の定義はISTQBでは以下となっています。
テストレベル(test level)
具体的にインスタンス化したテストプロセス。
同義語
テストステージ(test stage)
https://glossary.istqb.org/ja_JP/term/testlevel2*1
2018年にテストレベルを学んだ筆者としては、上記の定義は一昔前と異なっているように思えました。
また、なかなか直感的に理解できる内容ではないかなと思います。
そこで、私が使うテストレベルの定義を以下で示してみます。
「テスト対象を何らかの関心ごとでまとめて管理・実行されるテスト活動の集まり」
私はテストプロセスがインスタンス化されることよりも、「テスト対象がなにか」というところに重点を置きたいと考えています。
なので、ここでは上記のように定義しています。
おまけ:ISTQBの定義の解説
本記事の主要な目的ではないですが、せっかくなのでISTQBの定義についても軽く解説しておこうとおもいます。あくまでやましたの理解です。
「インスタンス化した」とは難しい表現ですが、「実際に利用するもの」くらいに捉えるといいです。
そう捉えると、"具体的に実際に利用するテストプロセス"と読み替えることが可能です。
ここでいう「テストプロセス」とは、テストにおけるプロセスです。
ISTQBでは、標準のテストプロセスとして、テスト計画〜テスト終了作業の一連の流れを定義しており、それらがテストプロセスです。
それらはあくまで「標準のテストプロセス」であり、言い換えれば「テストプロセスモデル」というクラスと言えると思います。
それを実際に利用する際に、特定のテストレベルのテストプロセスとして、テスト計画〜テスト終了作業を行う(一部省略することもある)がこの用語における「インスタンス化」だと捉えています。
なので、特定のソフトウェア開発の中で単体テストレベルのテストプロセスが存在して、同時にシステムテストプロセスが存在するという世界観になります。
「具体的にインスタンス化する」というのはすごく29119みを感じました。
テストレベルの識別
テストレベルの定義をするまえに、私がテストプロセスを聞き取りする時に用いる図を紹介します。
典型的なテストレベルの名前として、「単体テスト」「システムテスト」が用いられます。
しかし、会社によって独自の名前をつけられることが多々あり、先入観を与えないため、上記の図では敢えて書かないようにしています。
私は個別のテストレベルについて定義しません。
なので、新しい開発プロジェクトに出会うたびに「テストレベルの識別」という活動が必要になります。
テストレベルの識別をするモチベーションはこの後に記載するとして、ここからは私がテストレベルを識別する観点をいくつか紹介します。
- テスト対象の結合度
- 開発環境の種類(代表性、忠実性)
- テストベースの詳細度
- 品質ゲート
- 提供側と受け入れ側
これらは「こう分けるといいよ」ではありません。
私の経験則から「こんなのを元に識別してる現場があるよ〜」くらいに思ってほしいです。
テストレベルを識別する観点
テスト対象の結合度
もっとも一般的かつ、効果的だと考えるのが「テスト対象の結合度」です。
ソフトウェアは一般的に、システム=>サブシステム=>プロスグラム=>モジュールという風に構造的に詳細化されています。
上記の用語はコンピュータシステムの基礎第18版参照しました。
組織によってはプログラムがサービスだったりモジュールがクラスやメソッド、コンポーネントという名前だったりします。
テスト対象の結合度の観点で識別した場合、テストレベルは以下のようになります。
- モジュール単位でテストを行う、たとえばユニットテスト
- サブシステムまで結合した状態でプログラム間のやりとりをテストする、たとえばコンポーネント統合テスト
- システムまで結合した状態で行う、たとえばシステムテスト
- システムが依存する外部サービスまで使った状態で行う、たとえばシステム統合テスト
結合度を分けることには意味があります。
それぞれの結合度で実施することで、たとえば以下の効果を期待します。
- テストのスコープを狭める
- テスト実行のスピードを調整する
- デバッグをしやすくする
- それぞれの結合度での信頼の積み上げ
- 他チームに渡すために自信をつける
他にもあるかもしれません。
これはシーケンシャルでもアジャイルでも成り立つテストレベルの識別方法だと思っています。
「テスト対象の結合度」と名付けていますが、正式な名前を私はよくわかっていません。
テスト環境の種類、忠実性
意外と語られていないですが、「テスト環境の種類」という観点でも識別できます。
「テスト環境の忠実性」というらしいです。「テスト環境の代表性」って言ったりもすることもあります。
端的に言えば、「テスト環境がどれだけ本番環境に近いか」ということを表しています。
開発者が実施するローカル環境がもっとも本番環境から遠く、本番環境と同等の動作環境であれば、本番環境に近い、つまり「テスト環境の代表性が高い」という意味になります。
テスト環境の種類、代表性によってテストレベルを識別することで、以下の効果を期待します。
- テスト環境を必要最低限にして、テスト環境を用意する費用を抑える
- テスト環境に依存するテストを識別して計画する
- 特定のテスト環境依存のバグを検出する
もっと他にあるかもしれません。
私がここでテスト環境の種類を識別するのは、主にハードが関わる組み込み系を想定していました。
組み込みだとハードの用意に時間もコストもかかるので、「ハードが必要なテストはハードのある環境で集中してやる」のような考えは一定のコストメリットがあると考えます。
また、Web系であってもインフラの設定の有無により確認するテストを識別する場合もありますが、IaCの世界観では結合度に丸め込まれている感はあります。
テストベースの詳細度
テストベースの詳細度は主にシーケンシャルな開発を想定しています。
いわゆるW字モデルを想定するといいかもしれません。
それぞれのテストベースに記載された内容が対応しているかどうかを確認します。
これらはそれぞれテストレベルとして識別されます。
それぞれの成果物が段階的詳細化されることが前提となっています。
「要件定義ベースのテストは要件定義ベースのテストで見たらいいし、単体テストは単体テストの設計書に書いてある内容をテストすればいいよね」という世界観です。
一方、私が観測している範囲では、テストベースとテストレベルが1対1で対応することはあんまりありません。
「1つのテストレベルでテスト条件は要件定義書から拾って期待結果は基本設計書から拾います」という現場はざらにあります。
そのため記事の冒頭で示したテストレベルの図では、さまざまなテストベースがさまざまなテストレベルに飛ぶカオスな図になっています。
テストベースの詳細度によってテストレベルを識別することによって、以下の効果を期待します。
- テストベースに対するトレーサビリティを確保する
- 「何がテストベースか」という観点でスコープを狭める
- 設計書に対する検証を実施する(ベンダー委託の場合によくある)
他にもあるかもしれません。
品質ゲート
品質ゲートの場合もシーケンシャルな開発を想定しています。
「下位のテストレベルが完了基準を満たし、品質への信頼性が高まっていることを確認してから次のテストレベルに移行する」という運用です。
「品質保証部」とかのIV&V的な観点がある場合も私はここに入れています。
以下の効果を期待しています。
- IV&Vができる
- 下位のテストが完了することで、そのテストレベルのスコープに集中することができる
- 「システムテストレベルで単体テストレベルのバグが出てるよ!」というコミュニケーションができる
提供側と受け入れ側
提供側と受け入れ側という観点は「受け入れテスト」の存在意義を説明するために記載しています。
受発注関係のある現場を想定しています。
以下の効果を期待しています。
- 提供側がきちんと仕事をしているかを評価するタイミングを作る
- 契約通りに作られているかどうかを検査する
テストレベルを識別するモチベーション
「テストレベル」という言葉があり、基本情報やJSTQB FLレベルでも普通に使われていることを私は知っています。
ただ、人によってそれらの理解はまちまちです。
その結果、不毛なテストの責務の押し付け合いや、「僕お勉強したから知ってるもん」と意固地になる人を私は何度も見ています。
私はその人々と同じ土俵で戦いたくないと思いました。
なので、「テストレベル」という概念を取り入れつつ、具体的な個別のテストレベルについては柔軟に定義していこうというアイデアを持ったのでした。
個別の嬉しさは個別の識別観点で見ることができます。
また、「なんでテストレベルを使わないといけないの」という意見があります。
それについては、私は以下の効果を期待しているからです。
- テストスコープを定義することで無限のテストを防ぐ
- より早い段階で、より早いテストを実現することができる
- 専門のテスターがやるよりも、開発者自身が実施した方が効率的なテストがあることを知ってほしい
その他の分け方に対する所感
これらの他にもさまざまなテストレベルらしき分け方があります。
それらについては私は「テストレベル」とはちょっと違うんじゃないかという見解を持っています。
この分け方が変という話ではなく、別軸で分けて考えてもいいという意味です。
テストダブルを使うかどうか
結合度や環境に近いところがありますが、テストダブルやモックを使うかどうかでもテストレベルの判定が行われる場合があります。
とくにコードベースのテストではありがちで、いわゆるQAエンジニアが行うテストというよりかは開発者が行うテストのレベルを判別するために使います。
品質保証の観点から言えば、ソフトウェアやテスト環境の代表性とそんなに変わらないと思います。
一方、テストコードを実装する際の技術的側面や、モックフレームワークを議論する際によく使われます。
ただ、テストレベルを割り当て後にそのテストレベル内で許容できるテストダブルがあると思うので、テストの技術的側面として分けたほうがマネジメントしやすいんじゃないかなと思ったりします。
テストサイズ
Googleで定義され、「テストレベルはもう古い、これからはテストサイズ」って言っている人はいますね。
これらは使用されるリソースや実行時間に着目して、テストを分けるような考え方です。
この考え自体はいいと思いますが、テストサイズは自動テストのマネジメントを行う際に使う基準であるので、
テストレベルを判定する唯一の基準として使うのは使いづらいかなと思ったりします。
おわりに
「テストレベル」とは基本情報でも出てくる概念です。
そして、なんとなく共通認識を持ってると勘違いして、「これ単体テストだよね」「システムテストだよね」って言ってる人は多いと思います。
しかし、それらのテストレベルが識別された背景を理解しているかというと、人によってまちまちだったりします。
アドベントカレンダーなので、これらの分け方について体系的に示している書籍を紹介したかったのですが、とくにない気がします。すみません。
ですのでこの記事をきっかけに、テストレベルの背景について思いを馳せていただければ幸いです。
Discussion