View a markdown version of this page

サーバーレスアプリケーションをテストするためのベストプラクティス - AWS 規範ガイダンス

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

サーバーレスアプリケーションをテストするためのベストプラクティス

以下のセクションでは、サーバーレスアプリケーションをテストする際に効果的なテストカバレッジを達成するための、ベストプラクティスの概要を説明します。

クラウドでのテストを優先する

優れた設計を持つアプリケーションでは、幅広い要件や条件を満たすさまざまなテスト方法を使用できます。ただし、現行のツールに基づく場合、可能な限りクラウドでのテストに重点をおくことが推奨されます。クラウドでのテストは、デベロッパーの待ち時間が多く、コストがかかり、DevOps の制御に追加の投資が必要になることがありますが、信頼性や精度は最も高く、すべてを網羅したテストカバレッジを達成できます。

テストを実行するユーザーは、隔離された環境にアクセスできる必要があります。理想的には、各デベロッパーには、同じコードで作業している複数のデベロッパーが、同じ名前のリソースに対して API コールをデプロイまたは呼び出そうとしたときに発生する可能性のあるリソース命名に関する問題を回避 AWS アカウント するための専用の が必要です。こうした環境では、不要な支出を避けるため、適切なアラートやコントロールを設定する必要があります。例えば、作成できるリソースのタイプ、階層、またはサイズを制限したり、推定コストが特定のしきい値を超えたときにメールアラートを送信したりすることができます。

1 つの を AWS アカウント 他の開発者と共有する必要がある場合、自動テストプロセスでは、開発者ごとに一意のリソースに名前を付ける必要があります。たとえば、CLI sam デプロイコマンドまたは sam 同期コマンドを引き起こす更新スクリプトまたは TOML AWS SAM 設定ファイルでは、ローカル開発者のユーザー名を含むスタック名を自動的に指定できます。

クラウドでのテストは、ユニットテスト、統合テスト、エンドツーエンドテストなど、テストのあらゆる段階で役立ちます。

必要に応じてモックを使用

モックフレームワークは、高速なユニットテストを記述するための有用なツールです。特に、数値の計算や財務計算、あるいはシミュレーションなど、社内の複雑なビジネスロジックをテスト対象とする場合にとても役立ちます。テストケースや入力の変動が多く、それらの入力によって他のクラウドサービスへの呼び出しのパターンや呼び出しの内容が変化しないユニットテストが想定されています。このようなシナリオのモックテストを作成すると、デベロッパーの反復作業に要する時間を短縮することができます。

モックテストを使用しているユニットテストで対象とするコードは、クラウドでのテストでも対象に含める必要があります。これは、モックがまだデベロッパーのラップトップまたはビルドマシンで実行されており、環境がクラウドとは異なる設定になっている可能性があるために必要です。例えば、コードには、特定の入力パラメータで実行されるときに Lambda が割り当てるように設定されたよりも多くのメモリを使用する関数や時間がかかる AWS Lambda 関数が含まれる場合があります。または、コードに、同じ方法 (またはまったく) で設定されていない環境変数が含まれている場合があり、その違いによってコードの動作や障害が発生する可能性があります。

クラウドサービスのモックを使用して、それらのサービス統合の適切な実装を検証しないでください。他の機能をテストする場合は、クラウドサービスをモックしても問題ありませんが、クラウドでクラウドサービスの呼び出しをテストして、正しい設定と機能実装を検証する必要があります。

特に多数のケースを頻繁にテストする場合、モックはユニットテストに価値を追加することができます。この利点は統合テストでは低減します。接続ポイントの数が増えるほど、必要なモックを実装するための手間が増えるためです。エンドツーエンドのテストではモックを使うべきではありません。これらのテストは一般にモックフレームワークでは簡単にシミュレートできない状態や複雑なロジックを扱うためです。

エミュレーションテストのトレードオフを理解する

エミュレータは、特定のユースケースで実用的な選択肢です。たとえば、インターネットアクセスが制限されている、一貫性がない、または遅い開発チームは、エミュレーションテストがクラウド環境に移行する前にコードで反復する最も信頼性の高い方法であると判断する場合があります。

他のほとんどの状況では、エミュレータを選択的に使用します。エミュレータに大きく依存している場合、エミュレーションベンダーが機能パリティを提供するために更新をリリースするまで、テストに新しい AWS サービス機能を組み込むことが難しくなる可能性があります。エミュレータには、開発システムおよびビルドマシン全体のセットアップと設定のための事前投資と継続的な投資も必要です。さらに、多くのクラウドサービスにはエミュレータがありません。エミュレーションファースト戦略を選択すると、これらのサービスの使用が妨げられるか、実際のサービス動作に対して十分にテストされていないコードや設定が生成される可能性があります。

エミュレーションテストを使用する場合は、可能な限りクラウドテストで補完して、適切なクラウド設定が設定されていることを検証し、エミュレートされた環境でのみシミュレートまたはモックできる サービスとのインタラクションをテストします。

エミュレーションテストは、ユニットテストの迅速なフィードバックを提供することができ、エミュレーションソフトウェアの機能と動作パリティによっては、いくつかの統合テストとend-to-endテストもサポートする場合があります。

自然境界によるスコープテスト

サーバーレスアプリケーションがより多くのアーキテクチャコンポーネントにまたがって成長するにつれて、特に単一目的関数やイベント駆動型デカップリングなどのベストプラクティスに従う場合、サブシステムの周囲に自然境界が現れます。これらの境界は、コンポーネント間の契約を検証できる効果的なテストエッジとして機能します。

アーキテクチャの境界を特定する

アプリケーション設計で自然なシームを探します。

  • パブリッシャーをコンシューマーに接続する Amazon EventBridge ルールなどのサービス間

  • Lambda 関数の前にある Amazon API Gateway エンドポイントなどの API エッジ

  • 複数のサービスの AWS Step Functions オーケストレーションなどのワークフローについて

  • ダウンストリーム処理をトリガーする Amazon DynamoDB ストリームなどのストレージレイヤー

Lambda コードをビジネスロジックから分離する

Lambda コードをコアビジネスロジックから分離することで、テストを簡素化します。Lambda ハンドラーは、 AWS ランタイムとアプリケーションロジックの間のシンアダプターとして機能します。イベントデータを抽出して検証し、Lambda 依存関係のないテスト可能な関数に委任する必要があります。これにより、Lambda オブジェクトをモックしたり、複雑な環境を設定したりすることなく、ビジネスロジックを移植可能にし、推論しやすく、簡単にテストできます。

境界を契約として扱う

通過するのではなく、境界でテストします。ダウンストリームシステム全体を必要とせずに、エッジを通過するものを検証します。これらの同じ境界は、本番環境でオブザーバビリティフックとしても機能します。テストするアーキテクチャシームは、Amazon CloudWatch Logs、 AWS X-Ray トレース、EventBridge イベントを使用してモニタリングするために計測できます。

非同期ワークフローにテストハーネスを使用する

サーバーレスアプリケーションは、多くの場合非同期パターンに依存します。非同期パターンでは、イベントが処理をトリガーし、メッセージがキューを流れ、ワークフローが複数のサービスにまたがり、すぐに応答することはありません。単に関数を呼び出して戻り値を検査することはできません。結果は、後でデータベース、ログストリーム、または別のサービスに表示されることがあります。

テストハーネスは、アプリケーションと共にデプロイするインフラストラクチャをテストして、この非同期動作を監視および検証します。テストハーネスには通常、次のものが含まれます。

  • アプリケーションが生成するのと同じイベントにサブスクライブするイベントリスナー

  • テスト結果をキャプチャできるストレージメカニズム (DynamoDB テーブルや Amazon S3 バケットなど)

  • 期待される結果が表示されるまで待機するテストコード内のポーリングロジック

テストコードはイベントを開始し、ワークフローが完了するまで待機してから、テストハーネスにクエリを実行して、予想される結果が発生したことを確認します。

ベストプラクティスは以下のとおりです。

  • 非同期オペレーションの明確な SLAs を定義する – ワークフローにかかる時間を設定し、それらをテストのポーリングタイムアウトとして使用します。

  • テスト分離に一意の識別子を使用する – テスト実行ごとに一意のファイル名、メッセージ IDs、または相関トークンを生成して、テスト間の干渉を防止します。

  • アプリケーションと一緒にテストインフラストラクチャをデプロイする – テストハーネスリソースを infrastructure-as-code テンプレートに含めて、アプリケーションの進化に合わせて同期を維持します。

  • テスト実行後にテストデータをクリーンアップする – これにより、クラウド環境にテストアーティファクトが蓄積されるのを防ぐことができます。

テストハーネスは、複数のサービスにわたるワークフローを検証する統合テスト、完全なユーザージャーニーを検証するend-to-endテスト、およびサービスが EventBridge、Amazon SNS、Amazon SQS、または Amazon Kinesis を介して通信するイベント駆動型アーキテクチャに最も役立ちます。

開発者を分離するためのクラウド環境の整理

クラウドでのテストには、相互に分離された環境が必要です。デベロッパーがチーム開発アカウントなどの単一の を共有する場合は AWS アカウント、デベロッパーまたは機能ブランチごとに個別のアプリケーションスタックを作成することを検討してください。これにより、リソースが分離され、命名衝突が防止され、テスト中のクォータの競合やノイズの多い近隣問題を回避できます。

Parameter Store または同様のツールを使用して、API AWS Systems Manager エンドポイントやキュー名などのスタック固有の設定を管理します。コスト効率を高めるために、Amazon Relational Database Service (Amazon RDS) クラスターなどの高価なリソースを開発者スタック間で共有し、スタックごとに軽量のサーバーレスリソース (Lambda 関数、API Gateway ステージ、DynamoDB テーブルなど) を分離します。

規制された業界では、エンタープライズセキュリティポリシーによって開発者のクラウド環境へのアクセスが制限され、ローカル開発ワークフローの一部としてクラウドテストを実行することが難しくなる可能性があります。このような場合、エミュレーションテストはローカルモックテストと完全なクラウド検証の間のギャップを埋めることができますが、アクセスが許す場合は常にクラウドテストで補完する必要があります。

フィードバックループを高速化

クラウドでテストを行うときは、いろいろなツールとテクニックを使って開発のフィードバックループを加速させます。たとえば、 AWS SAM Accelerate モードと AWS CDK watch モードを使用すると、コード変更をクラウド環境にプッシュする時間を短縮できます。GitHub のサーバーレステストサンプルリポジトリにあるサンプルでは、これらのテクニックをいくつか取り上げています。

また、ソース管理へのチェックイン後だけでなく、開発中にできるだけ早くローカルマシンからクラウドリソースを作成してテストすることをお勧めします。この方法により、ソリューションを開発する際の調査と実験を迅速に行うことができます。さらに、開発マシンからのデプロイを自動化できれば、クラウド構成内の問題の発見をはやめ、ソース管理の、変更の更新と承認に要する無駄な作業を減らすことができます。