負荷テストツール「K6」を使って、アプリケーションのパフォーマンスを効率的にテストする方法を解説します。本記事では、インストール方法から基本構文、テスト実行まで、実践的な使い方を紹介します。
Table of Contents
この記事の概要
- K6のインストール方法
- テストの基本と実行
- テストファイルの作成方法
- メトリクスとオプション設定
- Thresholds(しきい値)の設定と使い方
- テストライフサイクル
1. インストール
・Homebrew(macOS/Linux)
brew install k6
・Docker
docker pull grafana/k6
・Windows
Chocolateyまたは公式サイトからインストール可能。
2. テスト実行の基本
・テンプレートでテストファイルを作成する
k6 new
k6 new
コマンドでテストファイルのテンプレートを作成することができます。k6 new <ファイル名>
と指定することで、ファイル名を指定してテンプレートを作成することもできます。
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
// A number specifying the number of VUs to run concurrently.
vus: 10,
// A string specifying the total duration of the test run.
duration: '30s',
// The following section contains configuration options for execution of this
// test script in Grafana Cloud.
//
// See https://grafana.com/docs/grafana-cloud/k6/get-started/run-cloud-tests-from-the-cli/
// to learn about authoring and running k6 test scripts in Grafana k6 Cloud.
//
// ext: {
// loadimpact: {
// // The ID of the project to which the test is assigned in the k6 Cloud UI.
// // By default tests are executed in default project.
// projectID: "",
// // The name of the test in the k6 Cloud UI.
// // Test runs with the same name will be grouped.
// name: "hoge.js"
// }
// },
// Uncomment this section to enable the use of Browser API in your tests.
//
// See https://grafana.com/docs/k6/latest/using-k6-browser/running-browser-tests/ to learn more
// about using Browser API in your test scripts.
//
// scenarios: {
// // The scenario name appears in the result summary, tags, and so on.
// // You can give the scenario any name, as long as each name in the script is unique.
// ui: {
// // Executor is a mandatory parameter for browser-based tests.
// // Shared iterations in this case tells k6 to reuse VUs to execute iterations.
// //
// // See https://grafana.com/docs/k6/latest/using-k6/scenarios/executors/ for other executor types.
// executor: 'shared-iterations',
// options: {
// browser: {
// // This is a mandatory parameter that instructs k6 to launch and
// // connect to a chromium-based browser, and use it to run UI-based
// // tests.
// type: 'chromium',
// },
// },
// },
// }
};
// The function that defines VU logic.
//
// See https://grafana.com/docs/k6/latest/examples/get-started-with-k6/ to learn more
// about authoring k6 scripts.
//
export default function() {
http.get('https://test.k6.io');
sleep(1);
}
テストスクリプトはJavaScript形式で記述します。以下は基本構文です。
テストファイルの基本構文
import http from 'k6/http';
import { check, sleep } from 'k6';
export let options = {
vus: 10, // 仮想ユーザー数
duration: '30s', // 実行時間
};
export default function () {
let response = http.get('https://example.com');
check(response, { 'status is 200': (r) => r.status === 200 });
sleep(1);
}
vus
: 仮想ユーザー数(Virtual Users)。同時にリクエストを実行する数。ここでは10人のユーザーがアクセスをシミュレーションします。duration
: テストの継続時間。30秒間、リクエストを送り続けます。http.get('https://example.com')
: 指定URLにGETリクエストを送信します。response
変数に結果が格納されます。check(response, { 'status is 200': (r) => r.status === 200 })
: レスポンスステータスが200(成功)であることを確認します。条件が満たされれば成功、満たされない場合は失敗として記録されます。sleep(1)
: 1秒の遅延を挿入し、負荷を均等に分散します。
テストの実行
以下のコマンドでテストを実行することができる。
k6 run test-script.js
3. 実行オプション
オプション | 説明 |
---|---|
vus | 仮想ユーザー数 |
duration | テスト実行の継続時間 |
iterations | リクエストの実行回数 |
4. メトリクスの見方
実行結果には、http_req_durationやhttp_req_failedなどの詳細なメトリクスが表示されます。
詳細は公式のmetricsのページをご覧ください。
/\ |‾‾| /‾‾/ /‾‾/
/\ / \ | |/ / / /
/ \/ \ | ( / ‾‾\
/ \ | |\ \ | (‾) |
/ __________ \ |__| \__\ \_____/ .io
execution: local
script: test.js
output: -
scenarios: (100.00%) 1 scenario, 10 max VUs, 1m0s max duration (incl. graceful stop):
* default: 10 looping VUs for 30s (gracefulStop: 30s)
data_received..................: 3.0 MB 96 kB/s
data_sent......................: 28 kB 911 B/s
http_req_blocked...............: avg=17.47ms min=2µs med=5µs max=457.81ms p(90)=8µs p(95)=24.69µs
http_req_connecting............: avg=6.87ms min=0s med=0s max=182.71ms p(90)=0s p(95)=0s
http_req_duration..............: avg=182.93ms min=174.29ms med=176.02ms max=349.4ms p(90)=177.33ms p(95)=178.13ms
{ expected_response:true }...: avg=182.93ms min=174.29ms med=176.02ms max=349.4ms p(90)=177.33ms p(95)=178.13ms
http_req_failed................: 0.00% ✓ 0 ✗ 254
http_req_receiving.............: avg=6.91ms min=32µs med=70.5µs max=173.03ms p(90)=355µs p(95)=628.79µs
http_req_sending...............: avg=26.9µs min=9µs med=20µs max=684µs p(90)=35µs p(95)=40µs
http_req_tls_handshaking.......: avg=8.05ms min=0s med=0s max=216.55ms p(90)=0s p(95)=0s
http_req_waiting...............: avg=175.99ms min=173.46ms med=175.82ms max=196.98ms p(90)=176.9ms p(95)=177.23ms
http_reqs......................: 254 8.180674/s
iteration_duration.............: avg=1.2s min=1.17s med=1.17s max=1.63s p(90)=1.17s p(95)=1.34s
iterations.....................: 254 8.180674/s
vus............................: 4 min=4 max=10
vus_max........................: 10 min=10 max=10
running (0m31.0s), 00/10 VUs, 254 complete and 0 interrupted iterations
default ✓ [======================================] 10 VUs 30s
メトリック名 | 説明 |
---|---|
data_received | 受信したデータの量 |
data_sent | 送信されたデータ量 |
http_req_blocked | リクエストを開始するまでにブロック(TCPコネクションスロットの空き待ち)された時間 |
http_req_connecting | リモートホストとのTCPコネクション確立に要した時間 |
http_req_duration | リクエストの合計時間(http_req_sending + http_req_waiting + http_req_receiving) |
http_req_failed | 失敗したリクエストの割合 |
http_req_receiving | リモートホストからの応答データ受信に要した時間 |
http_req_sending | リモートホストへのデータ送信に費やした時間 |
http_req_tls_handshaking | リモートホストとのTLSセッションのハンドシェイクに費やした時間 |
http_req_waiting | リモートホストからの応答待ち時間(time to first byte TTFBとも呼ばれる) |
http_reqs | httpリクエストの総数 |
iteration_duration | 1回のイテレーションの実行に要した時間 |
iterations | vus(仮想ユーザー)が実行したデフォルト関数の回数 |
vus | virtual usersの略 同時にアクセスする仮想ユーザー数 |
vus_max | 仮想ユーザーの最大可能数 |
成功の判断基準
- チェックの合格率 (
checks
) が100%である。 - 失敗リクエスト (
http_req_failed
) が0%。 - 設定したしきい値 (
thresholds
) を超えない応答時間。
5. CheckとThresholds
Checkはテスト条件の成功/失敗を定義し、Thresholdsで基準値を指定できます。
export let options = {
thresholds: {
'http_req_duration{p(95)}': ['<500'], // 95%のリクエストが500ms以内
},
};
6. テストライフサイクル
ここでは、k6のテストライフサイクルについて説明します。
k6には、次の4つのライフサイクルステージが存在します。
ステージ | 目的 |
---|---|
init | テストの開始前に一度だけ実行されるステージです。グローバル変数の宣言やテスト全体で使用する設定の初期化などを行います。 |
setup | テストのdefault関数(VU code)が実行される前に一度だけ実行されるステージです。テストデータの準備や外部からのデータの取り込みなど、テスト実行に必要な前処理を行います。 |
VU Code | 各VU(仮想ユーザー)によって実行されるメインのテストスクリプトです。HTTPリクエストの送信やカスタムメトリクスの計測など、テストの核となるアクションが含まれます。 |
teardown | テストのメイン部分の実行が終了した後に一度だけ実行されるステージです。テストで使用したリソースのクリーンアップや結果の後処理などを行います。 |
ライフサイクルは次のように関数で定義します。
// 1. init: 関数外のスコープは全てinitになる
export function setup() {
// 2. setup: テスト実行(`k6 run`)1回につき1度テスト実行前に呼び出される
}
export default function() {
// 3. VU code: 実際のテストシナリオ
}
export function teardown() {
// 4. teardown code: テスト実行(`k6 run`)1回につき1度テスト実行後に呼び出される
}
まとめ
K6は、シンプルかつ強力な負荷テストツールです。スクリプト作成の柔軟性と、Thresholdsを活用した基準設定により、リアルな負荷シミュレーションを実現します。CI/CD環境に統合し、継続的なパフォーマンステストを行いましょう。
【その他技術ブログ】
・正常系テストと異常系テストの違い、必要性について解説【初心者】
・React におけるインテグレーションテストの重要性を調べてみた
・[AWS EC2]Amazon Linux2023にcomposerをインストールする
・シンギュラリティとは?未来社会を変える「技術的特異点」を解説
・Git 高度な使い方:プロジェクト管理を一段階上へ