こんにちは。よっしーです(^^)
今日は、APIの負荷テストについてご紹介します。
背景
Dockerで構築したWebアプリの開発環境において、k6を利用した負荷テストについて調査したときの内容を備忘として残しました。
開発環境のソースは下記のリポジトリにあります。
API負荷テスト
API負荷テストは、通常、孤立したコンポーネントに対して小規模な負荷から始まります。テストが進化するにつれて、APIをより完全にテストする方法を検討する戦略を採用できます。このプロセスでは、より多くのリクエスト、長い期間、および孤立したコンポーネントから完全なエンドツーエンドのワークフローまで、広範囲なテストスコープでAPIをテストします。
APIテストを設計する際に、まずAPIをテストする理由を考えます:
- どのフローまたはコンポーネントをテストしたいですか?
- テストをどのように実行しますか?
- 受け入れ可能なパフォーマンスを決定する基準は何ですか?
これらの質問に答えることができれば、APIテスト戦略はおおよそ以下の手順に従うことになるでしょう:
- テストをスクリプト化する。ユーザーフローを記述し、テストデータをパラメータ化し、URLをグループ化します。
- パフォーマンスと正確さを確認する。システムの応答を確認するためにチェックを使用し、システムがSLO(サービスレベル目標)内で動作することを確認するためにしきい値を使用します。
- モデル化と負荷生成。テスト目標に適したワークロードを正確にモデル化するために、正しいエグゼキューターを選択します。負荷ジェネレーターが適切な位置に配置されていることを確認します。
- テストスイートを反復する。時間の経過とともに、スクリプトのロジック(ユーザーログインフローやスループットの設定など)を再利用できるようになります。また、テストをより広範囲に実行したり、自動化テストスイートの一部として実行したりすることもできるようになります。
以下のセクションでは、このプロセスの各ステップについて具体的な説明と例を提供しています。
テストするコンポーネントを特定する
テストを開始する前に、テストしたいコンポーネントを特定します。単一のエンドポイントをテストするか、エンドツーエンドのフロー全体をテストしたいですか?
次のスクリプトは、k6 HTTPモジュールを使用して単一のエンドポイントをテストする例です。
import http from 'k6/http';
export default function () {
const payload = JSON.stringify({
name: 'lorem',
surname: 'ipsum',
});
const headers = { 'Content-Type': 'application/json' };
http.post('https://httpbin.test.k6.io/post', payload, { headers });
}
これは、1つの呼び出しで1つのコンポーネントをテストする最小限のテストです。通常、テストスイートはこのようなスクリプトからより複雑で完全なワークフローに進化します。このプロセスで、テストスイートは次のようにテストピラミッドを進むでしょう:
- 孤立したAPIのテスト。APIのエンドポイントをテストするためのabのようなツールを使用して、ベースラインのパフォーマンス、ブレークポイント、可用性をテストします。コンポーネントがパフォーマンス要件を満たさない場合、それはボトルネックです。一般的に、負荷は秒間リクエスト数で設定されます。
- 統合されたAPIのテスト。内部または外部の他のAPIと連携する1つまたは複数のAPIをテストします。焦点は1つのシステムまたは複数のシステムのテストになるかもしれません。
- エンドツーエンドのAPIフローのテスト。API間のリアルな相互作用をシミュレートして、システム全体をテストします。焦点は通常、頻繁で重要なユーザーシナリオに置かれます。
負荷テストスイートにはさまざまなテストが含まれるべきです。ただし、始めるときは小規模かつシンプルに始め、個々のAPIと複雑でない統合テストを行うことから始めます。
検査の理由を決定
テスト負荷を設定する前に、APIをどのようなトラフィックパターンでテストしたいかを知る必要があります。負荷テストは通常、次の2つの目的のいずれかを達成しようとします:
- 予想されるトラフィックの下で信頼性を検証する。
- 異常なトラフィックの下で問題やシステムの限界を発見する。
たとえば、チームは平均的なトラフィックで頻繁なユーザーフローのための1つのテストセットを作成し、APIの限界を見つけるための別のセットを作成するかもしれません。テストロジックが同じでも、負荷は異なるかもしれません。
テストの目標はテストタイプを決定し、それがテスト負荷を決定します。以下は、さまざまな目標の負荷プロファイルに対応するさまざまなテストタイプを考慮してください:
- スモークテスト。最小限の負荷でシステムの機能を検証します。
- “平均”の負荷テスト。通常のトラフィックでシステムの動作を確認します。
- ストレステスト。ピーク時のトラフィック負荷でシステムの動作を確認します。
- スパイクテスト。急激かつ大規模なトラフィック増加でシステムの動作を確認します。
- ブレークポイントテスト。徐々にトラフィックを増やしてシステムの限界を発見します。
- ソークテスト。長時間の負荷の下でシステムが劣化するかどうかを発見します。
選択したテストタイプは、テストの計画と構造をどのように行うかに影響を与えます。ただし、各アプリケーション、組織、テストプロジェクトは異なります。
推奨事項は常に次のとおりです:
“シンプルに始めて頻繁にテストを実施し、テストスイートを繰り返し拡充していくこと”
負荷プロファイルを決定したら、k6のオプションを使用してスケジュールを設定できます。
おわりに
今日は、APIの負荷テストを実施するにあたって決定すべき事項についてご紹介しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント