Pippi Life

主に仕事に関連するITのことや、プライベートもちょいちょい書きます。

APIのテスト書いたので覚書

はじめに

最近サーバーレスを良くやっているので、 APIのテストを書きたくて、いいフレームワークを探していました。 とりあえず動くところまで行けたので、覚書しておきます。

環境

やりたいこと

  • 学習コストが少なくAPIテストをテストを書きたい
  • メンテナンスしやすいこと
  • レスポンスの値を、後続のテストケースで使いたい。

Frisby + Jest

さがしていて出会ったのが、Frisby + Jestという構成 frisbyはAPIテストのフレームワーク、Jestが実行環境みたいです。

https://github.com/vlucas/frisby

シンプルに書ける

const frisby = require('frisby');

it('should be a teapot', function (done) {
  frisby.get('http://httpbin.org/status/418')
    .expect('status', 418)
    .done(done);
});

ネストした処理も記述できる

const frisby = require('frisby');
const Joi = frisby.Joi; // Joiは便利らしい

describe('Posts', function () {
  it('should return all posts and first post should have comments', function (done) {
    frisby.get('http://jsonplaceholder.typicode.com/posts')
      .expect('status', 200)
      .expect('jsonTypes', '*', {
        userId: Joi.number(),
        id: Joi.number(),
        title: Joi.string(),
        body: Joi.string()
      })
      .then(function (res) { // res = FrisbyResponse object
        let postId = res.json[0].id;

        // これでやりたかったこともできる
        return frisby.get('http://jsonplaceholder.typicode.com/posts/' + postId + '/comments')
          .expect('status', 200)
          .expect('json', '*', {
            postId: postId
          })
          .expect('jsonTypes', '*', {
            postId: Joi.number(),
            id: Joi.number(),
            name: Joi.string(),
            email: Joi.string().email(),
            body: Joi.string()
          });
      })
      .done(done);
  });
});

ビルトインのアサーションも豊富

  • status
  • header
  • json
  • jsonStrict
  • jsonTypes
  • jsonTypesStrict
  • bodyContains

他にも拡張ハンドラが作成できる、とかJasmine Matcherを直接アサーションに記述できるとか。 使ってませんが。

環境構築

インストール

環境構築や使い方はこちらを参考にさせてもらいました。

$ npm install frisby --save-dev
$ npm install jest --save-dev

package.json

npm run apitestで実行できるように、package.jsonも修正しておきましょう。

:
:
  },
  "devDependencies": {
    "frisby": "^2.0.14",
    "jest": "^22.4.3",
  },
  "scripts": {
    "apitest": "jest"
  }
:

テスト書いてみる

Jestは、__test__フォルダ配下か、 .spec.js もしくは .test.js のファイル名をフィルタして、 テスト実行してくれるみたいです。

const frisby = require('frisby');
const Joi = frisby.Joi;

var target_host = 'https://hostname';
var arg1 = 'sample';
var arg2 = '1234567890';

var arg3 = "";
var arg4 = "";

it('__正常系__JSONアサーション', function (done) {
    frisby.post(target_host + '/api1',
        {
            "req_body1": arg1,
            "req_body2": arg2
        }
    )
        // ステータスコードのアサーション
        .expect('status', 200)
        // jsonのアサーションはこう書く
        .expect('jsonTypes', '', {
            'res_body1': Joi.string().required(),
            'res_body2': Joi.string().required()
        })
        .then(function (res) {
            // arg3,4は後続のテストでも使用できる。
            arg3 = res.json.res_body1;
            arg4 = res.json.res_body2;
            // コンソールにログを出力もできる
            console.log(arg3);
            console.log(arg4);
        })
        .done(done);
});


it('__正常系__JSONのリストアサーション', function (done) {
    frisby.setup({
        request: {
            //例えばレスポンスの値を、ヘッダーに追加してリクエストしたいとき
            headers: {
                'Authorization': arg3
            }
        }
    })
        .get(target_host + '/api2?req_body1=' + arg4)
        .expect('status', 200)
        // listのアサーション
        .expect('jsonTypes', '', {
            'res_body3': Joi.array()
        })
        .then(function (res) {
            // リストの中身のアサーション
            expect(res.json.res_body3[0].aaa).toBe("bbb");
        })
        .done(done);
});

expectの中身はまだまだ勉強が必要です。 ネット上の情報を見る限り、決め打ちのjsonアサーションもできる気がします。 これでPythonで書いたサーバーレスAPIPythonでut,it、NodeでAPItestとある程度テストをかけて大変うれしい次第です。 サーバーレスアーキテクチャって微妙にデバッグしにくいのは自分だけでしょうか? APIのテスト、みんなどう書いてるんでしょ?

qiitaにもあります。