API Blueprintで書いたWeb APIをdreddでテストする


- 前々回：[API BlueprintでWeb APIのドキュメントを生成する - Qiita](http://qiita.com/yagays/items/8e16a27b058f0ddef653)
- 前回：[API Blueprintとapi-mockでモックサーバを作成する - Qiita](http://qiita.com/yagays/items/29398da51c41dc69858d)

## 概要

さて、今回はAPI Blueprintを使って作成したWeb APIがドキュメント通りに動作するかを、[dredd](https://github.com/apiaryio/dredd)を使ってテストします。

## dreddとは

dreddはAPI BlueprintをベースにしたWeb APIのテストフレームワークです。"Language-agnostic"と謳っているだけあってテストのフックにはnode.js以外にもgoやPython、Rubyなど多様な言語が利用でき、またCircleCIやJenkinsCIなどのCIのサポートもあります。

このように、API Blueprintのエコシステムに乗っかることによって、API Blueprint形式で書いた仕様からaglioを使ってドキュメント生成をし、それと同じファイルを使ってWeb APIのテストまで幅広くカバーすることができます。またこれにより、ドキュメントドリブンやテストドリブンといった形でWeb APIを開発することができますし、ドキュメントの書き忘れなどを防ぐことができます。

## dreddの初期設定

まず`dredd init`コマンドでテストの設定をします。対話型のコンソールで、以下の情報を入力します。

- 対象とするAPI Blueprintの場所とファイル名
- APIサーバの起動方法
- APIエンドポイントのURL
- テストのフックに利用する言語(nodejs,Ruby,Pythonなど)
- Apiary Test Inspectorを利用するか？
- CircleCIのconfigファイルを生成するか？



```sh
$ dredd init
? Location of the API blueprint recipe.apib
? Command to start API backend server e.g. (bundle exec rails server) python ../../bottle/sample.py
? URL of tested API endpoint http://localhost:8080/
? Programming language of hooks nodejs
? Do you want to use Apiary test inspector? No
? Dredd is best served with Continuous Integration. Create CircleCI config for Dredd? No

Configuration saved to dredd.yml

Run test now, with:

  $ dredd

```

dreddではみずからAPIサーバの起動してテストを走らせます。今回は[前々回の記事](http://qiita.com/yagays/items/8e16a27b058f0ddef653)で使用したPython+Bottleのコードを利用するため、`python ../../bottle/sample.py`のように起動コマンドを指定しています。

これでdreddを実行するための`dredd.yml`が生成されます。

## dreddでテストを行う

`dredd init`で作成した設定ファイルを元に、`dredd`コマンドでdreddを起動します。


```sh
$ dredd
info: Configuration dredd.yml found, ignoring other arguments.
info: Starting server with command: python ../../bottle/sample.py
info: Waiting 3 seconds for server command to start...
warn: Parser warning in file 'recipe.apib': (2) the resource '/recipes/{name}' is already defined on line 31
warn: Parser warning in file 'recipe.apib': (2) the resource '/recipes/{name}' is already defined on line 45
info: Beginning Dredd testing...
pass: GET /recipes/ duration: 42ms
pass: GET /recipes/name duration: 22ms
pass: DELETE /recipes/name duration: 26ms
pass: PUT /recipes/name duration: 28ms
complete: 4 passing, 0 failing, 0 errors, 0 skipped, 4 total
complete: Tests took 126ms
info: Sending SIGTERM to the backend server
info: Backend server was killed
```

dreddによるテストが終了しました。ここでは無事4つのテストがパスしており、Pythonで書かれたAPIサーバが`recipe.apib`に書いたドキュメント通りの動きをしていることが確認できました。

なお、既に上で述べたようにdreddは自分でAPIサーバを起動してテストを行うため、すでに別でAPIサーバを起動している場合はエンドポイントURLが重複してdreddがエラーとなる場合があります。そのため、通常は`http://localhost:8080/`で起動するAPIサーバの場合、dreddに登録する設定は`http://localhost:8081/`のようにした上で、APIサーバもdredd専用のportで起動するなどしたほうがいいかもしれません。

## Apiary Test Inspectorについて

`dredd init`でApiary Test Inspectorの使用を"Yes"にすると、dredd起動時に以下のようなURLが出力されます。これはdreddの結果を[Apiary.io](https://apiary.io/)のPublic Test Runにアップロードされ一時的にテストの結果を共有する機能で、ウェブでテスト結果を確認することができます。

```
complete: See results in Apiary at: https://app.apiary.io/public/tests/run/0973d151-0c39-43ca-9336-6bb1c17a8ddd
```

<img width="1254" alt="ss_2016-04-23_16_05_11.png" src="https://qiita-image-store.s3.amazonaws.com/0/4452/7013e70b-49a8-b779-3f01-8429ac330628.png">

通常Apiaryを利用する際は、アカウントを作成したでGithubのレポジトリに上げた`.apib`ファイルと連携といった形でテスト結果を管理することができますが、一時的に利用したいだけの場合などはApiary Test Inspectorを用いた共有もできます。

### 参考

- [apiaryio/dredd: Language-agnostic HTTP API Testing Framework](https://github.com/apiaryio/dredd)
- [Dredd](https://dredd.readthedocs.org/en/latest/)
- [How To Test REST API with API Blueprint and Dredd—Apiary Blog](http://blog.apiary.io/2013/10/17/How-to-test-api-with-api-blueprint-and-dredd/)
- [APIドキュメントでAPIサーバをテストする | WEB EGG](http://leko.jp/archives/800)
- [Apiaryで作成するAPIドキュメントをGitHubで管理する - Qiita](http://qiita.com/Horie1024/items/6928a0e58bf49eb24cba)