k6で始めるパフォーマンステスト
はじめに
今年新卒で入社し、エンジニアとして働き始めた中西です。
パフォーマンステストを行っていく中でk6の良さを知ったので、共有します。
パフォーマンステストとは
全体を通して速度や品質などの性能がどの程度かを測るテストのことです。
ボトルネックを発見し、修正することでソフトウェアの品質を高めることができます。
有名なテストに、負荷テスト、ストレステスト、スパイクテストなどがあります。
k6とは
概要
k6とは、オープンソースの負荷テストツールです。
パフォーマンステストを毎回手動でやっていては面倒に感じられるものでもあります。そんな中でも、k6であれば自動化することができます。そのため、ソフトウェアの更新があった場合に、k6でパフォーマンステストを作ってさえおけば、問題点をすぐに発見でき、品質の向上につなげられるというわけです。
メリット
k6ならではの強みとして以下があります。
- 軽量にテストを動作させられること
- ローカルでもクラウドでも実行可能であること
- JavaScriptでテストシナリオを作成できること
- 豊富なドキュメントが存在すること
デメリット
k6はテストシナリオをJavaScriptを用いて実装するため、GUIではパフォーマンステストを作成することができません。特にGUIでパフォーマンステストを作成したい場合などは、k6よりもJMeterを使用することをおすすめします。
重要だと感じたこと
テスト作成時に知っておくべきこと
-
仮想ユーザーとオプション
テストシナリオの重要な要素で、これらを組み合わせることで思い通りにテストを動作させられるようになります。- 仮想ユーザー
- k6ではVUともいわれる
-
options
メソッドや実行時に設定できる - コード例
/** * 1名の仮想ユーザーが1回テストを実行する */ export const options = { // 仮想ユーザー数:1名 vus: 1, // テスト反復数:1回 iterations: 1, }
- オプション
- テストの動作(テストシナリオ)を決めるもの
-
options
メソッドで実装する - コード例
/** * 各仮想ユーザーが10回ずつテストを実行する */ export const options = { scenarios: { per_vu_iterations_scenario: { // シナリオの設定:仮想ユーザーごとに決められた反復数テストを実行するシナリオ executor: 'per-vu-iterations', // 仮想ユーザー数:10名 vus: 10, // テスト反復数:10回 iterations: 10, // 最大テスト実行時間:5分間 maxDuration: '5m', }, }, }
- 仮想ユーザー
-
ライフサイクル
テストを設計する上で重要な要素です。私は最初にこれを知らずに作成しており、テストの実行に失敗していました。段階 サイクル名 呼ばれる回数 必須か 初期化 コンテキスト(init) VU毎に1回 Yes 準備 setup 全体で1回 No テスト default 反復ごとか、オプションで設定している回数だけ Yes 終了後 teardown 全体で1回 No その他 handleSummary 全体で1回 No コード例
export const options = { // シナリオの設定 } export const setup = () => { // テストの前処理 } export default ()=> { // テスト } export const teardown = () => { // テストの後処理 } export const handleSummary = (data) => { // カスタムメトリクスを出力 }
-
メトリクス
メトリクスを知ることで、リリース前にボトルネックを発見し、問題の原因を特定・修正へとつなげることができます。それにより、リリース後も前と変わらない状態を維持できるため、私はテスト終了後の評価が最も大事だと考えています。
- 最終的な結果で、計測されたものが出力される
- 表示結果例
data_received..................: 22 kB 5.7 kB/s data_sent......................: 742 B 198 B/s http_req_blocked...............: avg=1.05s min=1.05s med=1.05s max=1.05s p(90)=1.05s p(95)=1.05s http_req_connecting............: avg=334.26ms min=334.26ms med=334.26ms max=334.26ms p(90)=334.26ms p(95)=334.26ms http_req_duration..............: avg=2.7s min=2.7s med=2.7s max=2.7s p(90)=2.7s p(95)=2.7s { expected_response:true }...: avg=2.7s min=2.7s med=2.7s max=2.7s p(90)=2.7s p(95)=2.7s http_req_failed................: 0.00% ✓ 0 ✗ 1 http_req_receiving.............: avg=112.41µs min=112.41µs med=112.41µs max=112.41µs p(90)=112.41µs p(95)=112.41µs http_req_sending...............: avg=294.48µs min=294.48µs med=294.48µs max=294.48µs p(90)=294.48µs p(95)=294.48µs http_req_tls_handshaking.......: avg=700.6ms min=700.6ms med=700.6ms max=700.6ms p(90)=700.6ms p(95)=700.6ms http_req_waiting...............: avg=2.7s min=2.7s med=2.7s max=2.7s p(90)=2.7s p(95)=2.7s http_reqs......................: 1 0.266167/s iteration_duration.............: avg=3.75s min=3.75s med=3.75s max=3.75s p(90)=3.75s p(95)=3.75s iterations.....................: 1 0.266167/s vus............................: 1 min=1 max=1 vus_max........................: 1 min=1 max=1
- 使用例
-
http_req_duration
でAPIの応答時間を測る- さらにAPIごとに測っている場合は、ボトルネックを発見することができる
-
http_reqs
でシステムが処理できるリクエストの総数を測る
-
- https://grafana.com/docs/k6/latest/using-k6/metrics/#example-output
- 使用例
- 出力結果をカスタムするには
handleSummary
メソッドを利用する
つまづいたポイント
- Node.jsのライブラリは使用できないこと
- OSモジュールを用いたCPU使用率やメモリー使用率の測定はできない
- コンテキスト内(init)で、VU間共有の変数は使用できないこと
- コンテキストはVU毎に1回呼ばれるため
TIPS
- setupの結果をdefaultやteardownに受け渡すときは、dataを利用することで受渡が可能
- 検証結果をグループ化して表示するにはgroupメソッドを使用
- 何もしなければ、全部まとめて出力されるので、問題を切り分けるなどしたい場合はグループ化させておく必要がある
- https://grafana.com/docs/k6/latest/using-k6/tags-and-groups/#groups
- カスタムメトリクスを使用するにはTrendクラスを使用
- メトリクスはすべての計測結果が出力されるので、個々のAPIのメトリクスを出力させるにはカスタムメトリクスを使用する
- https://grafana.com/docs/k6/latest/javascript-api/k6-metrics/trend/
- テスト結果はHTMLファイルに出力可能
- https://grafana.com/docs/k6/latest/results-output/web-dashboard/
- グラフなどの視覚情報でテスト結果を残すことができるようになる
まとめ
k6はJavaScriptで手軽に作成できるため、テストの迅速な実施と運用を行えます。なによりも、AWSやCI/CDパイプラインとの高い親和性があります。クラウド環境や自動化プロセスにも組み込みやすく、開発サイクル全体の効率を向上させることができます。そのため、k6を使えば、ソフトウェアの信頼性と品質を向上させることができるでしょう。
参考
- ソフトウェアパフォーマンステスト | Wikipedia
- Grafana k6
Discussion