本チュートリアルの内容:

  1. k6 のテスト結果をエクスポートする
  2. k6 のテスト結果の出力を保存する
  3. 負荷テスト用の CI/CD パイプラインをスケジュール実行する

この k6 シリーズでは、これまで、k6 を使用した HTTP リクエスト テストと、k6 を使用したパフォーマンス テストについて解説してきました。

前提条件

このチュートリアルを進めるには、以下の準備が必要です。

  1. JavaScript の基礎を理解する
  2. HTTP リクエストの基礎とテスト方法を理解する
  3. Node.js (バージョン 10.13 以上) をローカルシステムにインストールする
  4. CircleCI アカウントを用意する
  5. GitHub アカウントを用意する

    前回のチュートリアル「k6 で API のパフォーマンスをテストする方法」をまだご覧になっていない場合は、このチュートリアルを始める前に確認しておくことをお勧めします。

今回のチュートリアルは、前回のチュートリアルで作成したものをベースにしています。 前回のチュートリアルの GitHub リポジトリクローンすることが、今回の最初のステップです。

以下のコマンドを実行すると、GitHub のリポジトリをクローンできます。

git clone https://github.com/CIRCLECI-GWP/api-performance-testing-with-k6.git

これで準備完了です。 チュートリアルを始めましょう!

k6 のテスト結果の出力を保存する

k6 でパフォーマンスをテストする前回のチュートリアルでは、チーム全体で確認や分析ができるように、k6 のメトリクスとログをクラウドに出力する方法について解説しました。 今回のチュートリアルでは、テストを実行したローカルマシンにテストの出力を保存する方法について解説します。

k6 には、テスト結果を後の確認用にエクスポートする方法が複数用意されています。 k6 のエクスポートに対応しているサービスには、Amazon CloudWatch、Apache Kafka、Influx DB、New Relic、Prometheus、Datadog などがあります。 このチュートリアルでは、これらのサービスへの出力と同じものを JSON で取得する方法を解説します。

k6 でテスト結果を外部へ出力するには、--out フラグを指定する必要があります。 前回のチュートリアルでは、やや異なる方法でこれを行いました。 今回は、先ほどクローンしたリポジトリで、Heroku API のシンプルな負荷テストを実行します。

この負荷テストでは、仮想ユーザーを複数シミュレートして、 30 秒間で次の処理を行います。

  • API を使って複数の todo 項目を作成する
  • ToDo 項目を作成するたびに、項目がアプリケーションエンドポイントを使って作成できたか確認する

このテストのコードスニペットを次に示します。

// create-todo-http-requests.js ファイル
import http from 'k6/http';
import { check, group } from 'k6';
import { Trend } from 'k6/metrics';

const uptimeTrendCheck = new Trend('/GET API uptime');
const todoCreationTrend = new Trend('/POST Create a todo');

export let options = {
   stages: [
       { duration: '0.5m', target: 3 }, // 0.5 分間にわたりユーザーが 0 名から 3 名にランプアップしたときのトラフィックをシミュレーションする
   ],
};

export default function () {
   group('API uptime check', () => {
       const response = http.get('https://todo-app-barkend.herokuapp.com/todos/');
       uptimeTrendCheck.add(response.timings.duration);
       check(response, {
           "status code should be 200": res => res.status === 200,
       });
   });

   let todoID;
   group('Create a Todo', () => {
       const response = http.post('https://todo-app-barkend.herokuapp.com/todos/',
           { "task": "write k6 tests" }
       );
       todoCreationTrend.add(response.timings.duration);
       todoID = response.json()._id;
       check(response, {
           "status code should be 200": res => res.status === 200,
       });
       check(response, {
           "response should have created todo": res => res.json().completed === false,
       });
   })
}

create-todo-http-requests.js ファイルの最初の group() ブロックでは、API の応答を確認する稼働チェックを実行します。 次のブロックでは、todo 項目の作成と、項目の作成に成功したことの確認を行います。

このテストは、k6 run test-file というコマンドで実行できます。 ただ、今回は多くの情報を知りたいので、別のコマンドを使用することにします。 正常に実行されたかどうかの確認に加えて、実行のログを JSON ファイルに保存したいと思います。

そのためには、--out outputFile.json フラグを使用します。 このフラグを指定することで、テストの応答が JSON 形式で記録されます。 それでは、次のコマンドを実行しましょう。

k6 run create-todo-http-request.js --out  json=create-todo-http-request-load.json

テストが通常どおりに実行され、create-todo-http-request-load.json ファイルが作成されます。 このファイルには、今回のコマンド実行におけるすべてのテストの実行情報が記録されます。

テストメトリクスの出力を定義して k6 を実行すれば、その出力が記録され、テスト実行結果に表示されます。

負荷テスト結果の出力

テストの実行後、JSON 出力ファイルを開くと結果を確認できます。

負荷テスト結果のファイル

JSON 出力ファイルには、k6 でデータ生成に使用されたメトリクスが記録されています。 また、次の点についても確認できます。

  • 負荷テストの実行時に行われたすべてのリクエスト
  • リクエストのタイムスタンプ
  • 各リクエストの実行に要した時間

これらのデータから、最も遅い応答や最も速い応答を見極め、ボトルネックがわかります。 これによって、テストへの理解が深まるだけでなく、生成された結果出力ファイルを恒久的に保存できます。 このように、データをエクスポートすることで、後で確認したり他のテスト実行と比較したりするためのデータを効率的に保存できます。 今回は JSON のエクスポートを試しましたが、CSV や XML など、他のファイルタイプのエクスポートも試してみてください。

CircleCI パイプラインのスケジュール実行機能を使用して負荷テストをスケジュール実行する

負荷テストは実行に時間がかかるのが常で、システムリソースを大量に消費する場合もあります。 そのため、負荷テストは、システムにアクセスするユーザーがいないときや、アプリケーションユーザーに対するテストの影響がほとんど、あるいはまったくないとわかっているときにだけ実行することをお勧めします。 別の方法として、本番環境を模倣した並列負荷テスト環境を構築してもよいでしょう。

CI/CD を実践している方なら、リソースは常に制約となる一方で、品質が常に優先事項となることはご存じでしょう。 これらを踏まえると、負荷テストの実行では、パイプラインのスケジュール実行を活用するのが有効な選択肢となります。

パイプラインのスケジュール実行機能を使用すれば、システム内のユーザー数がわずかであると予想される時間帯に限って、負荷テストの実行プロセスを自動で実行できます。

CircleCI でパイプラインのスケジュール実行を設定する方法

パイプラインのスケジュール実行を設定するには、CircleCI ダッシュボードに移動し、[Project Settings (プロジェクト設定)] を選択します。 使用するプロジェクトを選択します。 このチュートリアルでは、api-performance-testing-with-k6 プロジェクトを使用します。 プロジェクトの横にある省略記号 (…) をクリックします。

プロジェクトの省略記号

[Trigger (トリガー)] をクリックします。

[Trigger (トリガー)] ページの [Add Trigger (トリガーを追加)] をクリックして、トリガー設定フォームを表示します。

トリガーの追加

フォームに必要事項を入力して、目的のタイミングで負荷テストを実行するトリガーを追加します。 このチュートリアルでは、毎週日曜日の午後 10 時 (UTC) に 1 回実行するように、Sunday22:00 UTC を選択します。 パイプラインのスケジュール実行の設定を保存します。

パイプラインのスケジュール実行の設定

これで、負荷テストを行うパイプラインが週に 1 回実行されるよう設定できました。 スケジュールは、必要に応じて編集できます。 負荷テストの実行を忘れても、指定した日時に CircleCI が確実に実行してくれます。 パイプラインのスケジュール実行機能を使用して開発時間とリソース使用率を最適化する方法については、継続的インテグレーションのパイプラインをスケジュール実行するメリット(英語)についての記事をご覧ください。

おわりに

このチュートリアルでは、k6 を使用して負荷テストを実行する方法を再確認し、テストメトリクスを外部へエクスポートする方法を新たに解説しました。 今回は JSON ファイルにエクスポートしましたが、CSV や XML も使用可能です。 また、負荷テストの実行用にパイプラインのスケジュール実行を設定するプロセスについても解説しました。 CircleCI パイプラインで負荷テストを実行する条件や日時の指定方法について、具体的にご紹介しました。 今回ご紹介した情報が、みなさまのチームで取り組んでいる作業のお役に立てば幸いです。

ぜひ、本シリーズの他 2 つのチュートリアルもご覧になり、今回学んだことをさらに発展させてください。


Waweru Mwaura 氏は品質工学を専門とするソフトウェア エンジニアです。生涯学習の実践者という顔も持ち、 Packt で執筆者を務めながら、工学や金融、テクノロジーの書籍を愛読しています。 Mwaura 氏の詳細な情報は、こちらの Web プロフィールをご覧ください。

さんの他の投稿を読む Waweru Mwaura