十数年前のこと
チームリーダー「このテストやっといてー(どっさり)」
新人の私「はい」
(なんだこれ・・・どう操作したらテストできるのかさっぱりわからない・・・。)
(なんか変な動きをしている気がする・・・確認内容だけに限ればOK扱いになるけどNGって書くべきなんだろうか・・・。)
(バグレポートってなんだ・・・バグを起こしたときの所感とか書けばいいのか・・・。)
ソフトウェア開発業務に新人が入る場合、一番最初に割り振られやすい業務だったりします。
ソフトウェアの仕様を理解しながら操作方法や機能を知るためのに、テストを一通り流してみるのはいい方法ですが、テストそのものは最終的な品質を決定する部分になるので、ソフトウェア開発の重要な部分でもあります。
ソフトウェアテストの中身は開発するソフトウェアごとに違いますが、テストに共通する要点はあります。
「ソフトウェアテスト293の鉄則」では、さまざまなソフトウェアテストで重要とされるポイントを簡潔に押さえているので、テスト作成者からテスト実施者まで幅広く役立つでしょう。
今回は本書から大きな7つのポイントを紹介します。
残りについては・・・買って読んでみてください1・・・良書です・・・(ステマ)。
ソフトウェアテスト293の鉄則/日経BP
Cem Kaner, James Bach, Bret Pettichord 著
テスト技術者交流会 訳
テストの五大要素
・誰がテストを実施するか。
・何をどこまでテストするか。
・どんな問題を探すつもりでテストするか。
・どんなアプローチでテストするか。
・結果の合否判定の基準は何か。
一般に誰がテストを実施しても同じ手順でテスト実施できるようにテストを作ることが必要ですが、ゲリラテストのように自由度が高いテストを行う場合もあります。ゲリラテストではバグの潜んでいそうな所に目星をつけてテストをするのが効果的ですが、これはテストに熟練した人でないと難しいです。反対に自由度が低いテストであれば誰が実施しても同じになるので、テスト初心者でも有効なテストが行えます。
何をどこまでテストするかを決めることで、品質をどこまで保証するかが決まります。テストは8~9割程度までは実施数とバグの発見数が正比例して、残り1~2割を実施するのに8~9割のテストに要した時間と同じだけかかると言われています。2
完全なテストは理想的ですが、現実では1割程度のバグは後から修正してでもテストの費用/期間を半減したいというプロジェクトも少なくありません。定期的なアップデートが計画に含まれているソフトウェア開発では完全な品質よりもコストと品質のバランスのいい箇所を見極めることが重要になることもあります。
開発上のウィークポイントを押さえておこくとで、そこを手厚くテストし、品質を高めることができます。DBが複雑なのか、コントローラが煩雑なのか、セキュリティ面が弱いのか、それぞれにおいて作成されるテストが変わってきます。テストに割り当てられるリソース(人員、時間)は有限なので、効果的なテストができるようにどんな問題(ウィークポイント)を探すのかテストを作り始める前に考えておきます。
テストのポイント
・回帰テスト(リグレッションテスト)
・手順書に従ったテスト
・ビルドごとの簡単なテスト(スモークテスト)
・探索的テスト(テストのアップデート)
・ゲリラテスト(モンキーテスト)
・シナリオテスト
・インストールテスト
・負荷テスト
・性能テスト
削られやすい・見逃されやすいのは回帰テスト、負荷テスト、性能テスト辺りでしょうか。回帰テストは既にテストされている場所だから大丈夫だろうという安心感から優先度が低く見られがちです。バグ改修後の回帰テストでは早いリリースが要求された場合に回帰テストが削られやすくなります。
負荷テスト、性能テストが削られることで問題が起きるのはWeb系に多いです。ローカル開発環境では問題無かったのでサービス開始したら、ローカル環境とは桁違いのアクセスが発生してサービスが停止した、というような話は少なくありません。Web系では適切な最大アクセス数を想定した負荷テスト、性能テストが必要です。
負荷テスト:ソフトウェアを200人もの人が同時に使うとどうなるか。2000人ではどうだろうか。こういったシナリオのシミュレーションには自動化が必要である。
性能ベンチマーク:システムの性能は上がっているのか、下がっているのか。自動テストを実行するときには常に、実行時間を測定する自動テストも用意すべきである。測定結果を集計し、比較して調べることによって、性能劣化を発見できる。メモリやストレージのような資源に使用量を調査する場合も、同じようなアプローチが使えるだろう。
構成テスト:ソフトウェアは、異なるプラットフォームや周辺機器などの様々な環境で動作することが求められる。このような適用範囲の全てをテスト確認することは実質的には不可能である。このテストの範囲を広げるには、実施するテストがプラットフォームに依存しないような高い移植性を持たなければならない。
耐久性テスト:製品を数週間から数カ月もの間使い続けるとどうなるか。例えば、メモリリークが起き、スタックは溢れ、ポインタは大暴れする、そういったエラーがいつ起きるかは分からないが、いずれは解決しなくてはいけない問題である。こういった問題をあぶり出す一つの方法は、システムを再起動することなく、数日から数週間の長い時間をかけて長時間のテストを実行することであるが、これにはテストの自動化が必要になる。
競合状態:特定のタイミングでのみ発生する種類のバグがある。例えば、同じリソースに複数のスレッドやプロセスが同時にアクセスすると、競合状態に伴うエラーを起こすことがある。競合状態起こすことは非常に困難であるが、自動化テストはこんな時に威力を発揮する。手順では難しいタイミングを僅かに変えたテストを何度も繰り返し実行できるからだ。
複合バグ:いくつかの原因が絡んで起こるエラーもある。様々な方法を組み合わせた複雑なテストを大量に実行するには、自動化が有効な手段である。
競合状態のテストは、競合する他のイベントを理解していないと有効なテストを作るのが難しくなります。大規模ソフトウェアでは開発担当箇所が一部分に限られるため、担当箇所以外に競合するものを見落とす可能性があります。広く全体の構成を知っている人がテストを作成するか、テスト仕様書のレビューを行うなどして競合の漏れを無くすようにします。
障害を引き起こすもの
・新規要素
・新規技術
・新規市場
・習熟曲線
・変更事項
・土壇場での変更
・詰め込み作業
・貧弱な設計、保守できない実装
・疲れきったプログラマ
・スタッフの抱える問題
・開発計画外の追加した機能
・外部で作った部品
・予算外の作業
・曖昧さ
・矛盾した要求
・要求の反映もれ
・要求が開発進行と共に進化する(それに対応できない)
・複雑さ
・バグが多発する機能には未発見のバグが潜む
・依存関係が引き起こすバグ
・テストの非容易性
・単体テストをしない
・システムテストまでテストを行っていない
・以前のテストをテスト戦略に組み入れていない(バージョンアップ後の性能テストの変化など)
・テストツールが不十分
・修正しにくい
・言語特有のエラー
これらはテスト作成、実施だけでなく、プロジェクトの計画立案から設計、開発、テストまでの全体において注意が必要なチェックリストになります。
開発初期段階でチェックOKになっていても、開発が進んでいくにつれて予想外の割り込みやアクシデントが発生して、チェックをやり直すとNGになっていることもあります。それぞれの開発フェイズでチェックリストを見直して、その都度バグの要因となりそうなもの発生したりが紛れ込んだりしていないか確認します。
次に示す品質特性のうちどれか一つでも満足できていないなら、バグとして報告しなければならないこともある。
・アクセス可能性
・互換性
・一貫性
・一致性
・標準適合性
・効率性
・インストール/アンイストール容易性
・ローカライズ容易性
・保守性
・性能
・移植性
・回復性
・信頼性
・スケーラビリティ
・セキュリティ
・サポート容易性
・テスト容易性
・使い勝手
テストのOK事項を満たしていれば他におかしな挙動をしていても、テストOKだったのでバグ報告を上げなかったというテスターを見たことがあります(テスト初心者でした)。渡されたテスト仕様書のテストをするように指示されていたので、テスト仕様書に載っていない内容は別のところでテストするだろうという考えだったようですが、基本的には怪しい挙動があれば担当テスト外であってもバグ報告します。
バグを取りこぼして後々に改修するより、同じバグを重複チケットとして閉じる方がずっと低コストで済みます。
テスト慣れしていない人に怪しい挙動もバグ登録せよと言っても、経験が浅いと何が怪しい挙動なのか分からないので、そういう場合にこのリストを見てもらいます。
まず障害を再現させる手順を簡潔に記述することが必要だ。
・一足飛びにいきなりバグ現象を説明するのでなく。1ステップずつ手順を書いてバグに至るまでの手順を誘導する。
・一つひとつのステップに番号をふる
・問題を再現するために必要なステップを何も省略しない
・読み手を簡単に障害に到達させるために、手順を手短にまとめたリストを作る。
・報告書を見やすくするように、余白をうまく使う。
・短く、簡潔な文章で書く。
・何が起こったのか、何が起こると期待していたのかを指摘する。
・自分は深刻な結果だと認識していても、プログラマにはその重大さが伝わらないリスクがある場合には、なぜそう思うのかを十分に説明する。
・相手が問題を認識したり、また修正後の確認テストのための手助けとなるなら、必要なコメントを追加する。
・複雑な製品や問題の場合、最初の3行に、経営幹部/役員/経営人向けの問題の要約を書く。その後に詳細を記載する。
・語調を荒げない。
・誤解を招かないように、冗談などは書いてはいけない。
バグレポートを書くのにどうしてこんなに注意点が多いかというと、バグ発見者が見つけたバグを改修者が正確に辿れないことがあるからです。
「画面のボタンを押したらアプリが落ちた」というようなバグレポートが挙げられたとすると、これから改修者が読み取れる確かな情報は「アプリが落ちる直前の操作がボタンを押したこと」だけであって、バグを正確に再現できないことがあります。また、発生条件に不明確な点が多いほど、そのバグの原因を幾つも推論することになり、調査時間もかかってしまいます。
改修者が正確にバグを再現できるように正確で抜けのない操作手順が必要になります。
(実際はこのポイントだけでは不十分なことも多いですが。)
テストが十分できた(未発見のバグが残っている可能性が低い)と判断するための条件は以下の通りである。
・残存バグがあるとしても、どんな問題を見つけるべきかが分かっている。
・まだテストしていない部分のどこに重要な問題が出て来そうか分かっている。
・リスクに見合った量と方法で製品を検査した
・テスト項目は多岐に及んでおり、見逃しを防ぐのに十分である。
・テストに使える資源はできる限り全て使用した
・顧客が要求するテストプロセス標準を全て満たしている
・テスト方針、テスト結果および品質評価をできるだけ明確に示してある
このようにテストの十分性に配慮してテストを実行したにもかかわらず、リリース後に重大なバグが見つかったとしたら、次の三つのうちのどれかが原因であろう。
・リスクを軽視していた
・テストでミスを犯した
・リスクについて認識は正しかった。しかし、マネジメントレベルであえて危険を犯すという判断をした。これが裏目に出た
「テストが完了したタイミング」は、作成したテスト仕様書がすべてOKになった時ではなく、テストを実施した結果を評価して、品質が適切に担保できていると確認できた時になります。
バグの検出数が想定値付近であり、内容も軽微なものであればテスト仕様書が完了した時にテスト完了として問題ありません。
しかしバグが総定数よりも大量に検出されたり、構造を大きく変える修正があったり、致命的なバグが存在したような時は、それらの問題を引き起こした根源的な要因は何かを考えて、追加で試験を作成・実施し、弱い部分を追加試験する必要があります。
プログラミングはゼロからプラスに積み上げ行く作業ですが、テストはマイナスを減らしていく作業なので、プログラミングが好きでソフトウェア開発を始めた人の中にはテストは性に合わないという人もいます。
ですが、ポイントを押さえて戦略的にテストを行えば、テストは単なる確認作業ではなく、クリエイティブで楽しい面もあります(きっと)。
注釈