web-dev-qa-db-ja.com

統合テストはいつ書くべきですか?

TDDのルールによると、ユニットテストは製品コードの前に記述されていますが、具体的な(モックではない)ワイヤードオブジェクト間の相互作用を実行する統合テストはどうですか?

「配線」をテストするためだけに、ユニットテストの前に、または量産コードの後に​​記述する必要がありますか?

受け入れテストや機能テストではなく、低レベルの統合テストについて話していることに注意してください。

30
Chedy2149

Rspec Book は、他のBDDリソースの中でも、次のようなサイクルを示唆しています。

enter image description here

基本的に、プロセスは次のとおりです。

While behaviour required
    Write an integration test for a specific behaviour
    While integration test failing
        Write a unit test to fulfil partial behavior
        While unit test failing
            Write code to make unit test pass
        Commit
        While refactoring can be done
            Refactor
            While unit test failing
                Write code to make unit test pass
            Commit
    Push

免責事項:これが最良のコードと製品につながることは間違いありませんが、時間がかかる可能性があります。統合テストは常に合格しなければならないということになると、データと決定論の周りにあらゆる種類の困難があります。すべての状況に適しているわけではありません。ドアから物を取り出さなければならないこともあります。

とはいえ、理想的なプロセスを念頭に置くことは素晴らしいことです。それはあなたに妥協点を与えます。

50
pdr

実際のプロジェクトでは、ユニットテストを作成してから統合することは不可能であり、反対方向でさえ間違っていることがわかりました。

どうして?両方の種類のテストの見方を書いてみましょう。

  1. 単体テスト-ウィキペディアとすべての既知の情報に加えて、単体テストは設計を絞り込むのに役立ちます、モデル、関係を改善します。フローは単純です。新しいプロジェクト/新しいコンポーネントを入力し始めると、ほとんどの場合、ある種のPoCを作成します。完了すると、常に長いメソッド、長いクラス、一貫性のないメソッドとクラスなどができます。

    単体テストは、上記のモック(他のコンポーネントへの依存なし)クラスを使用して実際の単体テストを行う場合はテストできないため、これらの問題を取り除くのに役立ちます。テストできないコードの基本的な兆候は、多くの依存関係(または状況)をモックする必要があるため、テストの大きなモック部分です。

  2. 統合テスト-新しいコンポーネント(または複数のコンポーネント)が他のコンポーネントと一緒に、または他のコンポーネントと連携して機能することを正しいテストで確認します-これは通常の定義です。統合テストは、主にフローを定義するのに役立つことがわかりました(== --- ==)コンポーネントの使用方法消費者側

    これは、APIが外部からは意味をなさないことを時々言うので、本当に重要です。

まあ、ユニットテストと統合テストを後で書いたらどうなりますか?

私は、Niceクラス、明確なデザイン、優れたコンストラクター、短く一貫したメソッド、IoCの準備などを手に入れました。統合またはGUIチームの開発者である彼は、私のAPIを論理的でなく奇妙なように使用できませんでした。彼はただ混乱していた。だから私は彼の見解に従ってAPIを修復しましたが、メソッドの変更や、場合によってはAPIの使用方法まで変更するように強いられたため、多くのテストを書き直す必要がありました。

さて、統合テストと単体テストを後で書いたらどうなりますか?

正確な流れ、使い勝手は良かったです。また、大きなクラス、一貫性のないコード、ロギングなし、長いメソッドもあります。 スパゲッティコード

私のアドバイスは何ですか?

私は次の流れを学びました:

  1. コードの基本的なスケルトンを開発する
  2. 消費者の観点からそれが理にかなっているかどうかを言う統合テストを書きます。今のところ、基本的なユースケースで十分です。テストは明らかに機能しません。
  3. 各クラスの単体テストとともにコードを記述します。
  4. 残りの統合テストの欠落を記述します。コードをどのように改善しているか、これらのテストを#3内に実装する方が良いでしょう。

ユニット/統合テストについて 小さなプレゼンテーション を作成したことに注意してください。スケルトンが記述されているスライド#21を参照してください。

10
Martin Podval

ユニットテストは、アプリケーション内のソフトウェアのテスト可能な最小ビットをテストし、その機能をテストするために使用されます。各ユニットは、アプリケーションのパーツまたはより大きなコンポーネントに統合する前に個別にテストされます。

それが統合テストの出番です。
彼らは、これらのパーツを組み合わせるときに、以前にテストされたユニットで構成されるこれらの新しく作成されたパーツをテストします。最良のケースは、アプリケーション自体を作成しながら、この時点でテストを作成することです。

5
Ben McDougall

統合テストは単体テストと非常によく似ていると思いがちです。その点で、コードのサブセットをブラックボックスとして扱っています。したがって、統合テストはより大きなボックスにすぎません。

私は量産コードの前にそれらを書くことを好みます。これには、まだ配線していない部分やオブジェクトの相互作用の詳細を少し変更したことを思い出せるという利点があります。

3
Schleis

受け入れテストは別として、私はアプリケーションの境界でのみ統合テストを作成する傾向があり、サードパーティのシステムやコンポーネントとうまく統合できることを確認しています。

アイデアは、サードパーティの発言からアプリケーションが必要とするものに変換するアダプタオブジェクトを作成し、これらのトランスレータを実際の外部システムに対してテストすることです。テストファーストでもテストラストでも、通常の単体テストほど重要ではないと思います。

  • TDDが提供する設計の洞察はここではそれほど重要ではありません。設計は事前によく知られているため、通常、それほど複雑なものは何もないため、システム間でマッピングするだけです。

  • 取り組むモジュール/システムによっては、多くの調査、構成の調整、サンプルデータの準備が必要になる場合があり、時間がかかり、短いTDDフィードバックループにはあまり適合しません。

ただし、少し安全な手順で段階的にアダプターを段階的に構築する方が本当に快適だと感じる場合は、テストから始めることをお勧めします。

このアプローチの例はここにあります: http://davesquared.net/2011/04/dont-mock-types-you-dont-own.html (6番目の段落) http ://blog.8thlight.com/eric-smith/2011/10/27/thats-not-yours.html

2
guillaume31

だから最初の答えを受け入れるつもりでしたが、それは削除されました。
要約すると
所定の反復で:

  1. ユニットテストを書く
  2. 量産コードを書く
  3. 相互作用をテストするための統合テストを作成する

統合レベルでのテスト容易性を保証するために、1と2の間の統合テストを念頭に置いてください。

統合テストは、必ずしもステップ3でエンドツーエンドで記述されるとは限りません。ステップ1と2の間に部分的に記述される場合があります。

2
Chedy2149

単体テストでは、コードの個別のブロックをテストしますwithinプロジェクト。
統合テストは、コードが他のコードとどのようにインターフェースするかをテストします。つまり、コードのinterfaceをテストします。

インターフェースの背後にあるコードを開発するときにユニットテストを記述します。
インターフェイスまたはインターフェイスを実装するコードを開発するときに、統合テストを記述します。

これは、作業の大部分がインターフェースの背後にあるため、プロジェクトの非常に遅い時期に統合テストを作成する場合があることを意味します。たとえば、コンパイラー、ロジックの複数のレイヤーを実装する特定のWebサービス、または..内部ロジック。

ただし、RESTサービスのセットを実装するか、データモデルをリファクタリングしてXAトランザクションのサポートを追加する場合は、ほとんどの場合、統合テストの開発をすぐに開始します。 REST APIであっても、プログラムでのデータモデルの使用方法であっても、作業はインターフェイスを中心に行われます。

0
Marco