結合テストの概念
統合テストに関しては、テスト エンジニアなら誰でもよく知っていると思いますが、新しい概念ではありません。従来のソフトウェア テストにおけるその意味は、Wikipedia の定義から知ることができます。
統合テスト (統合およびテスト、略して I&T とも呼ばれます) は、個々のソフトウェア モジュールを組み合わせてグループとしてテストするソフトウェア テストのフェーズです。統合テストは、システムまたはコンポーネントが指定された機能要件に準拠しているかどうかを評価するために実施されます。
つまり、統合テスト (略して統合およびテスト、または I&T とも呼ばれます) は、システムまたはコンポーネントが指定された機能要件に準拠しているかどうかを評価するために、個別に開発されたソフトウェア モジュールを組み合わせて全体としてテストするソフトウェア テストの段階です。 。
マイクロサービス アーキテクチャでは統合テストも必要であり、異なるサービスの異なるメソッド間の通信に関連するテストを実行する必要があります。マイクロサービスを単体テストする場合、単体テスト ケースではテスト対象のユニットの内部ロジックのみが検証され、依存するモジュールは検証されないためです。サービス A とサービス B の単体テストが別々に合格したとしても、サービス A とサービス B の間の相互作用が正常であることを意味するわけではありません。
マイクロサービス アーキテクチャの場合、統合テストは通常、データ ストアや他のマイクロサービスなどの外部コンポーネントと通信するサブシステムまたはモジュールの検証に焦点を当てます。目的は、これらのサブシステムまたはモジュールが外部コンポーネントと適切に通信できることを検証することであり、外部コンポーネントが正しく動作することをテストすることではありません。したがって、マイクロサービス アーキテクチャでの統合テストでは、統合対象のサブシステムと外部コンポーネント間の基本的な通信パス (正しいパスと間違ったパスを含む) を検証する必要があります。
マイクロサービスアーキテクチャでの統合テスト
上の図に示すように、ゲートウェイ コンポーネント層 (ゲートウェイ+HTTP クライアント+外部サービス) には、システム内の別のマイクロサービスまたは外部サービスに接続する、通常 HTTP/S クライアントを含む外部サービスにアクセスするためのロジックが含まれています。データ永続層 (日付マッパー/ORM) は、外部データ ストアに接続するために使用されます。
つまり、マイクロサービス アーキテクチャでの統合テストは主に次の 2 つの部分で構成されます。
ゲートウェイ コンポーネント層、マイクロサービス コンポーネントと外部サービス間の通信パス。
データ永続層、データベース アクセス モジュールと外部データベース間の対話。
ここで注意していただきたいのは、マイクロサービス配下のサブシステム間の通信や外部サービスの通信が正しいかテストする必要があるため、外部コンポーネントにはテストダブル(Test Double)を使用しないのが理想的です。
これら 2 つの部分がどのように統合され、1 つずつテストされるかを見てみましょう。
(1) ゲートウェイコンポーネント層の統合テスト
現在時刻を知る必要があるログイン サービスがあり、その時刻が外部タイム サービスによって提供されているとします。/api/json/cet/now に対して GET リクエストを行うと、ステータス コードは 200 となり、次のように完全な時間情報が返されます。
{
$id: "1",
currentDateTime: "2020-07-29T02:11+02:00",
utcOffset: "02:00:00",
isDayLightSavingsTime: true,
dayOfTheWeek: "Wednesday",
timeZoneName: "Central Europe Standard Time",
currentFileTime: 132404622740972830,
ordinalDate: "2020-211",
serviceResponse: null,
}
/api/json111/cet/now に GET リクエストを送信した場合など、アクセスした URL が間違っている場合、ステータスコードは 404 となり、以下のエラーメッセージが返されます。
一般に、統合テストは、外部サービスへの接続と、HTTP ヘッダーの欠落、SSL 処理の例外、要求/応答の不一致などの対話プロトコルに関連する問題を検証する責任があります。すべてのエラー処理ロジックをテストでカバーし、使用されるサービスとプロトコル クライアントが特殊な場合に期待どおりに応答することを確認する必要があります。
(2) データ永続層統合テスト
データ永続層の統合テストは、結果がストレージ システムに保存されて永続化され、各テストの実行がデータの変更により後続のテストの実行に影響を与える可能性があるため、より複雑になります。これは、2 つのテストが共通のデータを操作するため、完全に独立していないことを意味します。
ほとんどの場合、2 つのテスト間の外部要因も互いに独立していることを確認する必要があります。なぜなら、こうしたエラー(テストデータの改ざんによるテスト実行の失敗)は、発生してから気づくことが困難なことが多く、調査の進行に影響を与えることになるからです。
2 つのテストの独立性を確保するために、永続層統合テストの共通の手順は次のとおりです。
-
テストを実行する前に、データベースを既知の予測可能な状態にロールバックします。これには、データベースに対する以前の変更をクリーンアップ/ロールバックする必要があります。
-
テストに必要な既知のデータを挿入してデータベースを再構築します。
-
関連するテストを実施する。
-
上記のプロセスを繰り返します。
よくある問題と解決策
ただし、外部サービスが利用できない場合 (サービスがまだ開発されていない、またはサービスに修正されていないブロックレベルの欠陥がある)、またはその異常な動作 (外部コンポーネントのタイムアウト、応答の遅さ、など)検証が困難です。外部コンポーネントでテストダブルが使えない、外部サービスが利用できない、異常なシナリオの構築が難しいなど、解決策がないように見えますが、実は代替手段はあります。
サービスは利用できません
サービスが利用できない状況では、マイクロサービス仮想化テクノロジがこの問題を完全に解決できます。これは、特に多数の依存関係があるエンタープライズ環境で作業している場合に、他のサービスと通信するときの予期せぬ事態を避けるために必要なツールです。これは、テスト段階でサードパーティのサービスへの依存関係を削除し、遅延やその他のネットワークの問題が発生したときにアプリケーションがどのように動作するかをテストするために使用できます。プロキシ サービスを作成することで依存サービスのシミュレーションを実現します。これは、サービス間の通信をテストするのに特に適しています。一般的なツールには、Wiremock、Hoverfly、Mountebank などが含まれます。
Wiremock を例にとると、次のコードの効果は次のとおりです。相対 URL が /api/json/cet/now と完全に一致すると、ステータス 200 が返され、応答本文は /api の戻り値と同様になります。 /json/cet/now、Content- タイプヘッダーの値は text/plain です。そうしないと、/api/json111/cet/now にアクセスするなど、相対 URL が間違っている場合に 404 エラーが返されます。
@Test
public void exactUrlOnly() {
stubFor(get(urlEqualTo("/api/json/cet/now"))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withBody(equalToJson("{
$id: \"1\",
currentDateTime: \"2020-07-29T02:11+02:00\",
utcOffset: \"02:00:00\",
isDayLightSavingsTime: true,
dayOfTheWeek: \"Wednesday\",
timeZoneName: \"Central Europe Standard Time\",
currentFileTime: 132404622740972830,
ordinalDate: \"2020-211\",
serviceResponse: null,
}"))));
assertThat(testClient.get("/api/json/cet/now").statusCode(), is(200));
assertThat(testClient.get("/api/json111/cet/now").statusCode(), is(404));
}
サービスのタイムアウトと応答の遅さの構築が困難
実際のサービステストを使用する場合、サービスのタイムアウトや応答の遅さなど特別な構築が必要な場合は、Fiddler、Dummynet、Clumsy などのさまざまなツールを使用する方が便利です。
Wiremock は、withFixedDelay() を使用して固定遅延効果を実現するなど、遅延関数もサポートしています。
stubFor(get(urlEqualTo("/api/json/cet/now")).willReturn(
aResponse()
.withStatus(200)
.withFixedDelay(2000)));
withLogNormalRandomDelay() を使用して、ランダムな遅延効果を実現します。
stubFor(get(urlEqualTo("/api/json/cet/now")).willReturn(
aResponse()
.withStatus(200)
.withLogNormalRandomDelay(90, 0.1)));
データの初期化と構築に費用がかかる
データ永続化層の結合テストは上記の方法が一般的ですが、データベースを初期化するために大量のサンプルコードを記述する必要があり、また、期待されるデータを挿入するために大量のデータベース操作文を記述する必要があります。データ。この問題に直面した場合、テスト エクスペリエンスを向上させるために、既製の永続性テスト フレームワークを使用できます。一般的な永続性テスト フレームワークには、NoSQLUnit、DBUnit などが含まれます。
DBUnit の設計コンセプトは、テスト前にデータベースをバックアップし、準備が必要なデータをオブジェクト データベースに埋め込み、テスト終了後にバックアップしたデータベースを読み込んでテスト前の状態に初期化することです。DBUnit は、テスト ケースのライフ サイクル中にデータベースの操作結果を比較できます。DBUnit でサポートされるデータベースには、db2、h2、mssql、mysql、orace、postgresql などが含まれます。
NoSQLUnit は、NoSQL データベースのテストを作成するための DBUnit に似た方法です。HBase、MongoDB、Redis、ElasticSearch、Vault、Neo4j など、さまざまな NoSQL データベースをサポートします。
要約する
このレッスンでは、マイクロサービス アーキテクチャでの統合テストの定義を説明した後、マイクロサービスでの統合テストの 2 つの側面、ゲートウェイ コンポーネント層の統合テストとデータ永続層の統合テストについて説明します。
ゲートウェイコンポーネント層の結合テストでは、サービス仮想化技術により外部サービス機能のシミュレーションを実現し、ネットワーク異常をシミュレーションすることで外部サービスのタイムアウトや応答遅延の状況を構築します。
データ永続層統合テストでは、永続テスト フレームワークにより、従来の永続テストでの大量のコードや大量の SQL ステートメントの記述を回避できます。
もちろん、上記のフレームワークやツールの威力はこれに限定されるものではなく、この記事では主要な例の情報のみが提供されており、ニーズや興味に応じて自分で調べて学習することができます。
最後に、私の記事を注意深く読んでくださった皆さんに感謝します。互恵性は常に必要です。それはそれほど価値のあるものではありませんが、必要な場合はそれを取り上げることができます。
ソフトウェアテストインタビューアプレット
ソフトウェア テストの質問バンクには、何百万人もの人が参加しました。!!誰が知っているのか!!!ネットワーク全体で最も包括的なクイズ ミニ プログラムです。携帯電話を使用して、地下鉄やバスの中でもクイズに答えることができます。
次の面接の質問セクションが取り上げられます。
1. ソフトウェアテストの基礎理論、2. Web、アプリ、インターフェース機能テスト、3. ネットワーク、4. データベース、5. Linux
6. Web、アプリ、インターフェイスの自動化、7. パフォーマンス テスト、8. プログラミングの基本、9. 時間面接の質問、10. 公開テストの質問、11. セキュリティ テスト、12. コンピューターの基本
これらの資料は、[ソフトウェア テスト] の友人にとって最も包括的で完全な準備倉庫となるはずです。この倉庫は、最も困難な旅を乗り越える何万人ものテスト エンジニアにも同行してきました。あなたにも役立つことを願っています。