PostmanとNewmanを組み合わせて、CI/CDに組み込むREST APIの自動テストを作ろう！

## はじめに

REST APIのテストツール、テストが書きやすくてCLIベースで動くものを探していたんですが、[Postman](https://www.getpostman.com/)と[Newman](https://github.com/postmanlabs/newman)の組み合わせが神だったのでご紹介です。
これらを使うとざっくりこんなことが出来ます。

1. REST API実行する
2. 実行したAPIのresponseをチェックするテストスクリプトを作る
3. 作ったテストスクリプトをjsonファイルにexport
4. CI/CDでこのスクリプトを実行するようjenkinsジョブを作る

このざっくり説明で少しでも興味を持った方、ざっくり使い方を見ていってください。

## [Postman](https://www.getpostman.com/)

Postmanは、APIを持つソフトウェアの開発を簡単にするためのツールです。アイコンかわいい(大事

<img width="500" alt="postman" src="https://assets.getpostman.com/common-share/postman-logo-horizontal-white.svg">

### 出来ること

- APIテストを作ることができる
    - UIでREST APIの実行確認が出来る。
        - headerやbodyも入力可能。量が多いのでUIベースの方が楽だったりしますよね
    - 実行したAPIのresponseをチェックするテストを比較的簡単に書ける
        - テストコードの書き方に戸惑うもんですが、サンプルコードが出てくるのでまあやれるでしょう
- 作ったテストをjsonファイルに出力できる
    - 共有らくちん

### 使い方

#### 準備

まずは[Get started](https://www.getpostman.com/downloads/)からインストーラーをダウンロードしてインストールしてください。Windows/Mac OS/Linuxサポートしてます。
インストールしたツールを起動したらまずはログイン。アカウントを作成するか、Googleアカウントを利用することが出来ます。

<img width="950" alt="login.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252277/5d28eae4-9c78-5df9-d214-3ca8fc854095.png">

#### APIテストを作る

ログインしたらテストスクリプトを作成しましょう。スクリプトはCollectionと呼ばれる単位で作成し、そのCollectionの中にAPIを記載していきます。
Collection > APIsの構成。

<img width="1000" alt="APIDefine.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252277/9eb5ae89-1009-0e09-0993-8968156ceaf5.png">

Add requests もしくはNewからRequestを追加・選択した状態がこれ。Query, Header, Bodyや、Authorization等細かなパラメータを指定できるので、REST APIツールとしても満足できます。

<img width="950" alt="API check.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252277/16421436-10df-ef6c-d083-c02354b9f55a.png">

さて、テストスクリプトを作るには結果をチェックするテストスクリプトがいりますね。Testsタブで何やら書けそう。でもどうすればいいんだろう。。。
と困ったら右のボックスに試験から似たものをクリックしてみましょう。そのコードがTestsに反映されるので、後は編集するだけ。割と楽ちんですね
<img width="950" alt="pushjson.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252277/e54d713f-c99f-994f-b3ab-b3690e7d44d7.png">

このテスト、使い勝手を良くするためには例えば環境変数からIPを取ってきたり、レスポンスの内容を次のテストで利用したりなんていうことも出来るようです。安心
[Postmanを使ってWeb APIにアクセスする その2](https://sendgrid.kke.co.jp/blog/?p=8796)

作り終えたら実行。Collection横の再生ボタンを押し、Runでテスト実行が出来ます。
<img width="952" alt="run.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252277/e8a31295-d61b-e179-57b5-032ac0b35bc1.png">

#### 環境変数を使って値を使いまわす

Postmanでは、環境変数を設定することで環境による切り替えが可能です。
また、TestScriptの中で環境設定の変更も可能なため、API実行結果を別のAPIで利用することが出来ます。

右側の歯車マークを押すとこのような画面が出てきて、環境変数を設定できます。こちらはテストケースと別にファイルをエクスポートすることが可能です。

<img width="960" alt="環境変数.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252277/03bd9661-d5ff-c009-0ee9-cdc0483308bd.png">

値はkey/value形式で保存。

<img width="600" alt="permission.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252277/3ecd125f-5260-beb0-ddbe-f1c02cd2e85f.png">

作成した環境変数は、右上のプルダウンによって指定することが可能で、Requestパラメータに対しては`{{access_token}}`のように`{{}}`でくくることで利用することが出来ます。

TestScriptsの中で使う場合は、`pm.environment.get("XXX");`, `pm.environment.set("XXX", value);`という使い方をします。


<details><summary>サンプルとしてQiitaAPIを叩くスクリプトを貼っておきます(テスト感はないですが)。興味がある方は開いてみてください。</summary><div>

```json:Testcase.json
{
	"info": {
		"_postman_id": "f87211e1-edf5-4bce-9305-bfab5ce7e93b",
		"name": "QiitaTest",
		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
	},
	"item": [
		{
			"name": "QiitaItemGet",
			"event": [
				{
					"listen": "test",
					"script": {
						"id": "481d2d73-4dc5-4fd4-befb-6c3495bfc0af",
						"exec": [
							"",
							"pm.test(\"Status code is 200\", function () {",
							"    pm.response.to.have.status(200);",
							"});",
							"",
							"pm.test(\"Reponse number check\", function () {",
							"    //get data from env",
							"    var value = pm.environment.get(\"env_val_result\");",
							"",
							"    //json parse",
							"    var jsonData = pm.response.json();",
							"    pm.expect(String(jsonData.length)).to.eql(value)",
							"})",
							"",
							"pm.test(\"Reponse body check\", function () {",
							"    var jsonData = pm.response.json();",
							"    for (var i = 0; i < 2; i ++ ){",
							"        pm.expect(jsonData[i][\"group\"] == null).to.true",
							"    }",
							"});",
							""
						],
						"type": "text/javascript"
					}
				}
			],
			"request": {
				"auth": {
					"type": "noauth"
				},
				"method": "GET",
				"header": [
					{
						"key": "Authorization",
						"value": "Bearer {{access_token}}",
						"type": "text"
					}
				],
				"url": {
					"raw": "https://qiita.com/api/v2/authenticated_user/items?page=1&per_page={{env_val_result}}",
					"protocol": "https",
					"host": [
						"qiita",
						"com"
					],
					"path": [
						"api",
						"v2",
						"authenticated_user",
						"items"
					],
					"query": [
						{
							"key": "page",
							"value": "1"
						},
						{
							"key": "per_page",
							"value": "{{env_val_result}}"
						}
					]
				}
			},
			"response": []
		}
	]
}
```

access_tokenを正しいものにしないとエラーとなります。

```json:TestEnvironment.json
{
	"id": "df3993ba-1827-47a9-8ef3-b33530c9ff05",
	"name": "QiitaSample",
	"values": [
		{
			"key": "access_token",
			"value": "aaaaaaaa",
			"enabled": true
		},
		{
			"key": "env_val_result",
			"value": "2",
			"enabled": true
		}
	],
	"_postman_variable_scope": "environment",
	"_postman_exported_at": "2019-08-08T14:48:36.520Z",
	"_postman_exported_using": "Postman/7.3.6"
}
```

</div></details>

#### 作ったテストをjsonファイルに出力

Collectionの...をクリックし、Exportを選択するとjsonファイルが出力できます。

<img width="952" alt="Export.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252277/f7ab309a-3464-050d-c5f8-53da34d773a7.png">

同じく設定した環境変数ファイルもjsonファイルに出力することが出来ます。

## [Newman](https://github.com/postmanlabs/newman)

### 出来ること

- postmanで作ったjsonファイルをCLIで実行できる
    - UIベーステストの欠点、CI/CDに組み込みにくい問題を完全解決！

### 使い方

npmでnewmanをインストールします。

```
npm install -g newman
```

後はPostmanからexportしたjsonファイルを引数に指定するだけ。

```
newman run exported_json_file.json
```

Postmanで設定した環境変数ファイルは `-e` オプションで指定します。

```
newman run -e exported_environment.json exported_json_file.json
```

newman公式より
![](https://raw.githubusercontent.com/postmanlabs/postmanlabs.github.io/develop/global-artefacts/newman-terminal.gif)

## セットで出来ること

1. PostmanでUIベースのAPIテスト(Collection)を作る。
2. 作ったテストをjsonファイルで出力し保存
3. `newman run exported_json_file.json` でテストを実行

というわけで、編集はUI、実行はCLIという形での運用が良さそうです。

### 追加の補足ツール

[swagger2-to-postman](https://github.com/postmanlabs/swagger2-to-postman)というツールで、Postmanにimport出来るjsonファイルを出力することが出来ます。
使い勝手が悪いので、[swagger から postman の設定ファイルを作成し自動 API テストを行う](https://qiita.com/moaikids/items/1e05ef2595504689fe3e)という記事のコードをほぼそのまま流用。
npm install出来るようにする必要もあったので[swagger2-to-postman-sample](https://github.com/developer-kikikaikai/swagger2-to-postman-sample)にリポジトリ化しました。
以下コマンドでファイル出力できます。

```
git clone https://github.com/developer-kikikaikai/swagger2-to-postman-sample.git
cd swagger2-to-postman-sample
npm install
./cli.js -i input.json  > output.json
```

Bodyのデータがjsonフォーマットではなく"Pet to add to the store"というDescriptionが書いてあるだけという状態だったりしますが、忘れやすいヘッダーも設定してくれてるのでそれなりに使い勝手は良さそうです。

## 最後に

API開発者の方には定番と思われる神ツールを紹介しました。UIのテストツールはCI/CDに組み込みにくいという思い込みがあったためスルーしてきたんですが、こんな組み合わせ方があったとは。
UIはこの辺が困るよな～っていうかゆい所に手が届く、素晴らしいツールでした。皆さん、これで楽しいテストライフを！

## 参考

公式:
[Postman](https://www.getpostman.com/)
[Newman](https://github.com/postmanlabs/newman)
[swagger2-to-postman-sample](https://github.com/developer-kikikaikai/swagger2-to-postman-sample)
[OpenAPI-Specification](https://github.com/OAI/OpenAPI-Specification)

メイン記事の参考:
[PostmanとNewmanを使って複数のAPIを連続して実行させる](https://itneko.com/postman-newman/)
[swagger から postman の設定ファイルを作成し自動 API テストを行う](https://qiita.com/moaikids/items/1e05ef2595504689fe3e)