プログラムの作成が終わった段階で行うテストが単体テストになります。
単体テストは、軽視されがちですが、実はとても重要な工程になります。
軽視されている理由は、プログラム作成と単体テストを一緒に「実装」工程としているプロジェクトが多いことが挙げられます。単体テストを一つの工程にしていないということです。
そのような状況のプロジェクトでは、単体テストの項目は非常に意味のないものができあがります。
その場しのぎの、どうでもいい、バグの出ないテストしかしないということです。
これでは、結合テスト以降に大量に障害(バグ)が出るのは当たり前なのです。
今回は、品質を上げるための、単体テストに必要な観点について、学んでください。
単体テストとは?その目的は?
まず、単体テストとは何なのかについて見ていきましょう。
単体テストとは、プログラム自体が、要求される機能を満たしているのかどうかをチェックすることです。
次工程の結合テストでは、プログラム自体ではなく、プログラムを機能として捉えます。
例えば、あなたが担当しているプログラムが「請求書発行機能」というものであれば、単体テストは、請求書を発行する機能が正しく動作するのかどうかをテストするのが「単体テスト」です。
一方、請求書発行機能が、請求管理サブシステムというシステムの一部の機能だとすれば、請求管理サブシステムの中で、請求書が正しく発行されるかどうかをチェックするのが「結合テスト」になります。
当然のことですが、結合テスト、総合テスト、ユーザーテストで障害(バグ)が発生する基は、全て単体テストの不備に起因します。
単体テストで障害(バグ)を全て取り除くことができれば、次工程以降のテストでは障害(バグ)は発生しないのです。ですが、これはあくまで机上の空論です。不可能なことです。
機能間、システム間などで想定しきれない部分によって、障害(バグ)が発生することは多々あるからです。所詮、人間が作り上げるものです。全て完璧に仕上げることなど不可能なのです。
ですから、その不可能なものを極力完璧に近づけるために、テストを徹底的に行わなければならないのです。ユーザーに喜んでもらえることができないのです。
その出発点となる単体テストが障害(バグ)を多く取り除くことができる唯一の工程なのです。
正しく動作することはもちろんですが、単体テストは、障害(バグ)を多く取り除くことが最大の目的なのです。
ある条件の場合のみ、正しく動作するのではなく、どのような状態であっても正しく動作させなければいけないのです。
その、「どのような状態であっても」という部分が、テストの観点となるのです。障害(バグ)を出しながら、どのような状態であっても正しく動作するように修正していくのが、単体テストなのです。
いくら障害(バグ)が発生しても許される工程であると認識してください。
結合テスト以降は、必ず、なぜ単体テストで見つけられなかったのか?という理由や、発生させないための再発防止策などが必要になり、簡単に修正ができなくなります。
ですから、単体テストで出せるだけ障害(バグ)を出すことが重要なのです。
単体テストに必要な観点とは?
単体テストの方法として、大きく、ホワイトボックステストとブラックボックステストと呼ばれるものがあります。
ホワイトボックステストとは、プログラムに対して、以下の3つをデバッガなどのツールを使って確認する方法です。
- 順次
- 条件、分岐
- 繰り返し
プログラムの各命令が、きちんと命令されていることを確認するものが「順次」。命令網羅とも呼ばれます。これは、変数に値が正しく設定されているか、計算がされているかなどを確認していくものです。
次に、IF文などの条件文が正しく、判定され、想定している命令を実行するかどうか、想定している関数などに分岐するかなどを確認するのものが「条件、分岐」です。条件網羅とも呼ばれます。
そして、繰り返しまたはループとも言いますが、想定している回数分繰り返されているかどうかを確認していきます。
これらは、主に、デバッガというツールでひとつひとつ確認していきます。
テストする対象が、それ自体で動作しない関数などであれば、それを起動させるための呼び元の関数を作って動作させたりすることもあります。この呼び元のことをドライバと呼びます。
このドライバに、起動させる関数への引数などを設定し、動作を確認するということをします。
逆に、テスト対象の関数から呼ばれる別の関数が別な担当者が作成しているプログラムだとした場合、仮のプログラムが必要になる場合があります。
この仮のプログラムをスタブと呼びます。結合テストで、スタブが実際のプログラムに変わり、機能間テストが行わることになります。ですので、結合テストでは、この関数間の受け渡しに関わる部分に障害(バグ)が発生する可能性があるため、受け渡しに関するテスト項目が必要となります。
ドライバ、テスト対象、スタブの関係は以下のようなイメージになります。
一方、ブラックボックステストですが、プログラムを機能としてとらえ、仕様通りの機能を満たしているかをチェックするものです。
請求書発行機能を例にすると、
ホワイトボックステストは、
- タイトルを格納する変数に「請求書」という文字列が設定されているか
- タイトルの位置を格納する変数に座標が正しく設定されているか
- タイトルの色やフォント、サイズを格納する変数に正しく値が設定されているか
など
ブラックボックステストは、
- 請求書が発行できているか
- 請求書のタイトルが「請求書」と印字されているか
- 印字位置は正しいか
- タイトルの色やフォント、サイズが正しいか
など
以上のように、タイトルについてのチェックに関してそれぞれホワイトボックス、ブラックボックステストの項目を考えてみました。
ホワイトボックスは、あくまでプログラム内での確認になっているのが分かると思います。
ブラックボックスは、プログラムではなく、出力されて請求書を確認しているのが分かると思います。つまり、請求書発行機能について確認しているということです。
と、ここまでは、極一般的なテストの説明ですが、ここで気づくかどうかですが、確認していることは、同じ内容であると思いませんか?
ホワイトボックスにしても、ブラックボックスにしても、同じく、請求書のタイトルについての確認になります。何が違うのでしょうか?
それは、観点です。
みるべきところが違うということです。
ホワイトボックスでは、変数に正しい情報が設定されているか、条件が正しいかなどを確認し、それを確認することで、プログラムは大丈夫だと見なすのです。
ブラックボックスでは、プログラムは確認できたので、実際の請求書にはどうだろうかという観点になります。プログラムが正しく、実際の請求書も正しく出力されたことを確認することで、請求書発行機能は大丈夫だということになるのです。
特に、プログラム内での確認では大丈夫だったものが、実際に紙に印刷をすると想定外のことが起こったりします。それを微調整するためにも、実際の請求書を出力させ、印字内容を確認していくことが大事です。それがブラックボックスの役割でもあります。
前提として、このホワイトボックスとブラックボックス両面のテスト観点が必要であることを覚えておいてください。
そして、重要な観点として、全てのパターンを検証する必要があるということです。
正常ケース、異常ケースで取りうるパターン全てを確認するということです。
理由は、結合テスト以降ではしないであろうパターンを担保しておくということと、システム的に可能な条件がどういう結果になるのかを把握するためでもあります。
但し、全てのパターンといっても、範囲確認のような場合は、境界値の確認で十分です。
たとえば、以下の仕様があったとします。
- ID:01~10の場合、「一期生」と表示する
- ID:11~20の場合、「二期生」と表示する
- ID:21~40の場合、「三期生」と表示する
- ID:41~の場合、「四期生」と表示する
この場合の全パターンとは、全てを確認するわけではなく、以下のような境界値を考慮するわけです。
- 一期生:10以下
- 二期生:11、20
- 三期生:21、40
- 四期生:41
以上の、6パターンとなります。
この場合、2、3などを検証しても、2、3は10以下であるのは決まっているので、10以下を確認することで、必ず一期生になることが分かります。これが論理的思考でもあります。
無駄なテストパターンは必要ありません。しかし、41の確認は必ず必要ですので、注意してください。
40が三期生と表示されるのが検証されても、41が三期生となる可能性もあるからです。
このように、取りうるパターンは、全てテストするということが重要です。
また、リグレッションテストとは全テストで必須の観点であるでも書きましたが、現行のシステムがきちんと動作するかの確認も盛り込まなければなりません。これは必須と思ってください。
現場で使えるソフトウェアテスト Java編/町田欣史【2500円以上送料無料】
|
カテゴリ:テスト