こんにちは。よっしーです(^^)
今日は、k6を利用した性能テストの自動化についてご紹介します。
背景
Dockerで構築したWebアプリの開発環境において、k6を利用した負荷テストについて調査したときの内容を備忘として残しました。
開発環境のソースは下記のリポジトリにあります。
シナリオとワークロードをモデル化する
1つまたは複数のテストを選択したら、テストする必要があるさまざまなトラフィックの種類を特定する必要があります。
GETエンドポイントのパフォーマンスを評価するための1つのテストと、チェックアウトプロセスを検証するための1つのテストを使用するシンプルな例で説明しましょう。
次のステップは、これらのテストのためにシステムアンダーテスト(SUT)が処理するトラフィックを特定することです。この場合、GETエンドポイントとチェックアウトフローの典型的なトラフィックパターンを見つけるために、分析およびモニタリングツールを活用できます。
トラフィックの種類に応じて、さまざまな種類のテストを作成できます:
- スモーク:スクリプトエラーをテストし、最小のトラフィックでSUTを検証します。
- 平均負荷:通常のトラフィックをテストします。
- ストレス:最大予想トラフィックをテストします。
- スパイク:トラフィックの急増をテストします。
- ソーク:長時間にわたるトラフィックをテストします。
この例では、2つのシナリオに対する以下のワークロードを決定しました:
TEST SCENARIO | SMOKE | AVERAGE | STRESS | SPIKE | SOAK |
---|---|---|---|---|---|
GET endpoint | 1 iteration | 100 reqs/s – 3m | 1500 reqs/s – 5m | ||
Checkout process | 3 iterations | 50 VUs – 5m | 200 VUs – 1m |
常にベースライン比較のための平均負荷テストと、より大きなテストを実行する前にテストスクリプトのエラーを検証するためのスモークテストを作成することをお勧めします。
この例では、同じテストシナリオを使用して異なるワークロードを持つテストが存在することがあります。このパターンは非常に一般的です。この場合、テストの作成とメンテナンスの両方を簡素化するために、異なるワークロードのテストに共通のシナリオロジックを再利用できる能力が重要です。テストを整理する一般的なパターンは、テストの接頭辞にワークロードのタイプを付けることです:
smoke-get-api.js
: 一般的なシナリオをインポートし、1イテレーションを設定します。load-get-api.js
: 一般的なシナリオをインポートし、3分間に100 reqs/sを設定します。stress-get-api.js
: 一般的なシナリオをインポートし、3分間に1500 reqs/sを設定します。
k6でワークロードを設定する詳細については、「Scenarios」を確認してください。
各環境のテスト頻度を決める
次のステップは、テスト対象となる環境とその頻度を決定することです。各組織は異なる環境を持ち、その目的も組織によって異なる場合があります。
以下は、組織で一般的に見られるいくつかの環境と、それらをどのように使用するかの一般的なガイドラインです。
開発環境 (Development Environment)
この環境は、個人のマシンまたは専用の環境であるかもしれませんが、システムのすべてのコンポーネントを含んでいないかもしれません。通常、アプリケーションをより包括的な環境に展開する前の初期テストに使用されます。
この環境は、スモークテストを実行してテストの基本的な機能を検証するために適しています。
このタイプの環境では、自動化よりもデバッグとパフォーマンステストの構築が一般的です。ただし、プロジェクトの構造が許容する場合、プロジェクトの変更時にスモークテストの実行をスケジュールすることもできます。
各環境の目的と適切なテストの種類を考慮しながら、どの環境でどの頻度でテストを実行するかを検討することが重要です。
QA environment
この環境は、通常、全体のアプリケーションを展開しますが、インフラストラクチャのリソースは最小限です。これは、すべてのチームが新機能のための機能のテストとリグレッションの検出を行うために使用できる、規模の小さいステージング環境のようなものです。
インフラストラクチャが本番環境と非常に一致しないため、この種のQA環境はアプリケーションのパフォーマンスとスケーラビリティを評価するのには適していません。
ただし、スモークテストを使用してテストの機能面を検証することで、この環境でエラーを早期に検出するのに役立ちます。また、同じスクリプトが後で大規模な負荷テストで実行できることも検証します。
利用可能なすべてのスモークテスト(エンドツーエンド、統合、ユニットテストなど)を実行してください。これらのテストをCIフローで実行される自動化テストスイートの一部としてスケジュールして実行します。
事前リリース環境 (Pre-release Environment) & 一時的な環境 (Ephemeral Environment)
これらの環境は、将来のリリースをテストするために利用可能であり、各組織はそれらを独自のリリースプロセスの一部として異なる方法で使用しています。
事前リリース環境に関する一般的なルールとして、品質ゲートを持つ大規模なテストを実行することが挙げられます。品質ゲートは、SLO(サービスレベル目標)や信頼性の目標を検証する合格/不合格の基準を提供します。k6を使用してこれを実現するには、次のようにオプションのThresholdsを使用できます:
export const options = {
thresholds: {
// http errors should be less than 1%
http_req_failed: ['rate<0.01'],
// 90% of requests should be below 600ms
http_req_duration: ['p(90)<600'],
// 95% of requests tagged as static content should be below 200ms
'http_req_duration{type:staticContent}': ['p(99)<250'],
// the error rate of my custom metric should be below 5%
my_custom_metric: ['rate<0.05']
},
};
信頼性の目標を効果的に評価することは難しいことがあります。異なる種類の負荷でテストを行うと、しばしば “偽陽性” と “真陰性” に遭遇することがあります。
大規模なテストでは、リリースの合格/不合格ステータスに基づいてのみ検証することは、パフォーマンステストとリリースプロセスにおいて誤った安心感を生む可能性があります。
事前リリース環境を数時間または数日間使用し、システム全体を徹底的にテストすることをお勧めします。以下は、推奨事項の一部です:
- リリースを検証するために1日から数日間の期間を割り当てる。
- すべての既存の平均負荷、ストレス、スパイクテストを実行する。
- 各テストを少なくとも2回連続で実行する。
- すべてのテストを定期的に実行するスケジュールを設定する。たとえば、4時間ごとまたは8時間ごとに実行する。
これらの措置により、リリースが本番環境にデプロイされる前に、システム全体のパフォーマンスと信頼性をより確実に評価できるようになります。
Staging/pre-production
一部の場合、ステージング環境は「事前リリース」環境のような役割を果たします。その場合、前のセクションで述べた戦略に従ってください。
ステージング環境は常に利用可能であり、最新の変更が常に更新されます。一般的には、パフォーマンスの傾向、リグレッション、または改善などのパフォーマンスの変更を評価するのに適しています。
この場合、主要なパフォーマンス指標を評価するテストを選択し、それらのテストを一定の実行頻度でスケジュールして一定期間にわたるメトリクスを収集することをお勧めします。最初にいくつかのテストを選択し、週に2回から3回実行するようにスケジュールを設定します。
事前リリース環境と同様に、各テストを少なくとも2回連続で実行することを提案し、信頼性の低いテストを無視できるようにします。
パフォーマンスの変更を見つけることを目指しているため、ステージングインフラストラクチャに応じてテストのワークロードを調整することを検討してください。これは通常、本番環境のスケールには合わないことがあります。
Production
通常、前述のテスト環境は本番環境を完全に反映しておらず、テストデータ、インフラリソース、およびスケーラビリティポリシーに違いがあります。
本番環境でのテストは、他の環境では達成できない実世界の洞察を提供します。ただし、本番環境でのテストは、本番データの取り扱いと保存、実際のユーザーに影響を与えないように慎重なアプローチが必要です。
低リスクな一般的な実践方法は、合成テストまたは合成モニタリングとも呼ばれるスモークテストを使用することです。最小の負荷で本番環境をテストすることは安全です。スモークテストを毎5分ごとにスケジュールし、合格/不合格のテスト条件と効果的なアラートメカニズムを確立します。たとえば、6回の連続したテストが失敗した場合、アラートを送信します。
Blue/GreenやCanaryデプロイメントなどのリリース戦略が存在する場合、リリースを検証するためにGreenまたは新しいバージョンに対して負荷テストを実行します。これは、SLOが本番環境でどのように振る舞うかを確認する理想的な瞬間です。
また、夜間のテストやシステムが少ないトラフィックを処理する場合にもスケジュールすることを検討してください。目標はシステムをストレスにかけることではなく、変更を比較し、パフォーマンスのトレンドを分析するためにパフォーマンス結果を一貫して収集することです。たとえば、週に半分の平均トラフィックレベルでテストをスケジュールすることができます。
TEST | DEPLOYMENT ENV. | TYPE | WORKLOAD | AUTOMATION | FREQUENCY |
---|---|---|---|---|---|
Checkout process | QA | Smoke | 1 iteration | CI flow (Branch changes) | On Branch changes |
Checkout process | Pre-release | Average | 50 VUs – 5m | Scheduled during QA/Pre-release | 3 times per day during pre-release period |
Checkout process | Pre-release | Spike | 200 VUs – 1m | Scheduled during QA/Pre-release | 3 times per day during pre-release period |
Checkout process | Staging | Average | 50 VUs – 5m | Scheduled | 2 times per week |
GET endpoint | QA | Smoke | 1 iteration | CI flow (Branch changes) | On Branch changes |
GET endpoint | Pre-release | Average | 100 reqs/s – 3m | Scheduled during QA/Pre-release | 3 times per day during pre-release period |
GET endpoint | Pre-release | Stress | 1500 reqs/s – 5m | Scheduled during QA/Pre-release | 3 times per day during pre-release period |
GET endpoint | Staging | Average | 100 reqs/s – 3m | Scheduled | 2 times per week |
GET endpoint | Production | 50% Avg. | 50 reqs/s – 3m | Scheduled on minimal traffic | Weekly |
このテーブルでは、各テストの種類、デプロイメント環境、ワークロード、自動化方法、および実行頻度がまとめられています。それぞれのテストに対する詳細なスケジュールと自動化方法が示されています。
おわりに
今日は、k6を利用した性能テストの自動化についてご紹介しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント