- k6 とは
- インストール
- 簡単な負荷テストの例
- 出力メトリクス
- xk6-dashboard
- テストスクリプトの構成
- 実行オプション
- HTTP リクエスト
- HTTP レスポンスのCheck
- スクリプトの自動生成
k6 とは
- Go で書かれた開発者フレンドリーな負荷テストツール
- OSS
- シナリオは JS で作成
- HAR(HTTP アーカイブ) からシナリオへのコンバーターあり
- 各種ツールとの連携が充実
- ブラウザ含めたEtoEテストも可能
- 公式サイト
- Github リポジトリ
- 公式ドキュメントが非常にわかりやすい k6 documentation
インストール
GitHub Releases page からスタンドアロンのバイナリを取得するか、以下のコマンドでインストール可能。
単一の実行ファイルだけなので、作業ディレクトリに直接実行ファイルを配備するだけでも良い。
後述の xk6-dashboard を使う場合は、xk6-dashboard Releases からプラットフォーム別のバイナリをダウンロードして任意ディレクトリに解凍すれば良い(必要に応じてパス設定)。
MacOS
$ brew install k6
Windoes
> winget install k6
Docker
$ docker pull grafana/k6
バージョン確認
$ k6 version k6 v0.44.1 (.....)
簡単な負荷テストの例
任意ディレクトリに script.js
として以下を作成する。
import http from 'k6/http'; import { sleep } from 'k6'; export default function () { http.get('https://www.google.com/'); sleep(1); }
スクリプトの実行には run
コマンドを使用する。
$ k6 run script.js
仮想ユーザ vus
(VUs) と期間 duration
を指定する場合は以下
$ k6 run --vus 10 --duration 15s script.js
10ユーザ並列で、15秒間リクエストを繰り返す。
実行結果はいかのようになる。
$ k6 run --vus 10 --duration 15s script.js /\ |‾‾| /‾‾/ /‾‾/ /\ / \ | |/ / / / / \/ \ | ( / ‾‾\ / \ | |\ \ | (‾) | / __________ \ |__| \__\ \_____/ .io execution: local script: script.js output: - scenarios: (100.00%) 1 scenario, 10 max VUs, 45s max duration (incl. graceful stop): * default: 10 looping VUs for 15s (gracefulStop: 30s) data_received..................: 2.8 MB 173 kB/s data_sent......................: 29 kB 1.8 kB/s http_req_blocked...............: avg=9.45ms min=0s med=0s max=132.93ms p(90)=0s p(95)=132.41ms http_req_connecting............: avg=41.14µs min=0s med=0s max=623.19µs p(90)=0s p(95)=505.2µs http_req_duration..............: avg=107.29ms min=91.93ms med=103.77ms max=207.01ms p(90)=118.85ms p(95)=126.32ms { expected_response:true }...: avg=107.29ms min=91.93ms med=103.77ms max=207.01ms p(90)=118.85ms p(95)=126.32ms http_req_failed................: 0.00% ✓ 0 ✗ 140 http_req_receiving.............: avg=10.56ms min=246.3µs med=7.63ms max=113ms p(90)=16.97ms p(95)=20.08ms http_req_sending...............: avg=206.1µs min=0s med=0s max=1.06ms p(90)=730.6µs p(95)=982.05µs http_req_tls_handshaking.......: avg=7.7ms min=0s med=0s max=108.49ms p(90)=0s p(95)=107.86ms http_req_waiting...............: avg=96.52ms min=74.78ms med=94.34ms max=172.09ms p(90)=107.71ms p(95)=112.56ms http_reqs......................: 140 8.814585/s iteration_duration.............: avg=1.13s min=1.09s med=1.11s max=1.3s p(90)=1.13s p(95)=1.3s iterations.....................: 140 8.814585/s vus............................: 10 min=10 max=10 vus_max........................: 10 min=10 max=10 running (15.9s), 00/10 VUs, 140 complete and 0 interrupted iterations default ✓ [======================================] 10 VUs 15s
出力メトリクス
代表的なものは以下
http_req_duration
全リクエストの合計レイテンシー。上記例では平均 107.29mshttp_req_failed
失敗リクエストの数(エラー率, 可用性)。上記例ではゼロhttp_reqs
リクエスト数。上記例では秒間8.8リクエストiterations
イテレーション数。上記例ではシナリオを合計140回実行
その他、カスタムメトリクスを定義して収集することもできる。
テスト結果の詳細は、以下のように外部ファイルに出力することができる。
$ k6 run script.js --out csv=test.csv
--out influxdb=http://localhost:8086/k6
のように外部サービスにメトリクスを出力することもできる(Amazon CloudWatch, Datadog など多数の組み込みサポートがある)。大規模なテストで、複数ノードでテストを実行する場合にテスト結果を集約できる。
xk6-dashboard
k6 にビジュアライゼーション機能を追加した xk6-dashboardも良い。
リリースページからバイナリをダウンロードして解凍すると、k6
(k6.exe
) という単一の実行ファイルが得られる。
この実行ファイルにダッシュボードのサーバが組み込まれているため、実行すればブラウザでSSE経由でリアルタイムにメトリクスを見ることができる。
ダッシュボード利用時には --out dashboard
を指定して実行する。
$ ./k6 run --out dashboard script.js
http://127.0.0.1:5665
にアクセスすれば、ダッシュボードでメトリクスをリアルタイムで確認できる。
テストスクリプトの構成
スクリプトは、トップレベルに初期化コードを記載する。
export default function
に、イテレーションで実行するコードを記載する。
この関数がテスト期間中に繰り返して実行される。
import http from 'k6/http'; import { check, sleep } from 'k6'; // init code 仮想ユーザ(VU)毎に1回実行 export const options = { stages: [ { duration: '30s', target: 20 }, { duration: '1m30s', target: 10 }, { duration: '20s', target: 0 }, ], }; // VU code イテレーション毎に実行 export default function () { const res = http.get('https://...'); check(res, { 'status was 200': (r) => r.status == 200 }); sleep(1); }
VU をまたいで共有するデータの初期化は setup()
関数、テスト終了時の後処理(例えばテスト完了をwebhookなどで通知)は teardown()
関数に定義する。
setup()
から値を返すことで、その内容を VU コードや teardown()
で引数として受け取ることができる。
import http from 'k6/http'; export function setup() { const res = http.get('https://httpbin.test.k6.io/get'); return { data: res.json() }; } export default function (data) { console.log(JSON.stringify(data)); } export function teardown(data) { console.log(JSON.stringify(data)); }
group
を用いて複数のリクエストを纏めることがでる。
import { group } from 'k6'; export default function () { group('visit product listing page', function () { // ... }); group('add several products to the shopping cart', function () { // ... }); }
同じグループのリクエストにはグループ名でタグ付けされ、結果出力に反映される。
実行オプション
実行オプションは init code として以下のように定義する。
import http from 'k6/http'; // ... export const options = { userAgent: 'MyK6UserAgentString/1.0', stages: [ { duration: '30s', target: 20 }, { duration: '1m30s', target: 10 }, { duration: '20s', target: 0 }, ], thresholds: { http_req_failed: ['rate<0.01'], // http errors should be less than 1% http_req_duration: ['p(95)<200'], // 95% of requests should be below 200ms }, }; export default function () { http.get('http://...'); }
stages
を定義することで、仮想ユーザ(VUs) を時間の経過に応じて段階的に変化させることができる。
export const options = { stages: [ { duration: '30s', target: 20 }, { duration: '1m30s', target: 10 }, { duration: '20s', target: 0 }, ], };
コマンドラインで指定した場合、コマンドラインのオプションが優先される。
よく使うであろうオプションには以下がある。
insecureSkipTLSVerify: true
TLS 検証をスキップ(オレオレ証明書)maxRedirects: 10
リダイレクト回数を制限noCookiesReset: true
VUイテレーションでCookieをリセットしないuserAgent: 'k6/1.0'
ユーザエージェントを指定thresholds
メトリクスの対して閾値を指定し、エラーとして扱うscenarios
スクリプト中に複数の条件のテストシナリオを定義
その他、Options reference を参照。
HTTP リクエスト
http.get()
http.post()
http.put()
など、HTTPメソッドに応じたメソッドにてリクエストを発行する
import http from 'k6/http'; export default function () { let id = '999' http.get(`http://example.com/posts/${id}`); }
集計用に、リクエストにタグを付けることができる。
http.get(`http://example.com/posts/${id}`, { tags: { name: 'PostsItemURL' }, });
POSTリクエストの場合は以下のようになる。
export default function () { const url = 'http://...'; const payload = JSON.stringify({ email: 'aaa', password: 'bbb', }); const params = { headers: { 'Content-Type': 'application/json', }, }; http.post(url, payload, params); }
HTTP レスポンスのCheck
以下のようにHTTP 応答コードの検証が可能。
import { check } from 'k6'; import http from 'k6/http'; export default function () { const res = http.get('...'); check(res, { 'is status 200': (r) => r.status === 200, }); }
応答本文の検証は以下
const res = http.get('...'); check(res, { 'verify homepage text': (r) => r.body.includes('Collection of simple web-pages suitable for load testing'), });
以下のように複数指定することもできる。
const res = http.get('...'); check(res, { 'is status 200': (r) => r.status === 200, 'body size is 11,105 bytes': (r) => r.body.length == 11105, });
response.html([selector])
でHTML要素を取得することもできる。
check(res, { 'caption is correct': (r) => r.html('h1').text() == 'Example', });
selector
には jquery.find
で指定するセレクタと同様に指定する。
以下の様に処理することもできる。
const doc = res.html(); doc .find('link') .toArray() .forEach(function (item) { console.log(item.attr('href')); });
詳細は k6 API を参照。
スクリプトの自動生成
Webブラウザから出力した HAR ファイル (HTTP ARchive) からスクリプトを自動生成できる。
Github リポジトリは har-to-k6 converter
npm パッケージとして公開されているため、npm i
でインストールする。
$ npm install har-to-k6
HAR ファイルと出力先を指定して実行することで、k6 のスクリプトが得られる。
$ npx har-to-k6 <har.har> -o <script.js>
HAR ファイルはブラウザの開発者ツールから取得する。
Chrome の場合、「デベロッパーツール」-「ネットワーク」で画面操作し、一覧を右クリックし、「コピー」-「HARとしてすべてコピー」でHARのJSONがコピーできる。
Firefoxの場合「ウェブ開発ツール」-「ネットワーク」で画面操作し、一覧を右クリックし、「値をコピー」-「HAR形式ですべてコピー」でHARのJSONがコピーできる。
コピーしたJSONをHAR ファイルとして保存し、k6スクリプトへコンバートすれば、ブラウザで操作した内容がスクリプト化できる(実際には必要箇所を加工して使うことになる)。