Java + Rest-Assuredバックエンドテストプラクティス

前回の記事で、ロボットフレームワークでの自動化の経験を共有しました。 次に、KotlinのプロジェクトのAPIをテストするためのわずかに異なるアプローチについて説明します。



テクノロジースタックを選択する自由を利用し、「バトルで」新しいことを試してみたいという願望に頼って、Rest-Assuredに頼りました。 多少の困難がなければ、同僚と私はテストを開始し、アプローチをマスターした結果、この種のタスクの主要タスクのリストに記録しました。



画像






(パロディとして使用される画像)



それはすべて、Ad-techセグメントの新しいプロジェクトの1つでテストAPIを自動化する要求があったという事実から始まりました。 キャンペーンマネージャー、DMP、およびサードパーティシステムとのいくつかの統合を行いました。 また、テスターに​​は非常に簡単なタスクがありました。CIへのさらなる統合のためにスモークテストを自動化し、サードパーティシステムが関連付けられており、適切な操作が不可欠であるため、このAPIの状態を常に監視します。 テストされたサービスは本質的にプロキシインターフェイスであるため、この場合のビジネスロジックの検証は必要ありません。



安心の理由



テスト自動化の観点から、UI、Web、モバイル、デスクトップ、バックエンド、REST API、SOAPなどのさまざまな分野で作業することができました。 前のプロジェクトでは、ロボットフレームワークに関する非常に多くの経験があったため、それを使用するのが最も論理的でした。 ほとんどのテストチームは彼に精通しており、専門家の緊急の交換が必要な場合、これは迅速かつ事実上痛みなしに行われます。 しかし、別の決定が下されました。



まず、プロジェクト自体はKotlinで記述され、Gradleを使用して構築されました。 同時に、設計段階で、自動テストでは別のプロジェクトを割り当てないことが決定されました。 前の記事のコメントで述べたように、Java(Kotlin)とRobot Frameworkを結び付けることは大きな苦痛なので、RFに言及する意味はありませんでした。 さらに、ロボットでの作業を振り返って、別のアプローチを試すことに興味がありました。 さらに、このプロジェクトでは、テクノロジーのスタックを個別に選択できました。ビジネスは独自の条件を設定しませんでした。



アイデアを求めて、私は開発チームとテストの同僚に目を向け、CTOはRest-Assured( rest-assured.io )を調べるようアドバイスしました。 オープンソースのドキュメントとテスト例を読んだ後、Rest-Assuredによって提案されたアプローチは私にとって非常に魅力的でした。 JSONの形式でバックエンドから応答を受信することを意味します。JSONを古き良きJavaオブジェクトにデシリアライズします。



さらに、この構造を使用すると、通常のオブジェクトと同様に作業できます。 その結果、記述されたオブジェクト構造へのAPI応答の対応を検証するための完全に通常のオブジェクト指向のアプローチがあります。 ボーナスとして、応答構造の迅速なフェイルプルーフテストを取得します-API応答を逆シリアル化して受信したオブジェクトのフィールド数または名前が異なる場合、逆シリアル化エラーのあるデータをチェックする前にテストが終了します。 そのため、APIの新しい要件に従ってバックエンドの修復またはテストの更新が必要かどうかを理解します。 前述のように、多くのサードパーティサブシステムがAPIに関連付けられているため、この場合、これは重要でした。



正確さのために、RFでほぼ同じフェイルプルーフテストを取得できますが、わずかに異なる方法で取得できることに注意してください。 しかし、今日の話はそれについてではありません。 個人的には、特定のフィールドとメソッドを持つエンティティを使用して、Rest-Assuredの側から入力する方が便利で理解しやすいものでした。



フェザーテスト



実際のプロジェクトでスタックの使用を開始する前に、小さなCRUDサービスで試してみることにしました。 彼自身の間違いをすぐに練習しないように、私はこのスタックでベストプラクティスを検索することにし、Philip Hauerの記事をすぐに見つけまし 。彼はRest-Assuredで彼の自動化の経験を反映しました。 記事を読んだ後、私のサービスのテストの実際のバージョンを書くことは難しくありませんでした。 彼らは、シンプルで読みやすく、理解しやすいことがわかりました。



戦いに!



プロジェクトが開始され、最初の応答構造が記述されると、テストドキュメントの準備と自動テストの作成が開始されました。 全体像を理解するために、自動テストの完全なスタックを提供します。





最初のテストが書かれたとき、適切なパラメーター化の問題が明らかになりました。 データの単純な値と期待される結果を転送することは、非常に非効率的でandいように思われました。 私は休暇前にこの問題を解決する時間がありませんでしたが、不在中に関与していた同僚がそれを整理しました。 美しく読みやすいパラメーター化のために、彼らはオブジェクトパラメーターを追加、受信、削除する機能を持つ基本クラスを作成することを決定しました。そこから、対応するAPIメソッドの呼び出しにオブジェクトが使用されたすべてのクラスが継承されました。



画像



これにより、文字通りその場で必要なデータを作成し、テストパラメーターで送信することができました。



画像



Rest-Assuredを使用すると、必要なクラスへの応答を逆シリアル化できます。 結果の答えは、Jacksonを使用して既知の構造に分解されます。 逆シリアル化のクラスは可能な限りシンプルに見えます-期待されるすべてのフィールドとそのタイプが記述されています。



画像



さらに、オブジェクトの単純な作業と特定のフィールドとその値のアサーションが継続されます。

このアプローチで偶然に遭遇した最も困難で非自明なことは、パラメーターの1つとしてnullをRest-Assuredに渡すことができないことです(結果はNullPointerExceptionのドロップです)。 どうやら、これは既知の問題ですが、開発者は状況を修正せず、フィールドを空にするか、まったく送信しないことを推奨しています。 この問題は、プロジェクトの基礎が整い、テストクラスを追加するためだけに残っていた段階で既に直面していました。 したがって、コードをわずかに修正しました。



一般的に、私はアプローチが好きでした。 しばらくして、別の顧客のプロジェクトに適用され始めたのは不思議です(ただし、私たちの供給からではありません)。 そして、自動化テストAPI(JUnit + AssertJ + Rest-Assured)のアセンブルされたスタックを、Java / Kotlinプロジェクトの主要なもののカテゴリーに入れました。 Pythonでは、開発とテストのコンピテンシーが重複している方が良いため、これを引っ張ると直観に反します。



また、このソリューションの利点の1つは、拡張性と複雑なロジックへの適応性であることに注意してください。 これは、読み取り可能な形式でデータを準備、送信、受信し、その後のコンプライアンスのためのデータの検証を担当する個別の部分がある場合、大きなオブジェクト、クリーンコード、ブロックアーキテクチャを記述することが本当に意味のある深刻なプロジェクトに最適であることを意味しますいくつかの条件。 小さなプロジェクトでは、これはすべてプルする意味がありません。



まとめ



約1か月で、約250のテストを自動化し、必要なレベルのカバレッジを提供することができました。 もちろん、自動化プロセスの終了後、従業員が完了した作業のアイデアを持ち、このプロジェクトで得た経験から学ぶことができるように、全員に対して内部プレゼンテーションが行われました。



記事の著者:Dmitry Masters



PS Runetのいくつかのサイトで記事を公開しています。 VKFB、または電報チャネルのページを購読して、すべての出版物およびその他のMaxilectニュースについて学びます。



All Articles