継続は力なり

タイトル通り定期的な更新を心掛けるブログです。

k6 で GraphQL のファイルアップロードテストを行う

タダです.

k6負荷試験を行うことがあり,GrapQL でのファイルアップロードを確認する必要がありました.この記事ではファイルアップロードで k6 で実施する時に使ったツールやドキュメントをまとめていきます.

k6 での GrapQL リクエストを行う方法

公式のサンプルコードがありますが,リクエストのクエリやヘッダー情報を付与して GraphQL のリクエストを実行できます.ただ,今回初めて様々な GrapQL リクエストを見て感じたのは簡単にクエリを組み立てたりすることは難しいと感じました.

import http from "k6/http";
import { sleep } from "k6";

const accessToken = "YOUR_GITHUB_ACCESS_TOKEN";

export default function () {
  const query = `   
    query FindFirstIssue {  
      repository(owner:"grafana", name:"k6") {  
        issues(first:1) {   
          edges {   
            node {  
              title 
            }   
          }
        }
      }
    }`;

  const headers = {
    Authorization: `Bearer ${accessToken}`,
    "Content-Type": "application/json",
  };
  http.post(
    "https://api.github.com/graphql",
    JSON.stringify({ query: query }),
    { headers: headers }
  );
  sleep(0.3);
}

HAR ファイルから k6 のテストを生成する

そこで,今回は har-to-k6 とう言うツールを使いました.これは HAR ファイルから k6 のテストを生成するツールでまさに今回のケースにあっていました.README にも記載がありますが,HAR ファイルからテストファイルを生成するためには次のコマンドを実行すれば生成できるので,テストを行いたいサービスで対象の GrapQL リクエストを行った結果を HAR ファイルをダウンロードすれば OK です.

github.com

$ npx har-to-k6 hoge.har -o [テストファイル名].ts

har-to-k6 を使いテストの GraphQL のリクエスト部分を生成しました.

ファイルアップロードのテストのために行ったこと

ファイルアップロード部分で参照したのがこのドキュメントになります.今回のファイルアップロードではバイナリデータで PDF をマルチパートアップロードする必要があったので,以下のようなコードを書いて k6 でアップロードすることができました.上述の har-to-k6 で生成したコードではバイナリデータの部分は {binary} と表示されてどういったデータが入っているか分からず色々試していたんですが,最終的に http.file(data, [filename], [contentType])http.file(open関数で取得したデータ, ファイル名, application/pdf) にして k6 を実行するとファイルアップロードができました.

import http from 'k6/http';
import { check } from 'k6';
import { FormData } from 'https://jslib.k6.io/formdata/0.0.2/index.js';

const pdf = open('../test-files/hoge.pdf', 'b');

export default function () {
  const fd = new FormData();
  fd.append('someTextField', 'someValue');
  fd.append('pdf', http.file(pdf, 'test.pdf', 'application/pdf'));

  const res = http.post('https://(ドメイン)/(エンドポイント)', fd.body(), {
    headers: { 'Content-Type': 'multipart/form-data; boundary=' + fd.boundary },
  });
  check(res, {
    'is status 200': (r) => r.status === 200,
  });
  if(!check(res, { 'is status 200': (r) => r.status === 200 })) {
    console.log(res.body);
  }
}

まとめ

k6 で GraphQL のファイルアップロードテストを行う時に必要だった対応をまとめました.