テストレベルに「機能テスト」が入ると困る理由

はじめに

この記事は ソフトウェアテストの小ネタ Advent Calendar 2019 の3日目の記事です。

もはや、「小ネタ」という文量を遥かに超えてしまっている気もしますが、「機能テスト」という1つの単語に対しての小ネタということで…。*1

目次

この記事のきっかけ

こんな記事がありました

先日、テストレベルの種類*2として

  • 単体テスト…関数単位のプログラムのテスト
  • 結合テスト…プログラムを組み合わせて行うテスト
  • 機能テスト…結合したプログラムを使い、1つの機能として行うテスト
  • システムテスト…機能を統合したプログラムを検証するためのテスト
  • ユーザによるテスト…(特に細かい説明なし)

が羅列してあり、「システムテスト」の中身として

  • 回帰テスト
  • セキュリティテスト
  • 負荷テスト(性能テストを含む)

などが書いてある記事を見つけました。*3

これを開発者が話していたので、思わず「テストについては様々な側面で分類することができる」と言った上で、テストレベルとテストタイプの説明をしました。

テストレベル

JSTQBでは「テストレベルは、系統的にまとめ、マネジメントしていくテストの活動のグループである。」と記載されています。*4

また、設計工程に合わせてテストレベルを設定すると分かりやすいとは思います。

ここではJaSST'18 Kyushuでの池田暁さんの資料から図を拝借します。

f:id:nihonbuson:20191129112449p:plain
V字モデルとテストレベル

JSTQBではテストレベルを下記の4つとしています。

テストタイプ

JSTQBでは「特定のテストの目的から見たソフトウェアシステムの特性をテストするための活動を束ねたものである。」と記載されています。*5

有名なものとしては品質特性があります。*6ただし、盲目的にここに乗っている品質特性を当てはめるのではなく、自分たちの製品に必要なものは何か考えることが必要です。

f:id:nihonbuson:20191129125328p:plain
品質特性(JIS X 25010より)

なお、ここに書かれているもののうち、機能適合性を「機能性」、それ以外の部分を「非機能性」と呼んだりします。また、機能性をテストすることを「機能テスト」と呼んだりもします。

素朴な質問

テストレベルとテストタイプの説明をしたところで、QA歴の浅い人から興味深い質問をもらいました。

f:id:nihonbuson:20191202114734p:plain
素朴な疑問

それに対し、様々な知見を元にした回答を複数人で行なったのですが、せっかく良い話なので、ブログにして公開することにしました。*7

「機能テスト」がテストレベルに入っていることによる弊害

さて本題です。どうして、「機能テスト」がテストレベルに入っていると困るのでしょうか?

理由1. 複数人の間で認識齟齬が発生してしまうため

機能テストをテストレベルに入れてしまうと、「機能テスト」と呼んだ時、テストレベルの1つのことを言っているのか、それとも機能性のテストのことを呼んでいるのか混乱します。そして、認識齟齬にも繋がるリスクがあります。

例えば、下記のような会話が発生するかもしれません。

A「機能テストをやっといて」

B「はーい(単体テストレベルの機能性に対するテストを実施)」

A「なんだよ。機能テストをやってないじゃないか(結合したプログラムをテストしてもらう考えだった)」

このような認識齟齬が発生しないためにも、JSTQBで書かれているような内容で進めたいと個人的には考えています。*8

理由2. 不足や重複が確認しづらいため

例えば、「単体テスト、統合テスト、機能テストをします」と言われたとします。

すると、ここでの例は下記のどちらなのか分かりづらくなります。

  • 「システム全体の機能面は機能テストでテストする」と伝えようとしている
  • 単体テスト、統合テストとは別に、機能面の単体部分などをテストする」と伝えている(システムテストが抜け漏れている)

つまり、この例の場合、システムテストレベルは行われるかどうか分からない」という状況が生まれています。

このように、不足しているテストレベルやテストタイプを確認しやすくするためにも、JSTQBなどを使って共通理解をしたいと考えています。*9

理由3. テストできるはずの粒度・タイミングでのテストができるように見えなくなってしまうため

今回の例だと、「機能面のテスト(テストタイプの「機能性テスト」)を実施するには、コンポーネントテストでもシステムテストでもできる」ということが示しづらくなります。

元記事だと「単体テスト結合テスト、機能テスト、システムテスト、ユーザーによるテスト」と書いており、あたかも機能面のテストは単体テストレベルや結合テストレベルでは行わないように見えてしまうからです。

別の例として性能テストがあります。元記事では、性能テストをシステムテストで行うものの1つとして書いています。

しかし、システムテストでのみ性能テストを行うかというと、そうではありません。例えば、SQL単体での性能を測定する場面もあるはずです。この場合、単体テストレベルで性能テストをやっていることが分かります。

これを「性能テストはシステムテストレベルで行うべきだ」という考え方になってしまうと、後行程での不具合発見に繋がることになります。

なお、JSTQBではできるだけ前行程での確認を推奨しています。

本節では、全テストタイプにおける各テストレベルの適用例を示したが、すべてのソフトウェアに対して、各テストレベルで示した全テストタイプを適用する必要はない。

ただし、各テストレベルで適用可能なテストタイプを行うことが重要である。

中でもテストタイプが必要となる最も早いテストレベルで行うことは重要である。

なので、テストにおいてはテストレベルとテストタイプの掛け合わせでテストの対象を考えることが多いです。

(テストタイプだと捉えることもできてしまう)機能テストをテストレベルに入れてしまうと、「テストレベルとテストタイプの掛け合わせ」の表現が難しくなってしまうでしょう。

さらに発展した話

テストコンテナ

「テストレベル・テストタイプを掛け合わせる」という話をテスト設計コンテストチュートリアル(U30)では、テストコンテナを用いて図示しています。

f:id:nihonbuson:20191129194913p:plain
テストコンテナ図

こうすることにより、「困る理由2. 不足や重複が確認しづらいため」を解消することを手助けできます。

テスト計画

「テストレベル・テストタイプを掛け合わせる」という話には、テスト計画にも繋がります。

詳しくはWACATE 2019夏の資料を見ると分かりやすいかもしれません。

f:id:nihonbuson:20191129194647p:plain
テスト計画におけるテストレベルとテストタイプ

テスト計画時にテストレベルとテストタイプを意識することで、どのレベルでどのような特性のテストを行うのか示すことができます。

これはテスト計画とは名ばかりのスケジュール表とは違い、それぞれのタイミングでの責務が見えてきます。

また、開発とも合意を取ることで、「どの部分を開発者自身でテストするのか」もハッキリさせることができます。

テスコンチュートリアル(OPENクラス)にて…

と、ここまで書いてたら、昨日開催された『テスト設計コンテスト'20 チュートリアル』にて、講師のにしさんに、

「まあ、機能テストがテストレベルなのかテストタイプなのか、どっちでもいいんじゃね?」

と、言われてしまいました…w

おわりに

今回は、「機能テスト」という言葉をきっかけとして、テストコンテナやテスト計画についても書いていきました。

自分もまさかこんなところまで議論するとは思わなかったですが、ここまで議論ができたのも、周りの環境が良いからなんだろうなぁ…としみじみ感じてます。

最後に、テストレベルとテストタイプの説明を聞いたQA歴の浅い人と開発者の感想を載せて終わりとします。

QA歴の浅い人の感想(Slackのスクショ)

f:id:nihonbuson:20191129195747p:plain
感想

開発者の感想

「今まで自分たちは、『如何にテストについてなんとなくでやってきたのか』ということを実感しました。

こういう風にして、どんどん皆さんがテストに興味を持って、より深く考えてくれると良いですね。

*1:本当は、「マツコの知らないテスト勉強会の世界(2019年版)」をやろうと思ったんだが、昨年とあまり代わり映えしないなぁ…というのと、どうしてもこのネタを公開したいと思ったので、急遽テーマを変更しました。

*2:元記事では「テストの種類」と書いてありましたが、中身はテストレベルを意識したものだったため、本記事では問題点を分かりやすくするために「テストレベルの種類」と表記します

*3:別に晒すことが本記事の目的ではないので、URLは載せません。ただ、それが400以上の好意的反応を貰っているのは「なんだかなぁ…」とも感じてしまいます

*4:JSTQB FLのシラバスより

*5:JSTQB FLのシラバスより

*6:IPAの資料より拝借

*7:ここまでが前置き

*8:別に「JSTQBが正しい」と言いたいわけではなく、JSTQBという共通言語にしやすいものがあるのでそれに従うと楽だよねというだけです。開発チーム内で「結合したプログラムをテストする=機能テスト」という考えが統一できているならば、使っても良いとは思います。

*9:もちろん、開発チーム内で用語の定義が統一されており、その理解を皆がしているならば使っても良いとは思います。