1. ホーム
  2. testing

[解決済み] ユニットテスト、機能テスト、受け入れテスト、統合テストの違いは何ですか?[クローズド]

2022-03-18 01:32:41

質問

ユニットテスト、機能テスト、受け入れテスト、統合テスト(その他、言いそびれたテストの種類)の違いは何でしょうか。

どのように解決するのですか?

どこを見るかによって、微妙に違う答えが返ってきます。 私はこのテーマについて多くの本を読みましたが、その中から私が選んだ答えは次のとおりです。

単体テスト

機能の最小単位をテストします。典型的にはメソッド/関数です (例: 特定の状態を持つクラスがあるとき、そのクラスで x メソッドを呼び出すと y が発生するはずです)。 ユニットテストは、ある特定の機能に焦点を当てるべきです (たとえば、スタックが空のときに pop メソッドを呼び出すと InvalidOperationException ). テストコードに触れるものはすべてメモリ上で行わなければなりません。 テスト対象のコードは、そうであってはならないのです。

  • 自明でない)協力者への呼びかけ
  • ネットワークへのアクセス
  • データベースを叩く
  • ファイルシステムを使用する
  • スレッドをスピンアップする
  • など

遅い、理解しにくい、初期化しにくい、操作しにくい依存関係は、適切な手法でスタブ化・モック化・無効化し、依存関係ではなく、コード単位が何をするかに集中できるようにする必要があります。

要するに、ユニットテストはできるだけシンプルで、デバッグしやすく、(外部要因が少ないため)信頼性が高く、実行速度が速く、プログラムの最小の構成要素が組み合わされる前に意図した通りに機能することを証明するのに役立つものです。 ただし、単体では完璧に動作することを証明できても、コードの単位を組み合わせると爆発する可能性があるため、注意が必要です......。

統合テスト

統合テストは、コードのユニットを結合し、結果の組み合わせが正しく機能することをテストすることで、ユニットテストの上に構築されます。 これは、1つのシステムの内部であったり、複数のシステムを組み合わせて何か便利なことをすることであったりします。 また、統合テストと単体テストを区別するもう一つの点は、環境です。 統合テストでは、スレッドを使用したり、データベースにアクセスしたり、すべてのコードが正しく動作するために必要なことを行うことができます。 を使用することで、異なる環境の変化にも正しく対応できます。

ディスクに触れることなくシリアライズコードを構築し、その内部をユニットテストした場合、ディスクにロードしたりセーブしたりするときにそれが動作するとどうしてわかるのでしょう? もしかしたら、ファイルストリームのフラッシュとディスポーザーを忘れているかもしれません。 もしかしたら、ファイルのパーミッションが正しくなくて、インメモリストリームを使って内部をテストしたのかもしれません。 確実に知る唯一の方法は、本番に最も近い環境を使用して「実際に」テストすることです。

主な利点は、配線バグ(例:クラスAのインスタンスが予期せずBのNULLインスタンスを受信)や環境バグ(私のシングルCPUマシンでは正常に動作するが、同僚の4コアマシンではテストにパスしない)など、ユニットテストでは発見できないバグを見つけることができることです。 主な欠点は、統合テストはより多くのコードに触れ、信頼性が低く、失敗を診断するのが難しく、テストは保守しにくいということです。

また、統合テストは、必ずしも完全な機能が動作することを証明するものではありません。 ユーザーは私のプログラムの内部詳細について気にしないかもしれませんが、私は気にしますよ。

機能テスト

機能テストは、与えられた入力に対する結果を仕様と比較することで、特定の機能が正しいかどうかをチェックします。 関数テストは、中間結果や副作用を気にせず、結果だけをチェックします (x を行った後、オブジェクト y が状態 z を持つかどうかは気にしません)。例えば、関数 Square(x) を引数 2 で呼び出すと 4 が返ってくる、というような仕様の一部をテストするために書かれる。

受入テスト

受入テストは2種類に分かれるようです。

標準的な受け入れテストでは、アプリケーションの機能が仕様を満たしているかどうかを確認するために、システム全体(例えば、Webブラウザ経由でWebページを使用すること)でテストを実行します。例:ズームアイコンをクリックすると、ドキュメントビューが25%拡大されます。

利点は、テストが平易な英語で記述され、ソフトウェア全体として機能が完全であることを保証することです。 デメリットは、テストのピラミッドがもう一段階上がってしまうことです。受け入れテストはコードの山に触れるので、失敗を追跡するのは難しいかもしれません。

また、アジャイルソフトウェア開発では、ソフトウェアの開発時に顧客が作成した/顧客のためのユーザーストーリーを反映したテストを作成することがユーザー受入テストになります。 テストに合格すれば、そのソフトウェアが顧客の要求を満たし、ストーリーが完成したとみなすことができることを意味します。受け入れテストスイートは、基本的に、システムのユーザーが使用する言語でテストを記述した、ドメイン固有の言語で書かれた実行可能な仕様です。

結論

どれも補完的なものです。 1つのタイプに集中することが有利な場合もあれば、完全に排除することもあります。 私にとっての大きな違いは、プログラマーの視点から物事を見るテストもあれば、顧客やエンドユーザーの視点から見るテストもあることです。