はじめに
CIで継続的にテストを実施することは、プロダクト開発において非常に重要です。
負荷試験においても上記は例外ではなく、久しぶりに負荷スクリプトを動かしてみたら、全く動かなかった。という事態は避けたいものです。
今回は、CI上でモック用のAPIサーバに対してk6の負荷スクリプトを実行し、継続的な自動テストを実現します。
なお、本記事は以下の記事でモック用のAPIサーバを立てていることが前提となっています。
必要に応じて、以下の記事もご覧くださいませ。
実現すること
こちらのPRで実行されているような、mockTestForSampleApp
CIをGitHubActionsで定義し、自動で実行します。結論だけ知りたい方は、以下のPRをご覧くださいませ。
https://github.com/gonkunkun/k6-template/pull/3
CIを用意する
前提知識
以下のサンプルリポジトリをベースに説明いたします。
https://github.com/gonkunkun/k6-template
CI上の登場人物は以下の通りです。
k6
- 拡張機能を扱うために、xk6を利用しています
- 実行コマンドはgoでbuildして生成しています
Redis
- ユーザデータの格納のために利用しています
- 詳細は以下の記事で説明しています
- https://gonkunblog.com/k6-how-to-get-options-settings/1914/
Mock API Server
- k6から実際のAPIサーバをCallするのではなく、代わりにMock用のAPI ServerをCallしています
構築
CI用のenvファイル(.env.c
)を準備する。
AMOUNT_OF_INDEX_SIZE_FOR_TEST_DATA=10000
DEBUG=true
ENV=local
SAMPLE_PRODUCT_ENDPOINT=http://localhost:3005
REDIS_ENDPOINT=redis://localhost:6379
.github/workflows/mockTest.yml
を作成する。
name: mockTest
on: [pull_request]
jobs:
mockTestForSampleApp:
runs-on: ubuntu-latest
services:
redis:
image: redis
ports:
- 6379:6379
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 21
cache: 'npm'
- name: Cache npm directory
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
- name: Install npm dependencies for k6
run: npm install
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.22'
cache-dependency-path: '**/*.sum'
- name: Install xk6
run: go install go.k6.io/xk6/cmd/xk6@latest
- name: Cache k6 binary
uses: actions/cache@v4
id: cache-k6-binary
with:
path: k6
key: ${{ runner.os }}-k6-${{ hashFiles('**/k6.*') }}
restore-keys: |
${{ runner.os }}-k6-
- name: Build k6 with plugins
if: steps.cache-k6-binary.outputs.cache-hit != 'true'
run: |
xk6 build \
--with github.com/LeonAdato/xk6-output-statsd@latest \
--with github.com/grafana/xk6-dashboard@latest \
--with github.com/szkiba/xk6-enhanced@latest \
--with github.com/szkiba/xk6-dotenv@latest
- name: Set up environment variables
run: cp .env.ci .env
- name: Start mock endpoint
run: |
cd mock
npm install
npx ts-node ./src/index.ts 3005 &
- name: Cache k6 bundle files
uses: actions/cache@v4
id: cache-k6-bundle-files
with:
path: dist
key: ${{ runner.os }}-dist-${{ hashFiles('dist/**') }}
restore-keys: |
${{ runner.os }}-dist-
- name: Bundle k6 scripts
if: steps.cache-k6-bundle-files.outputs.cache-hit != 'true'
run: npm run bundle
- name: Run k6 smoke test
run: npm run smoke:sample-product
諸々の環境を準備したうえで、最後にスモークテスト用のシナリオを実行しています。
run: npm run smoke:sample-product
後は、普通にPRを作成してみて、CIが動作することを確かめましょう。
CIの実行ログを見てみると、無事にk6が動いていることが確認出来ます。
なお、一部cacheが上手く効いていない箇所があります。
今後の課題ということでご勘弁くださいませ。
おわりに
CIによって、毎回k6のシナリオが壊れていないことを確認出来るようにりました。
本記事で利用していたリポジトリの説明は、以下の記事でしています。
興味がある方はこちらもご覧くださいませ。
負荷試験スクリプトのテストコードをどこまで書くべきなのか、これは議論が分かれるところだと思います。
今回の例では、k6が実行出来てシナリオが動き切るところまでは確認出来ますが、シナリオ内で叩かれるモジュール、APIの振る舞いの担保は出来ていません。
この辺、上手いやり方をご存じの方がいたら、こっそりご連絡ください…
ここまで読んでいただき、ありがとうございました。