Claude Codeでk6の負荷テストスクリプトを作成する手順
Claude Codeにk6のJSシナリオを生成させ、しきい値とステージ設計、GitHub Actionsへの組み込みまでを手順化します。
Claude Codeにk6のシナリオを書かせると、雛形生成からしきい値設計、CI組み込みまでの反復作業を短くできます。対象エンドポイントとVU数(仮想ユーザー数)を伝えるだけで、k6のJavaScript構文に沿ったスクリプトが返ってきます。この記事では、基本シナリオの生成からGitHub Actionsへの組み込みまでを手順化します。
Claude Codeでk6スクリプトを書かせるとはどんな作業か
k6はGrafana Labsが開発するオープンソースの負荷テストツールで、テストシナリオをJavaScriptで記述します。HTTPリクエストベースの負荷テストが中心ですが、k6 browser APIを使えばブラウザを操作するシナリオも同じ構文で書け、CI/CDへの組み込みや障害注入を使ったカオステストにも対応します。Claude Codeはk6専用の統合機能を持つわけではなく、他のテストコードを書かせる作業と同じ、通常のコーディング支援としてk6のスクリプトを生成します。
そのため精度を左右するのは、対象URL・リクエスト方式・想定VU数・実行時間といった条件をどれだけ具体的に伝えるかです。既存コードにテストを書かせる進め方全般はClaude Codeでテストを書かせる実践手順にまとめており、対象を絞って条件を先に固めるという考え方はk6のシナリオ生成でも同じです。
前提条件
k6のCLIをローカルまたはCI環境にインストールしておきます。Macではbrew install k6、Debian/Ubuntu系ではAPTリポジトリ経由のパッケージが公式に用意されています。
brew install k6Dockerイメージgrafana/k6も配布されているため、CLIを直接インストールしたくない場合はコンテナ経由でも実行できます。加えて、テスト対象は本番環境ではなくステージングや専用の負荷テスト環境を用意します。実際に負荷をかけるテストなので、対象システムの許可なく本番URLに向けて実行しないよう注意します。
複数のパッケージでk6スクリプトを書く機会が繰り返しあるチームは、対象エンドポイントの命名規則やしきい値の既定値をSKILL.mdにまとめておくと、Claude Codeが毎回同じ規約でスクリプトを生成します。モノレポでテスト規約をSKILL.mdに教える手順はClaude Codeモノレポのテスト戦略をSKILL.mdで教える手順にまとめています。
手順1: 基本シナリオをClaude Codeに生成させる
最初に、対象エンドポイントと負荷条件を具体的に伝えて雛形を生成させます。
k6でJSのロードテストスクリプトを書いて。対象はhttps://staging.example.com/healthへのGETリクエスト、5 VUsで30秒間実行してこの指示から、Claude Codeは次のような雛形を生成します。
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
vus: 5,
duration: '30s',
};
export default function () {
http.get('https://staging.example.com/health');
sleep(1);
}k6のスクリプトは2種類のコードで構成されます。optionsを定義する部分は初期化コードでVUごとに1回だけ実行され、export default functionの中身がVUコードとして繰り返し実行されます。VU(仮想ユーザー)は並列に動くwhile(true)ループに近いモデルで、VU数を増やすほど同時実行される仮想ユーザーが増えます。
実際のAPIは単一エンドポイントだけで完結しないことが多く、ログインしてトークンを受け取り、そのトークンを使って認証済みリクエストを送るという流れを再現したい場面があります。「ログインAPIをPOSTで呼び、レスポンスのトークンをAuthorizationヘッダーに載せて/profileへGETして」のように依存関係まで含めて指示すると、Claude Codeは1回のVU実行の中で複数のhttpリクエストを順に呼び出し、各レスポンスを検証するスクリプトを生成します。
対象URLをスクリプトに直書きすると、ステージングと本番、PRごとのプレビュー環境で使い分けにくくなります。__ENV.TARGET_URLのように環境変数からURLを読み込む形にしておくと、k6 run -e TARGET_URL=https://staging.example.com/health script.jsのようにCLIから対象を切り替えられます。GitHub Actionsに組み込むときも、この仕組みのままワークフロー側のflagsから値を渡せます。
生成したスクリプトはk6 runコマンドで実行します。
k6 run script.js手順2: しきい値とステージで本番想定に近づける
固定VU数の一発実行だけでは、実運用に近い負荷パターンを再現できません。Claude Codeに「立ち上がりと収束を含めたステージ構成にして」と伝えると、stages配列を使ったランピング設計に書き換えてくれます。
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '30s', target: 20 },
{ duration: '1m30s', target: 10 },
{ duration: '20s', target: 0 },
],
thresholds: {
http_req_failed: ['rate<0.01'],
http_req_duration: ['p(95)<200'],
},
};
export default function () {
const res = http.get('https://staging.example.com/health');
check(res, { 'status was 200': (r) => r.status === 200 });
sleep(1);
}thresholdsはテストの合否を決める条件です。上の例では、HTTPエラー率が1%未満かつ95パーセンタイルのレスポンス時間が200ms未満であることを求めています。条件を満たさなければk6は非ゼロの終了コードで終わるため、そのままCIの合否判定に使えます。
check()はしきい値と役割が違います。checkは個々のレスポンスに対するアサーションで、失敗してもテスト自体は止まらず、成功と失敗の件数をchecks_succeeded・checks_failedというメトリクスに記録するだけです。特定のリクエストで期待どおりのステータスコードが返っているかを都度確認しつつ、テスト全体の合否はしきい値側で判定する、という役割分担が基本形になります。checkの成功率自体をゲートにしたい場合は、checksメトリクスにもしきい値を設定して両者を組み合わせます。
しきい値の集計方法はメトリクスの型によって変わります。
| メトリクス型 | 使える集計方法 |
|---|---|
| Counter | 使える集計方法count、rate |
| Gauge | 使える集計方法value |
| Rate | 使える集計方法rate |
| Trend | 使える集計方法avg、min、max、med、p(N)(パーセンタイル) |
どのくらいのVU数・実行時間を選ぶべきかは、テストの目的によって変わります。k6公式は6種類のテストタイプを挙げており、Claude Codeに条件を伝えるときの目安になります。
| タイプ | VU/スループット | 実行時間 | 使うタイミング |
|---|---|---|---|
| Smoke | VU/スループット低い | 実行時間数秒〜数分 | 使うタイミングコード変更のたびに、最低限の動作を確認する |
| Load | VU/スループット想定される通常運用相当 | 実行時間5〜60分 | 使うタイミング平常時の性能を確認する |
| Stress | VU/スループット想定を上回る高負荷 | 実行時間5〜60分 | 使うタイミング想定超えの負荷にどう耐えるかを確認する |
| Soak | VU/スループット平常運用相当 | 実行時間数時間 | 使うタイミング変更後に長時間稼働での劣化を確認する |
| Spike | VU/スループット非常に高い | 実行時間数分 | 使うタイミング突発的なトラフィック急増への耐性を確認する |
| Breakpoint | VU/スループット限界まで段階的に増加 | 実行時間必要な分だけ | 使うタイミングシステムの上限を探る |
いきなりStressやSoakから始めず、まずSmokeでスクリプト自体が正しく動くかを確認してから段階を上げるのが公式の推奨です。
手順3: GitHub Actionsに組み込む
k6を継続的に実行するには、CIパイプラインへの組み込みが定番です。以前はgrafana/k6-actionという単体のGitHub Actionが使われていましたが、このActionはアーカイブされ保守が止まっています。現在の公式手順は、k6のセットアップを担うsetup-k6-actionと実行を担うrun-k6-actionを組み合わせる方式です。
Claude Codeにワークフローの生成を依頼する場合は、対象スクリプトのパスとトリガー条件を伝えます。
scripts/load-test.jsをpush時に実行するGitHub Actionsワークフローを書いて。setup-k6-actionとrun-k6-actionを使って生成されるワークフローは次のような形になります。
name: Load test
on: [push]
jobs:
load-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: grafana/setup-k6-action@v1
- uses: grafana/run-k6-action@v1
with:
path: |
./scripts/load-test.jsGrafana Cloud k6に結果を送りたい場合は、K6_CLOUD_TOKENとK6_CLOUD_PROJECT_IDをGitHub ActionsのSecretsに登録し、envとして渡します。トークンをワークフローファイルに直書きしないよう、必ずSecrets経由にします。
run-k6-actionにはdebugやfail-fastといった入力もあります。既定ではサマリーだけがログに出ますが、debug: trueにするとk6の実行ログがそのままGitHub Actionsのログに出力されます。複数のスクリプトを並列実行しつつ、最初の失敗で処理を止めたい場合はfail-fast: trueを指定します。
CI環境の作り込み自体をClaude Codeに任せる進め方はClaude Codeセルフホスト環境をCIでE2Eテストするでも扱っており、認証情報をSecrets経由で渡す考え方は今回のk6連携とも共通します。
よくあるつまずき
古いgrafana/k6-actionの例をそのままコピーする。ブログ記事やStack Overflowの過去の回答には旧Action単体の例が多く残っています。新規にワークフローを組むときは、保守が続いているsetup-k6-actionとrun-k6-actionの組み合わせに寄せます。
VU数を上げれば必ずリクエスト数が増えると思い込む。VUは並列ループのモデルなので、レスポンスが遅くなるとVUあたりの反復回数が減り、リクエスト数はVU数に比例しません。リクエスト数そのものを制御したい場合は、VUベースではなくイテレーション/秒ベースのシナリオ設計を検討します。
しきい値を「テストを止める条件」と誤解する。デフォルトのしきい値は、テスト終了後に合否を判定するだけで、条件を満たさない時点で実行を中断するわけではありません。しきい値の設定でabortOnFailを指定した場合のみ、条件を割った時点でテストが打ち切られます。
大規模な負荷テストを本番デプロイをブロックするパイプラインに組み込む。1回の実行に3〜15分以上かかることも珍しくなく、デプロイ直前のパイプラインに組み込むとリリース全体が長引きます。公式ガイドも、大規模テストは自動デプロイ用パイプラインの外、専用環境でのリリース前検証に回すことを勧めています。
しきい値のPass/Failをそのままリリースのゲートにする。テスト対象のスクリプトやSLO自体が誤っている可能性もあるため、しきい値の判定結果は「詳しい調査が必要なシグナル」として扱い、判定基準がこなれるまでは全面的なブロック条件にしないという考え方が公式に案内されています。
まとめ
Claude Codeでk6の負荷テストスクリプトを作るときは、まず単純な固定VUの雛形をSmoke相当で動かし、次にステージとしきい値を足して本番想定に近づけ、最後にsetup-k6-action/run-k6-actionでCIに組み込む、という順で進めると安定します。テストタイプごとのVU数・実行時間の目安を先に押さえておくと、Claude Codeへの指示も具体的になります。ユニットテストの生成手順を先に押さえておくと、k6のシナリオ生成でも同じ「条件を先に固めてから生成させる」進め方がそのまま活きます。