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

# はじめに
最近サーバーレスを良くやっているので、
APIのテストを書きたくて、いいフレームワークを探していました。
とりあえず動くところまで行けたので、覚書しておきます。
まだまだjsは初心者なので、ご指摘いただけたら幸いです。

# 環境
* PC: Macbook Pro
* OS: macOS High Sierra
* Node.js: 6.13.0

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

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

https://github.com/vlucas/frisby

###シンプルに書ける

```javascript

const frisby = require('frisby');

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

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

```javascript
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を直接アサーションに記述できるとか。
使ってませんが。

# 環境構築

## インストール
環境構築や使い方は[こちら](https://qiita.com/H1Gdev/items/7aa5ca8a78839c615ac4)を参考にさせてもらいました。

```bash
$ npm install frisby --save-dev
$ npm install jest --save-dev
```
## package.json
`npm run apitest`で実行できるように、package.jsonも修正しておきましょう。

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


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


```javascript:__tests__/api.spec.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 + '/api１',
        {
            "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 + '/api２？req_body1=' + arg４)
        .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で書いたサーバーレスAPIが
Pythonでut,it、NodeでAPItestとある程度テストをかけて大変うれしい次第です。
サーバーレスアーキテクチャって微妙にデバッグしにくいのは自分だけでしょうか？
APIのテスト、みんなどう書いてるんでしょ？