オープンソース | AREX: Ctrip の次世代自動回帰テスト ツールの設計と実装

オープンソース | AREX: Ctrip の次世代自動回帰テスト ツールの設計と実装

著者について

Ctrip の R&D エネルギー効率マネージャー兼 SRE である Haibing は、エネルギー効率を改善するための自動テストとツール テクノロジーに重点を置いています。

1. 背景

Ctripの航空券BUの事業規模が拡大するにつれ、事業システムはますます複雑化し、さまざまな問題や課題が生じています。 R&D テスト チームは、ビジネスの複雑さ、データ構築の作業負荷の大きさ、完全な回帰テスト、通信コストの高さ、テスト ケースの数の多さと再利用の難しさ、テスト データの大量メンテナンス、ケース管理の自動化など、さまざまなパフォーマンス上の困難に直面しています。これらはそれぞれ、テストチームの効率と品質に影響を与え、ソフトウェア開発プロセスに課題をもたらします。

要約すると、コストと複雑さという 2 つの主要な困難があります。

コストに関しては、通常、コストと品質の間でトレードオフを行う必要があります。迅速に反復しながら品質を確保する必要があり、限られた投資内で品質を確保する必要があります。

複雑さの点では、ビジネス ルールが一定期間蓄積されると、ビジネス プロセス、ルール、シナリオ、およびデータ処理の複雑さは重ね合わせによって 2 次的または指数的に増加し、品質の高い作業をテストする上で大きな課題となります。

2. 探索:自動回帰テストの探索と実践

これらの課題に対処するために、当社は品質とテストの作業においていくつかの継続的な調査を実施してきました。

1) AUTO テスト プラットフォーム: 従来のプログラム可能なユース ケース設計管理および実行プラットフォーム。

2) 記録と再生テスト: 再生テストには TCP Replay が導入されています。利点は、テスト設計を簡素化できることです。欠点は、期待されるテスト結果がなく、分析結果に注意を払うために人的リソースが必要になることです。

3) テストデータ構築: スクリプトとインターフェースアクセスを組み合わせてデータを生成し、日常的なデータ依存の問題を解決します。ただし、構築の人件費は非常に高く、継続的な投資とメンテナンスが必要です。

4) データ MOCK プラットフォーム: テスト データの問題を解決するために、さまざまなシナリオに合わせて複数の MOCK プラットフォームを構築します。

5) さまざまなカバレッジ プラットフォーム: テストの範囲と作業負荷を測定します。

6) テスト環境を最適化します。継続的なデバッグとテストのニーズを満たすために、ベンチマーク テスト環境とサブ環境を構築します。

さらに、他のテスト フレームワーク、SQL ログ分析、ユニット テスト ケース生成、Chaos 障害ドリル プラットフォームなどでも多くの試みが行われています。

探索中に遭遇した問題

上記の調査により一定の成果は得られましたが、まだ 2 つの問題が残っています。

1)自動テストは自動実行に重点を置いていますが、メンテナンス作業は依然として「手動」であり、出力率はあまり楽観的ではありません。

2)大量のテストデータを構築し、シナリオを記述する必要があり、回帰テストの範囲が広く、リリースが頻繁に行われるシナリオでは、手動テストであれ自動テストであれ、ユースケースやデータのメンテナンスを含め、開発テストは依然として膨大な作業負荷に直面しており、テストの問題点が効果的に解決されていません。

新しい建設目標

そのため、R&D チームは私たちに新しい建設目標を与えました。「品質は向上し、保証されなければなりません。エネルギーは消費されるかもしれませんが、人的資源を無駄にしてはいけません。」

上記の探索経験と新たな目標に基づいて、「実際の本番トラフィックとデータを使用して回帰テストを実施する」というアイデアが生まれました。最終的に、このアイデアを具体的なソリューションに変換して実践し、記録 + 再生 + 比較を組み合わせた自動テスト プラットフォーム AREX を構築しました。これは現在、オープンソースになっています (オープンソース アドレスhttps://github.com/arextest )。

  • 記録: 生成されたリクエストだけでなく、リクエスト処理プロセスに関連するデータも記録されます。
  • 再生: リクエストを再生するだけでなく、関連データをアプリケーションに MOCK します。
  • 比較: テストアサーションを、記録された再生の違いに置き換えます。

3. AREXプラットフォームの紹介

3.1 AREXとは

AREX には、Java エージェントと、フロントエンド、ストレージ、スケジューリング、レポート、データベースなどのサービス コンポーネントが含まれています。全体的なアーキテクチャを下図に示します。

AREX回帰テストロジック

AREX 回帰テストの実装ロジックは、ほぼすべてのビジネス シナリオ要求とデータを運用環境で記録し、これらの実際の要求とデータをテスト環境で再生して、新しいバージョンのアプリケーションに対して包括的かつ迅速な回帰テストを実行することです。

ターゲットシナリオ

  • 頻繁かつ大規模なデータ生成を必要とするテストシナリオ。
  • 多数のビジネス ニーズの回帰テストを必要とするシナリオ。
  • 人的リソースが不足している開発シナリオをテストします。
  • 頻繁なリリースと頻繁な回帰テストを伴うシナリオ。

次に、AREXの仕組みをワークフローの観点から説明します。

下の図は、AREX に接続されていないアプリケーションの呼び出しチェーンを示しています。

写真

AREX に接続すると、次の図が表示されます。上部はトラフィック記録プロセスを示しています。通常の通話処理フローでは、AREX Java エージェントが通話リンク上のデータを傍受し、AREX データベースに保存します。

以下は再生プロセスです。リクエストを再生する場合、サードパーティの依存関係には実際にはアクセスされません。AREX は呼び出しチェーンを切断し、エージェントはデータベースから以前に収集したデータを読み取り、呼び出し元に返します。

AREX 再生テスト ケースが実行されると、AREX は比較 SDK を呼び出して比較を実行し、差異の結果を出力して、テスト レポートを生成します。

4. AREXテクノロジーの実装と最適化

交通記録・再生の概念はすでに当たり前になっていますが、実際に実装するのはそう簡単ではなく、解決すべき問題も多くあります。以下では、AREX プラットフォームを実装する際に私たちのチームが遭遇した技術的な問題と、その問題をどのように解決したかについて詳しく説明します。

4.1 AREXジェントの録音と再生の原理

以下は、AREX Agent の録音と再生の原理を説明するための簡単な機能です。

左側が変換前の関数、右側が変換後の関数です。

機能エントリー時に再生判定を行います。再生が必要な場合は、収集したデータを戻り値、つまり Mock として使用します。

関数終了部で記録判定を行い、記録が必要な場合にはアプリケーションが保存する必要のある中間データをAREXデータベースに保存します。

依存パッケージ注入の原理は非常にシンプルです。

4.2 AREXの技術的課題

AREX エージェント テクノロジー スタック

パフォーマンスが優れており、コードが読みやすく理解しやすいため、バイトコードの変更を実装するために ByteBuddy ライブラリを採用しました。

また、Javaが提供する拡張APIのセットであるSPI(Service Provider Interface)を使用します。これを使用することで、フレームワークの拡張やコンポーネントの置き換えが可能になります。私たちの注入コンポーネントは、このプラグイン モードを通じて実装されます。

TRACINGの実装

AREX の記録機能では、リクエスト、レスポンス、サードパーティのリクエスト レスポンスを記録する必要があり、これらのデータを連結してテスト ケースとして完全に使用できるようにするための一意のキーが必要です。このキーが AREX のレコード ID です。

次のクラスは AREX の呼び出しチェーンを実装します。つまり、呼び出しチェーンの入り口で、エージェントは一意のレコード ID を生成し、それをスレッド ローカル変数に保存します。アプリケーションの関数ヘッダーと末尾にエージェント コードを挿入します。このコードは、スレッド ローカル変数の値を読み取り、インターセプトされたデータと一緒に保存します。

コールチェーンの損失を解決する

上記は、AREX TRACING 伝送実装におけるより一般的な基本シナリオです。さらに、当社のアプリケーションには、マルチスレッド、非同期、その他のテクノロジを使用するシナリオも多数あります。このようなシナリオでは、呼び出しチェーンが失われ、データのシリアル接続に大きな困難が生じます。

呼び出しチェーンの損失の問題を解決するために、Runnable、Callable、ForkJoinTask、および Async Client クラスのカプセル化を実装しました。

基本的な原理は、元のコードを、マルチスレッド コードが呼び出されるカプセル化されたクラスに置き換え、カプセル化されたクラス内の元の機能を保持し、AREX のデータ読み取りおよび書き込み機能を実現することです。

ヒント: Wrapper はキーワードです。コード ベースで Wrapper を検索すると、すべての AREX ラッパー クラスの実装が表示されます。

録音と再生のインジェクションの実装

以下は、録音と再生を実装するためのコード例です。

 @Override public List<MethodInstrumentation> methodAdvices() { ElementMatcher<MethodDescription> matcher = named("doFilter") .and(takesArgument(0, named("javax.servlet.ServletRequest"))) .and(takesArgument(1, named("javax.servlet.ServletResponse"))); return Collections.singletonList(new MethodInstrumentation(matcher, FilterAdvice.class.getName())); }

新しい依存関係ライブラリを挿入する必要がある場合、このプラグインをどのように実装すればよいでしょうか?

まず、次の 3 つの要素を通じて、注入された関数を特定します。

  • モジュール (ModuleInstrumentation: FilterModuleInstrumentationV3): 論理管理の概念は、複数の注入クラスまたはカプセル化クラスを 1 つのモジュールに配置することです。
  • タイプ (TypeInstrumentation: FilterInstrumentationV3): これは、検索する注入されたオブジェクトのクラス、つまり、注入されたアプリケーション クラスです。
  • 関数 (MethodInstrumentation): この関数は、注入および変更する関数を特定します。

上記の例のように、注入するクラスは CacheAspectSupport クラス、そのクラスが含まれるモジュールは CacheModuleInstrumention モジュール、注入および変更する関数は doFilter 関数です。

次に、3 つのステップで関数インジェクション コードを実装します。以下は、AREX エージェントがコード インジェクションを実装する方法をより直感的に確認するための Mybatis Query() 関数です。

ステップ 1: METHOD_NAME_Query (文字列 "Query") という名前の関数を、インジェクション機能を実装するクラスである QueryAdvice クラスに関連付けます。

ステップ 2: QueryAdvice クラスは OnMethodEnter() 関数を実装し、ByteBuddy アノテーションを付けます。

ステップ 3: QueryAdvice クラスが Query 関数の先頭と末尾に挿入されます。

再生が必要な場合は、照会されたデータがローカル変数に保存されます。再生が不要な場合は、実行が続行されます。

以下は、終了前に Query 関数に挿入されたコードです。

  • MOCK 結果が条件を満たす場合、MOCK データが返されます。
  • 現在の状態が記録中の場合、クエリ SQL + クエリ結果の生データが AREX データベースに保存されます。

バージョン管理の実装

人気のあるコンポーネントには、異なるシステムで同時に使用される複数のバージョンが存在することがよくあります。異なるバージョンの実装方法は大きく異なる場合があり、互換性がない場合もあります。

この問題に対処するために、AREX は複数のバージョンとの互換性を実現しました。アプリケーションが起動すると、AREX エージェントは JAR パッケージの Manifest.MF ファイルなど、すべての依存パッケージの情報を取得し、マニフェストからクラス ライブラリのバージョン情報を取得し、バージョン情報に応じて対応する AREX インジェクション コードを起動することで、複数のバージョンとの互換性を実現します。

下の図に示すように、現在のインジェクション スクリプトが適応されるバージョン範囲が設定されているため、AREX はこれらのクラスがロードされる前にアプリケーションが依存するコンポーネント バージョンを識別し、クラスがロードされるときにバージョンを一致させて、正しいコード インジェクションを確実に行うことができます。

コード分​​離の実装

AREX の使用シナリオのほとんどは、本番環境で録音し、テスト環境で再生することであるため、安定性が非常に重要です。システムの安定性を確保し、エージェント コードがテスト対象アプリケーションのコード実行に影響を与えないようにするために、AREX はコードの分離と相互通信を実装します。

AREX コア JAR は別の ClassLoader にロードされ、ユーザーのアプリケーション コードとは通信しません。実行時に挿入されたコードに正しくアクセスできるようにするには、次の図に示すように、ClassLoader を変更するだけです。

時間問題を解決する

Ctrip のビジネス シナリオの多くは時間に敏感です。再生中に記録された時間が経過し、ビジネス ロジックを続行できず、再生が失敗することがよくあります。

オリジナルの Java currentTimeMillis() 呼び出しをプロキシするために、独自の currentTimeMillis() を使用します。記録時のシーンに応じて時間の記録と再生が実行され、時間のモックが実現されます。

このシナリオは、AREX エージェント #182 で詳しく説明されています。

キャッシュ問題の解決

実際のアプリケーションでは、実行時のパフォーマンスを向上させるためにさまざまなキャッシュが使用されています。キャッシュされたデータの違いによって生じる実行結果の不一致は、記録や再生において大きな問題となります。

AREX は、動的クラス モックの機能を提供します。実装方法は、ローカル キャッシュにアクセスするメソッドを動的クラスに構成することです。これは、このメソッドをモック用にカスタマイズすることと同じです。本番環境で構成した動的クラス メソッドのデータを記録し、対応する一致するデータを再生します。

もちろん、このアプローチにも欠点があります。

  • キャッシュ構成は見落とされやすく、再生パス率に大きな影響を与えます。
  • 各アプリケーションには独自のキャッシュ実装があり、事前に処理することはできず、手動による参加と構成コストが必要になります。

4.3 AREXのその他の利点

インターフェーステストの作成をサポート

システム変更後の業務の正しさを検証するには、単に返却結果を確認するだけでは十分ではなく、業務システムがデータベースに書き込んだデータ内容が正しいかなど、中間処理データの正しさを検証する必要があるのが通常です。

これを考慮して、AREX はインターフェース テストの作成にも完璧なサポートを提供します。

記録および再生プロセス中に、AREX はシステムの新バージョンと旧バージョンの外部データベース要求を記録し、2 つの要求を比較します。違いがある場合は、再生レポートに表示されます。

AREX はサードパーティの依存関係のすべてのリクエストを MOCK するため、データベース、メッセージ キュー、Redis データの検証をサポートし、ランタイム メモリ データの検証もサポートします。さらに、再生中にデータベースへの実際の呼び出しは行われないため、ダーティ データは生成されません。

生産上の問題の迅速な特定

実際の使用では、AREX は生産上の問題を迅速に特定するためにも使用できます。

運用中に問題が発生した場合、バージョンの違い、データの違いなどにより、開発者がローカルで問題を再現することが困難です。デバッグには多大なコストと時間がかかり、手間がかかります。

AREX を使用すると、問題のあるケースを本番環境で強制的に記録し (応答メッセージに一意のレコード ID が生成されます)、ローカル開発環境を起動して、送信されたリクエストのメッセージ ヘッダーにこのレコード ID を追加し、記録されたリクエストとデータをローカルで復元し、ローカル コードを使用して本番環境の問題を直接デバッグすることができます。

5. AREX自動テストの実装と展望

5.1 CtripにおけるAREXプロモーションの効果

各 BU が AREX に接続された後は、ツールや構成に慣れるための初期の学習コストを除いて、自動化されたユースケース開発、データ MOCK、データ構築におけるテスト開発者の作業負荷が大幅に軽減され、好循環が形成され、テストの見逃しが減り、カバレッジが拡大し、製品の品質が効果的に向上します。

この効果は、次の 2 つのシナリオで最も顕著になります。

  • 技術的なリファクタリング プロジェクト、特に要求応答が変更されないシナリオ。この使用シナリオでは、テスターが参加する必要はほとんどなく、開発者は AREX を使用して迅速なセルフテストを実行し、品質を確保できます。
  • 開発者は自己テストの品質を向上させます。

5.2 AREX最適化

Ctrip 内での AREX の初期試用段階では、全員がこのツールに非常に良い評価を与えました。しかし、使用範囲が拡大すると、特に他のチームが積極的に接続されていない場合には、さまざまな問題が発生します。

  • 誤報率が高く (時間、UUID、シリアル番号など)、早期の比較およびフィルタリング構成が多数あります。
  • コード変更の予想される確認は面倒であり、多くの手動介入が必要になります。

現在、AREX の構成と比較機能の最適化に注力しています。

構成の強化

現時点では、高いマッチング合格率を確保するには多くの手動介入(マッチングでは構成を無視するなど)が必要であるため、まず最初に行うべきことはユーザー構成コストを削減することです。

  • 違いを視覚的に表示する
  • 手動ラベル付けにより使いやすさが向上
  • 構成の更新は再計算され、再実行される可能性がある

類似の集約

同じタイプのエラーを複数の次元で集約することで、開発者は違いを観察しやすくなります。最終的には、ほとんどの場合、開発者は 1 つの違いを確認するだけで、比較の違いのほとんどを排除できます。

アルゴリズムによるノイズ低減

1) 事前解析ノイズ低減

事前分析のノイズ低減とは、記録されたトラフィックの実稼働バージョンをテスト環境にリリースし、このバージョンを再生して違いを比較し、トークンやシリアル番号などの「ノイズ」ポイントを事前に特定することです。

次に、ノイズは知識ベースとしてルール ベースにラベル付けされます。

最後に、メッセージとデータのスキーマ変更が識別され、アクティブなノイズ削減が実行され、ユーザーによる手動構成のコストが削減されます。

2) 比較知識ベース

比較はAREXの中核機能ですが、現在の比較は比較的粗く、誤検出率も高くなっています。反復テストでの比較知識の蓄積(人間の介入なし)を増やし、比較知識ベースを形成し、ユーザーが有効な違いを正確に識別できるようにしたいと考えています。たとえば、スキーマ定義を有効な比較ルールに変換します。

正確なテスト

精密テストはテストの範囲を絞り込むことです。精密テストは将来的にAREXでも導入される予定です。主な目的は比較の違いの原因を明確に特定することです。

コード変更、コード実行リンク、AREX 再生をリンクし、コード変更と差分結果を双方向にトレースすることで、ユーザーが問題を「観察可能に」確認できるようにする予定です。まず、コードの更新によって生じる想定される差異かどうかを識別し、さらに予期しない問題の差異点を積極的にフィルタリングして特定します。

差異結果を比較して最適化することで、R&D構成コストを効果的に削減し、差異結果の精度を向上させることができます。これがAREXの自動回帰テストの真の価値です。

6. 最後に

AREX は継続的な最適化を経て、実際のトラフィックとデータを使用した回帰テストの目標を徐々に達成し、コストを削減し、品質を向上させ、構築の初期段階で設定された目標を達成しました。

もちろん、アルゴリズム、パフォーマンス、サポート範囲など、最適化と改善が必要な領域はまだ多くあり、さらなる最適化と開発が必要です。また、高い理想を持つすべての人々が、AREX オープンソース プロジェクトの共同構築に参加できることを願っています。

<<:  多言語自然言語処理 (NLP) で言語の壁を打ち破ります!

>>:  リチウム電池の防爆結果がネイチャー誌の表紙に登場、UCLAの中国チームが制作

ブログ    
ブログ    
ブログ    

推薦する

...

...

...

CMU のポスドクらが NLP データ処理ツールを発表

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

Googleはプライバシーポリシーを更新し、インターネット上の公開データをAIの訓練に利用していることを明確にした。

7月6日、Googleはプライバシーポリシーを更新し、BardやCloud AIなどのさまざまな人...

10000000000!マイクロソフトはTransformerを改良し、一度に多くのトークンを記憶できるようにした

Microsoft Research Asia の最新の調査は少々衝撃的だ。彼らは、実際にトークンを...

AI は無限であり、あなたの声によって動かされます。マイクロソフトは慈善団体や業界のパートナーと協力し、テクノロジーで愛を育むお手伝いをします。

12月2日、マイクロソフトと周迅のAI音声紅丹丹慈善プロジェクトの発起人である魯音源文化伝承社は、...

...

Cacti パーセンタイル監視アルゴリズム

Cactiパーセンテージ監視アルゴリズムの具体的な方法は次のとおりです。 cacti のテンプレート...

Python が Java や C/C++ に勝って機械学習に最適な言語である理由!

Python は、1989 年にオランダ人の Guido van Rossum によって発明され、...

...

...

AIアプリケーションのための実用的なフレームワークを構築するための5つのステップ

[51CTO.com クイック翻訳] ガートナーの調査によると、約 37% の組織が何らかの形で人工...

AI は「彼ら」による盗聴を防ぐことができますか?

次のような状況に遭遇したことがあるかもしれません:携帯電話でアプリを開くと、最初に表示されるのは数分...

Python で線形回帰機械学習モデルを作成する方法は? 「初心者ガイド」

線形回帰とロジスティック回帰は、現在人気のある 2 つの機械学習モデルです。 [[331887]]こ...