🤖

openapiから高速非同期ログインテスト!raxtestのご紹介

2023/04/04に公開

はじめに

こんにちは。calloc134です。情報工学を学ぶ学生です。
突然ですが皆さん、APIのテストをどのように行っていますか?
APIのテストの使われるツールといえば、postmanやdredd等がありますね。

さて、自分もAPIのテストを行いたいと思い、これらのツールを試行錯誤していましたが、どうも自分のやりたいこととズレているようでした。
最終的に、

  • openapiスキーマからテストをある程度生成できる(example値も参照する)
  • ログインしてクッキーを付与しながらテストを行える
  • 非同期でリクエストを行い、高速に実行できる
  • 結果をjsonで出力し、CI/CDに組み込みやすい

というテストツールがあればいいのに、と思いました。

そこで、自分で作ってみました!
(結構ChatGPTやGithub Conpilotにも協力をしてもらいました 笑)

誕生したのが、"raxtest" & "openapi2raxtest" という二つのOSSです。
https://github.com/calloc134/raxtest
https://github.com/calloc134/openapi2raxtest

openapi2raxtestでは、openapiスキーマからテスト定義ファイルを生成します。
Go言語で開発し、kin-openapiモジュールを利用しています。
raxtestでは、テスト定義ファイルを読み込み、テストを実行します。
Rustで開発し、tokioで非同期、reqwestでリクエストを行います。

ドキュメントは以下のリンクから見ることができます。

https://calloc134.github.io/raxtest/

では、これらの使い方を解説します。

使い方の例

以下のコマンドでテストを実行できます。

$ raxtest -i raxtest.yml -o output.json

-iオプションでインプットファイルを指定し、-oオプションでテスト結果の出力ファイルを指定します。

raxtestのテスト定義ファイルの書き方を説明します。
ざっくりこんな感じです。

base_url: http://localhost
data: json://out.json
init:
- name: LoginStep
  path: /api/auth/login
  method: POST
  ref_data: LoginData
  option:
    query: false
    body: true
categories:
  LoginCategory
    login: LoginStep
    steps:
    - name: UpdateMyProfile
      path: /api/profile/me
      method: PUT
      ref_data: MyProfileData
      option:
        query: false
        body: true

ここで、querybodyなどのタグには、data.jsonで定義したデータを参照することができるようになっています。
また、カテゴリ内のloginオプションでは、initの中に含まれているステップでのクッキー情報を参照することができます。

上述のとおり、このbodyqueryなどのタグに対応するデータを、data.jsonで定義することができます。
ここにおいて、データは複数定義することができ、テストの実行時にはすべてのデータがそれぞれ実行されます。

{
  "LoginStep": [
    {
      "body": {
        "password": "dummy",
        "screenName": "dummy"
      },
      "expect_status": 0
    }
  ],
  "UpdateMyProfile": [
    {
      "body": {
        "password": "dummy",
        "screenName": "dummy",
        "userName": "dummy"
      },
      "expect_status": 200
    }
  ],
}

テストは並列でリクエストが送信されるので、大量にテストがあっても爆速で実行できます!

テスト結果

テストが終わると、output.jsonに出力されます。

{
  "base_url": "http://localhost",
  "results": [
    {
      "name": "no_login/ApiUserMe(DELETE)[0]",
      "category": "no_login",
      "status": "success",
      "duration": 0.0126284,
      "message": "success (status: 401 Unauthorized, expect status: 401)"
    },
    {
      "name": "no_login/ApiUserMe(GET)[0]",
      "category": "no_login",
      "status": "success",
      "duration": 0.0099064,
      "message": "success (status: 401 Unauthorized, expect status: 401)"
    },
    {
      "name": "no_login/ApiUserMe(PUT)[0]",
      "category": "no_login",
      "status": "success",
      "duration": 0.007595,
      "message": "success (status: 401 Unauthorized, expect status: 401)"
    },
    ...
  ]
}

このようにして、テストの名前や成功の可否、所要時間などが出力されます。
json形式で出力されるため、CI/CDに非常に組み込みやすくなっています。

openapiスキーマよりテストを生成

テストの定義ファイルを書くのが面倒な人は、openapi2raxtestを使うと、OpenAPIの定義ファイルからテスト定義ファイルを生成できます。

$ openapi2raxtest -i openapi.yaml -o raxtest.yaml -d data.json -s http://localhost:8080

-iオプションでopenapiスキーマファイルを、-dオプションで出力する先のデータファイルのパスを、-sオプションでテストを実行するサーバのURLを指定します。
デフォルトではAPIのパスに「login」が含まれていればinitステップに分離してそのカテゴリを作成するようになっています。
ただ、細かい修正は手動で行う必要があるかもしれません。
raxtestとopenapi2raxtestのより詳しい使い方は、ドキュメントを参照してください。

注意事項

動作確認はローカルで行いましたが、バグが含まれている可能性があります。
バグを見つけた場合は暖かい目で、イシューで知らせてもらうか、プルリクエストを送ってもらえると嬉しいです。

このツールを気に入っていただけたら、スターをよろしくお願いします!
https://github.com/calloc134/raxtest
https://github.com/calloc134/openapi2raxtest

それでは、良いAPIテストを!

GitHubで編集を提案

Discussion