質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.93%

単体テスト、結合テストの方法について

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 15
  • VIEW 21K+

score 38

単体テスト、結合テストについて質問です。 私はこれらのテストについて以下のように考えております。

  • 単体テストについて

単体テストはカバレッジが100%になることを確認するものと考えており、先にテストソースを書いてから仕様書を書いています。

  • 結合テストについて

結合テストは予めテストケースを考えてからブラックボックステストを行い、処理が想定通りに行われることを確認するものと考えています。

  • お伺いしたいこと

カバレッジを100%にするための単体テストの意味が分からなくなってきており、ソース記述と仕様書作成の順番も逆のような気がします。少し理想論すぎるとも思うのですが、本来は仕様書を先に書き、それを元にテストを記述して実行した結果カバレッジを100%にするものなのでしょうか。

また、結合テストケースは作ろうと思えば際限なく作れそうに思え、その線引きに悩んでいます。例えば5つの定義が記述されている定義ファイルを読み込む機能のテストをする場合、各定義キーの値が記述されているかいないかの組み合わせだけでも2の5乗で32通りあると思います。結合テストケースの線引きは製作物の重要度等を考慮してテスト作成者がテストケースを取捨選択するものと捉えてよいのでしょうか。

それ以外にも回答者様のテスト方針等がありましたら聞かせていただけると幸いです。よろしくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+16

ソフトウェアテストは、その設計工程と極めて密接に関連(対応)しているため、どんな開発プロセス を採用しているかによって方法論も利用する道具も違ってきますので、テストのことだけを取り上げて論じても議論がすれ違いになる危険があります。

ですから、一般論的についての個人的な見解になってしまいますが、自分はinashichiさんとかなり違う認識を持っていますので、ご参考になればと思い回答します。

inashichiさんは テスト駆動開発 の事を念頭に置いてご質問だと思いますが、テストに対する考え方を理解しやすいので、まずは ウォーターフォール型 の開発プロセスの場合について書きます。

1. 設計工程とテスト工程の関連について

工程の分け方や呼び方はプロジェクトによっていろいろありますが、設計工程については下記ページの解説が分かりやすです。(参照先の資料によっても工程の分け方や呼び名が異なるので、適宜読み替えが必要です。)

  1. 外部設計:画面や帳票などのユーザーインターフェースを設計する工程
  2. 内部設計:開発するシステムを大まかな機能ごとに分割し、それらをつなぐインタフェースの仕様などを設計する工程
  3. 詳細設計:実際にどのような処理を行ってプログラムを動作させるかを決める工程

次にテスト工程の対応関係についてですが、以下のようになっています。
一般的なシステム開発で実施するテストの種類
V字モデルの復習

  1. 総合テスト:システムが本番業務の要件(外部仕様)を全て満たしているか、を確認する工程
        本来は外部設計工程でテスト仕様を確定すべき
  2. 連結テスト:サブシステム内もしくはサブシステム間で内部仕様通りに正しく連係動作することを確認する工程
        本来は内部設計工程でテスト仕様を確定すべき
  3. 単体テスト:システムが詳細仕様をきちんと満たしているかを確認する工程
        本来は詳細設計工程でテスト仕様を確定すべき

2. 詳細設計書のあり方について

先に書いたように、単体テストは、個々のモジュールが 詳細設計の仕様通りになっているか を確認するためのテストですので、まず仕様書ありき、です。つまり、コーディングも単体テストも、すべては詳細設計書を元に実施すべきものです。

しかし、実用に耐え得るほどに漏れなく詳細に記載すると、コーディング・単体テストを実施中に発生した細かな仕様変更を詳細設計書へ随時反映させるのはとてもコストの掛かる作業となってしまいます。そのため、短納期のプロジェクトでは詳細設計書のメンテナンスをつい後回しにしてしまったり、ついにはメンテナンスを放棄してしまうという最悪のケースさえ散見されます。

現実と乖離してしまった設計書ほど手に負えないものはありません。この「嘘の埋め込まれた設計書」(=詳しく調査しなければ、どこが違っているかさえ分からない)が、追加開発する際や障害発生時に必ず必要な調査活動を大きく妨げることになります。それを避けるために「後追い」で設計書をメンテナンスしたとしても、既にコーディングも単体テストも終わっているので、実際には使われないかもしれない設計書(のバージョン)のメンテナンスのために工数を割くという非生産的な活動になってしまいます。

詳しく書けば書くほど、そのメンテナンスが困難になり結局使えなくなってしまうというジレンマがあるため、下記のようなブログの記事もある程です。
    詳細設計書という名のゴミ

3. テスト駆動開発というアプローチ

テスト駆動開発というと、その解説の中に テストファースト という言葉が登場するために、コーディングに先立ち単体テストをする開発手法であるかのように受け止められる方もいらっしゃるようですが、実際には詳細設計工程のはらんでいる矛盾を解決するために考え出された手法です。

設計書メンテナンスのコストを削減する最大のコツは、実際に役立たないものや重要性の低いものなど、コストに見合わない設計書は極力書かないことです。

そこで、テスト駆動開発では、従来のような形式の詳細設計書は作成しません。その代わりに、作成するモジュールの仕様を規定するテストケースを、紙(=人間が参照するだけのドキュメント)ではなく実際にテストに使用できる形で作成します。ですから、Javaのテスト駆動開発で作成する テストクラス は、実はテストのためのものではなくテストに使用できる形で作成された詳細設計書であり、JUnitはテストクラスという形で作成された詳細設計書を実際のテストに使えるようにするためのツールなのです。

ですから、テストクラスのコメントは、そのテスト観点実装上の注意、このような仕様になった経緯など、コードを読んだだけでは分からない重要なポイントについて詳しく書いておくべきです。一方、実際に動くコードの方は、メンテナンス性を高めるために、極力コードを読めば分かるように実装してなるべくコメントを書かないようにします。

テスト駆動開発では、

  • 詳細設計が人間の解釈の余地のないテストクラスという形で作成されているので、仕様の勘違いによるコーディングミスを防げる
  • 詳細設計が完了した時点で、単体テスト用のテスト仕様書も「動くテストケース」という形で完成している
  • 常に仕様とのズレがないかを確認しながらコーディングするので、コーディングが完了した時点で単体テストも完了している
  • 仕様変更が発生した場合にも、テストクラス(=詳細設計書に相当)の修正とコーディング時の確認(=単体テストに相当)が同時に完了する

つまり、体裁を整えるためだけのドキュメントの作成・修正という無駄な作業を排除し、詳細設計書が実際のコードと乖離してしまわない仕組みを開発プロセスの中に組み込んでしまっている点が、テスト駆動開発の最大のメリットと言えます。

そういう観点から言えば、

先にテストソースを書いてから仕様書を書いています。

というのはちょっともったいない(テスト駆動開発のメリットを活かし切れていない)ように思います。

4. カバレッジの意味するところ

単体テストはカバレッジが100%になることを確認するものと考えており

についても、異論を持っています。

そもそも、カバレッジという指標については、何を意味しているのかを議論の前に厳密に定義する必要があります。
テストカバレッジ(てすとかばれっじ)
    検証の種類-カバレッジ(網羅率)

inashichiさんがおっしゃっている「カバレッジ100%」というのは、おそらくホワイトボックステストにおける「コードカバレッジ(構造カバレッジ)」のことだと思いますが、

機能保証が求められている場面でコードカバレッジ100%を達成しても、機能カバレッジを達成されていることの保証にならない。
テストカバレッジの数値はしばしば独り歩きするが、カバレッジ指標を有効活用するには単に数字だけを見るのではなく、何を計測しているものなのかを見極めたうえで使い分けをしていくことが重要である。

ということなので、「カバレッジが100%になることを確認する」ことが単体テストの目的になってはいけないと思います。

コードカバレッジを測定し、テストが実施されていないコードを確認することにより、テストの妥当性を向上させることができます。 

という記載もある通り、コードカバレッジの分析は、ソースコード自体の品質担保ではなくテストそのものの妥当性(言い換えると、詳細設計書としてのテストクラスに漏れが無いか)を判断する材料です。ですから、カバレッジが想定よりも低い場合は、詳細設計に考慮漏れがあったり、逆に仕様以上(オーバースペック)のコードになっているということを示唆しています。

とはいえ、詳細仕様のすべてがテストクラスのコードとして記述可能な訳ではありませんし、技術的には記述可能だったとしてもコストに見合わない、あるいは納期に間に合わない場合もあります。ですから、詳細仕様のどこまでをテストクラスの形で作成するかはプロジェクト全体の要件を考慮した上で慎重に決定すべきものであり、現実にはカバレッジ97%で妥当と判断されるケースだって少なくはないです。

5. 結合テストのケース作成について

結合テストケースは作ろうと思えば際限なく作れそうに思え、その線引きに悩んでいます。

これはテストを担当する人全員に共通した、しかも最大の悩みではないでしょうか。しかし、テストは事前に綿密に設計し計画するものであり、条件の全ての組み合わせを機械的に確認するものではないので、テスト技術者の腕の見せ所でもあります。

そもそも、テストはシステムにバグのないことを証明するために実施する訳ではありません。
何であれ、存在することを証明するには実例を一つ示せば良い訳ですが、存在しないことを証明しようとするとあらゆる可能性を否定しなければならず、複雑なシステムにバグの無いことを有限の時間で証明することは事実上不可能です。

そこで、許された時間内にいかに効率的にバグを炙り出せるかが重要であり、適切なテスト方法で発見されたバグ数の収束状況から、一定の品質に達したと判断するのが一般的なアプローチ方法だと思います。
どんなバグがいくつ潜在しているか分からないので、全くバグが見つからないのであればテスト方法自体が不適切である可能性があります。かと言って、いつまで経ってもバグが収束しないのであれば、システムの品質が悪すぎるということです。
このテーマはとても奥深い問題なので、下記ページの情報などを手掛かりに調べてみてください。
    ソフトウェア品質評価技法
    テスト消化曲線とバグ発生曲線の7パターン診断

さて、有限の時間でなるべく効率よくテストするために真っ先に実施すべきことは、テスト観点を洗い出すことです。そうすることで漏れや偏りの無いテストケースを作成することができます。下記ページを参考に、開発中のシステムに適したテスト観点を洗い出してください。
    テストの観点をどう決めるか

テスト観点が決まったら、必要な観点が漏れないように注意しながら、それぞれに工数を割り振って行きます。

ここまで準備出来たら、個々のテスト観点について具体的なテストケースを作成して行きますが、条件の組み合わせ数が膨大な場合は全てを網羅することができません。かと言ってデタラメに選んだのでは偏りが発生するかもしれません。それで科学的な方法でテストケースを効率的に絞り込む手法がいくつか提案されていますが、直交表を用いた方法が広く用いられていますので、下記ページなどをご参考に調べてみてください。(直交表は実験計画法という理論に基づいたものですが、詳しく説明すると分厚い参考書になるほどの内容ですので)
    組み合わせテストを科学的に効率化する――手法とツール、品質保証のための道具

ソフトウェアテストって、新人の開発者が先輩のやり方を見よう見真似で何となくやっている、というのが日本の開発現場の実態ではないかと思いますが、実際には非常に奥深く、専門技術の必要な分野だと思います。優れた参考書もありますので、精読する時間はないかもしれませんがポイントとなる箇所を拾い読みしてみるだけでも大いに勉強になりますから、一度手にとって見られることをオススメいたします。(わざわざ買わずとも、地元や近隣の公立図書館で借りられる場合も少なくないですから)
良書はたくさんありますが、とりあえず下記の2点をご紹介しておきます。
    知識ゼロから学ぶソフトウェアテスト
    ソフトウェアテスト293の鉄則

ちょっと長くなってしまいまいたが、幾らかでもご参考になれば幸いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/14 01:03

    沢山の参考ページと貴重なご意見、ありがとうございます。
    カバレッジのご指摘はごもっともであり、単なる100%の達成は元々の設計に不備がある可能性等を考えるとあまり意味はないですね。結合テストに関しては、完璧を目指すのではなく限られた条件下で効率よく結果を残すことが大事なんですね。また、テスト駆動開発について少し理解が深まりました。テストケースが詳細設計書も兼ねるのは魅力的なので、紹介ページを元に調べてみようと思います。
    ご回答ありがとうございました。

    キャンセル

+2

テストに対する考え方は色々あるので、アンケート的な質問と思いました。
そこで、私の考え方を書いてみます。(必ずしも「正しい」とは限りませんので、ご用心。)

テストは、テスト対象のプログラムが仕様を満たしていることを検証するために行うものです。
そのためには、まずテスト対象プログラムの「仕様」が明確になっていることが必要です。
「仕様」があれば、正しい姿が明確なのでその通り動作していることを検証する「テスト仕様」を設計できます。この時、全てのケースをテストすることは現実問題不可能ですので、省略しても良い部分は省きます。

さて、省いて良いと思ったけど人間の判断ですから、重要なコードのテストが漏れたり、重要な条件分岐が適切に分岐していることのテストが漏れたりすることがよくあります。それをできるだけ防ぐために、カバレッジを計測し、重要なコードや分岐について必要なテストができていることをチェックし、漏れが見つかったらテスト仕様へフィードバックするとよりテスト仕様にできます。

しかし、この方法でカバレッジを100%にすることはかなり困難です。
一般にはスタブを入れるなどして、条件分岐させると思います。しかし、カバレッジ100%を目指した場合、if文の中身を見て条件分岐するようにスタブを作りがちになるので、条件分岐のバグを検出できるのか、強い疑問を感じます。

テスト・リソースには限りがあるので、カバレッジ100%を目指すより、テスト仕様が「仕様」を本当に検証できているのか、思わぬ使い方が存在しないか、レビューなどした方がテスト効率が良いと、個人的には考えています。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/14 00:55

    プログラムを書いてからテストケースを漠然と考えるのではなく、仕様を満たしていることを示すためにテストをするんですね(書いてみれば当たり前でした)。
    今までは仕様に対する意識が希薄だったような気がします。といいますか、プログラムを書きながら文の構造を考えていた節もありましたので、設計段階の意識から気を付けようと思います。
    ご回答ありがとうございました。

    キャンセル

+1

内容からみると「テスト駆動開発」ではないかと思います。
1.テストコードを書く
2.そのテストコードが動く最低限の実装を行う
3.コードを洗練させる

個人ではまだ経験したことはないのアドバイスはできないです。

カバレッジ100%は、
先にテストコードか実装かにかかわらす 「自分が書いたソースが少なくとも一回は通ってるよね」を保障するものです。 EclipseのプラグインとしてDJUnitとか使えます。

でも単体テストはカバレッジ100%だけではなく、パターン網羅も考えないといけないです。

if (条件A || 条件B)の場合、 条件Aをテストすれば、 カバレッジ100%にはなるが、パターン網羅はされてないです。

結合テストは、
パターン網羅(記述してくれた内容はパターン網羅かなと)より 機能網羅(機能設計書もしくは基本設計書)をテストすべきかと思います。

以上、結構個人意見もたくさん含まれていますので、参考程度で。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/08 19:19

    ありがとうございます。「テスト駆動開発」の文言を間違えて理解していました。タグに追加しました。でも実際このようには単体テストできないですよね・・・。

    liguofeng29様の例だと私の環境では"1 of 2 branches missed"と表示されてカバレッジが100%にならないです。そうなれば確かにカバレッジによってパターン網羅をチェックできますね。
    機能網羅についてはすみません、少し調べてみてもよくわからなかったのでまた後ほど調べます。でも単体テストと異なる観点でテストを行っていることは参考になりました。
    ご回答ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.93%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る