[ツール] PostmanでAPI疎通試験 [試験を実行]

2016.06.17

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

前回、Postmanの基本的な機能について紹介しました。今回は、実際にテストケースをどのように組み上げ、疎通確認を行ったかをご紹介します。

テストコレクションの作成

前回は、テスト1つの作り方を紹介しました。しかし、あるシナリオに沿った試験となると、ひとつAPIを叩くだけで「はいOK」となるようなケースはあまりありません。それぞれユーザーの新規登録から削除処理などを絡め、さらに途中に認証処理などが入る場合もあるでしょう。また更新されたデータを再度取得して比較し、正常に更新されていることを確認する、などと言った前の状態を維持しながら流れの中でAPIを実行していく必要があります。

example1

これを可能にするのがコレクションです。ただのテストケースの寄せ集めではなく、定義した順序どおりに実行することができます。

Postmanには2階層あります。FolderとCollectionです。

スクリーンショット 2016-06-15 15.15.01

この場合は ブログ用API がFolderにあたり、 API動作確認 がCollectionに相当します。それぞれのCollection内にはテストケースが複数定義されているのが確認できます。

Collection

複数のテストケースをまとめた1つのシナリオとなります。基本的にCollectionが1シナリオと考えて良いかと思います。今回の案件ではいくつかのシナリオに沿ってCollectionを作成しました。以下はその1例です。

  • 全API疎通確認: 会員登録から会員退会まで全てのAPIを一度ずつ実行する。会員登録したら登録した会員情報を更新して、さらにその会員情報を取得して・・・、最終的に会員情報削除まで。
  • 会員情報の更新処理(xxがfalseの場合): 今回の案件ではそこそこ複雑な値の検証処理(Validation)が実装されています。会員情報のある項目の状態によって、エラーになったり正常で通したり、結構シナリオが複雑に絡みます。そのため、前提をCollectionに記載し、前提条件となるようなデータをAPIを実行することで作成し、その後試験しています。エンドトゥエンドの試験であるため、DBの内容などを直接改変して前提条件を作るのではなく、あくまでAPIの実行の流れの中で、前提条件となるようなデータを作成します。

注意が必要なのは実はRunnerではCollection単位での実行ができません。Folderを起動し、その中で実行したいCollectionを選ぶことになります。

Folder

Collectionをまとめる最上位のカテゴリ。このカテゴリがRunnerで実行する対象になります。

前述した 会員情報の更新処理 は条件や前提によって様々なシナリオがあることが分かりました。Folderは複数のCollectionを束ねることができるので、 会員情報の更新処理 という名称でFolderを作成し、様々な条件のCollectionをまとめることができます。

テストを実行する

疎通確認のケースをRunnerで実行してみましょう。Runnerを立ち上げるためには、Folderのサブメニューを開きます。前述したようにFolderのみしかRunnerを指定できません。

このようにCollectionにはRunnerを起動するサブメニューは表示されません。

スクリーンショット 2016-06-15 15.15.20

Folderのサブメニューを表示すると、Run の表示があります。

スクリーンショット 2016-06-15 15.15.43

Folderのサブメニューから Run をクリックします。すると一覧のテストを流すためのRunnerが別アプリとして立ち上がります。

スクリーンショット_2016-06-13_17_20_35

1: History

左のペインはRunnerで実行したCollectionの履歴となります。こちらに実行したものの履歴がずらずらとリスト形式で並びます。

2: テストCollectionの選択画面

2 で示した箇所は、テストの実行対象を選択肢ます。Folderの指定やCollectionの指定が可能です。単一のテストケースを指定することはできません。最小粒度はCollectionレベルです。

ここで選択した Folder 及び Collection の中に定義してあるテストケースが続々と実行されていきます。

3: 変数セットやテスト回数の設定

  • Environment: テストに利用する変数セットを選択します。前回解説したようにステージング、プロダクション、ローカル環境などで使い分けることができます。
  • Iteration: テストの実行回数です。Iterationなのでその名の通り、何周回すかを設定します。
  • Delay: テスト実行時のDelay時間を指定します。基本的には即実行して良いと思うので必要ないかもしれません。
  • Data File: テストに使用するデータをCSVJSONのいずれかのフォーマットで記述されたファイルで指定することができます。2. Next, get your file of variables you want to run ready. This can be a CSV or JSON file.
  • Start Test: テストを実行します。

4: 実行結果

実施されたテストケースの実行結果が表示されます。Tests Scriptをクリアすれば緑色、Tests Scriptをクリアできなければ赤色で表示されます。

スクリーンショット_2016-06-15_16_01_47

CLIツールを利用する

PostmanにはGUIツールの他にCLIが用意されています。nodeベースで作られているのでnodeさえ入ってれば何でも動きます。(多分)

インストールしていきましょう。自分の現在の環境は以下の通り。

$ npm -version
3.9.3
$ node -v
v6.2.1

postmanlabs - newmanのREADMEを参考にインストールを実行していきます。

今回はglobalへのインストールで良いかと思います。

$ npm install -g newman

> newman@2.1.1 preinstall /usr/local/lib/node_modules/.staging/newman-5a7802c8
> node ./scripts/preinstall.js

******************************************************************
*                           Notice                               *
******************************************************************
*  If you are using Node v0.12 or v0.10, you should install      *
*  Newman v1.x:                                                  *
*                                                                *
*                   npm install newman@1                         *
*                                                                *
*  Deprecation: Newman v3 onwards will deprecate the use of DOM  *
*  related libraries, such as JQuery and Backbone. For details,  *
*  check https://www.getpostman.com/docs/sandbox                 *
******************************************************************
/usr/local/bin/newman -> /usr/local/lib/node_modules/newman/bin/newman
/usr/local/lib
└─┬ newman@2.1.1
  ├── atob@1.1.2
  ├─┬ aws4@1.3.1
  │ └─┬ lru-cache@4.0.1
  │   ├── pseudomap@1.0.2
  │   └── yallist@2.0.0
  ├── backbone@1.3.3
  ├── btoa@1.1.2
  ├─┬ cli-color@0.2.3
  │ ├── es5-ext@0.9.2
  │ └─┬ memoizee@0.2.6
  │   ├── event-emitter@0.2.2
  │   └── next-tick@0.1.0
  ├─┬ commander@2.9.0
  │ └── graceful-readlink@1.0.1
  ├── crypto-js@3.1.6
  ├── dot@1.0.3
  ├─┬ hawk@3.1.2
  │ ├── boom@2.10.1
  │ ├── cryptiles@2.0.5
  │ ├── hoek@2.16.3
  │ └── sntp@1.0.9
  ├── jquery@2.1.1
  ├─┬ jsdom@7.1.0
  │ ├── abab@1.0.3
  │ ├── acorn@2.7.0
  │ ├── acorn-globals@1.0.9
  │ ├── cssom@0.3.1
  │ ├── cssstyle@0.2.36
  │ ├─┬ escodegen@1.8.0
  │ │ ├── esprima@2.7.2
  │ │ ├── estraverse@1.9.3
  │ │ ├── esutils@2.0.2
  │ │ ├─┬ optionator@0.8.1
  │ │ │ ├── deep-is@0.1.3
  │ │ │ ├── fast-levenshtein@1.1.3
  │ │ │ ├── levn@0.3.0
  │ │ │ ├── prelude-ls@1.1.2
  │ │ │ ├── type-check@0.3.2
  │ │ │ └── wordwrap@1.0.0
  │ │ └─┬ source-map@0.2.0
  │ │   └── amdefine@1.0.0
  │ ├─┬ htmlparser2@3.9.1
  │ │ ├── domelementtype@1.3.0
  │ │ ├── domhandler@2.3.0
  │ │ ├─┬ domutils@1.5.1
  │ │ │ └─┬ dom-serializer@0.1.0
  │ │ │   └── domelementtype@1.1.3
  │ │ ├── entities@1.1.1
  │ │ ├── inherits@2.0.1
  │ │ └─┬ readable-stream@2.1.4
  │ │   ├── buffer-shims@1.0.0
  │ │   ├── core-util-is@1.0.2
  │ │   ├── isarray@1.0.0
  │ │   ├── process-nextick-args@1.0.7
  │ │   ├── string_decoder@0.10.31
  │ │   └── util-deprecate@1.0.2
  │ ├── nwmatcher@1.3.8
  │ ├── parse5@1.5.1
  │ ├── symbol-tree@3.1.4
  │ ├── tough-cookie@2.2.2
  │ ├── webidl-conversions@2.0.1
  │ ├─┬ whatwg-url-compat@0.6.5
  │ │ └── tr46@0.0.3
  │ └── xml-name-validator@2.0.1
  ├── jsface@2.2.0
  ├── json5@0.4.0
  ├── lodash@3.10.1
  ├─┬ mkdirp@0.5.1
  │ └── minimist@0.0.8
  ├── node-uuid@1.4.1
  ├─┬ postman-collection-transformer@1.6.3
  │ ├── commander@2.8.1
  │ ├─┬ intel@1.0.2
  │ │ ├─┬ chalk@1.1.3
  │ │ │ ├── ansi-styles@2.2.1
  │ │ │ ├── escape-string-regexp@1.0.5
  │ │ │ ├─┬ has-ansi@2.0.0
  │ │ │ │ └── ansi-regex@2.0.0
  │ │ │ ├── strip-ansi@3.0.1
  │ │ │ └── supports-color@2.0.0
  │ │ ├── dbug@0.4.2
  │ │ ├── stack-trace@0.0.9
  │ │ ├── strftime@0.9.2
  │ │ ├── symbol@0.2.3
  │ │ └── utcstring@0.1.0
  │ ├── lodash@3.10.0
  │ ├── semver@5.1.0
  │ └── strip-json-comments@1.0.2
  ├─┬ postman_validator@0.0.4
  │ └── JSV@4.0.2
  ├─┬ request@2.72.0
  │ ├── aws-sign2@0.6.0
  │ ├─┬ bl@1.1.2
  │ │ └── readable-stream@2.0.6
  │ ├── caseless@0.11.0
  │ ├─┬ combined-stream@1.0.5
  │ │ └── delayed-stream@1.0.0
  │ ├── extend@3.0.0
  │ ├── forever-agent@0.6.1
  │ ├─┬ form-data@1.0.0-rc4
  │ │ └── async@1.5.2
  │ ├─┬ har-validator@2.0.6
  │ │ ├─┬ is-my-json-valid@2.13.1
  │ │ │ ├── generate-function@2.0.0
  │ │ │ ├─┬ generate-object-property@1.2.0
  │ │ │ │ └── is-property@1.0.2
  │ │ │ ├── jsonpointer@2.0.0
  │ │ │ └── xtend@4.0.1
  │ │ └─┬ pinkie-promise@2.0.1
  │ │   └── pinkie@2.0.4
  │ ├── hawk@3.1.3
  │ ├─┬ http-signature@1.1.1
  │ │ ├── assert-plus@0.2.0
  │ │ ├─┬ jsprim@1.2.2
  │ │ │ ├── extsprintf@1.0.2
  │ │ │ ├── json-schema@0.2.2
  │ │ │ └── verror@1.3.6
  │ │ └─┬ sshpk@1.8.3
  │ │   ├── asn1@0.2.3
  │ │   ├── assert-plus@1.0.0
  │ │   ├─┬ dashdash@1.14.0
  │ │   │ └── assert-plus@1.0.0
  │ │   ├── ecc-jsbn@0.1.1
  │ │   ├─┬ getpass@0.1.6
  │ │   │ └── assert-plus@1.0.0
  │ │   ├── jodid25519@1.0.2
  │ │   ├── jsbn@0.1.0
  │ │   └── tweetnacl@0.13.3
  │ ├── is-typedarray@1.0.0
  │ ├── isstream@0.1.2
  │ ├── json-stringify-safe@5.0.1
  │ ├─┬ mime-types@2.1.11
  │ │ └── mime-db@1.23.0
  │ ├── node-uuid@1.4.7
  │ ├── oauth-sign@0.8.2
  │ ├── qs@6.1.0
  │ ├── stringstream@0.0.5
  │ └── tunnel-agent@0.4.3
  ├── sugar@1.3.9
  ├── tv4@1.2.7
  ├── underscore@1.8.3
  ├─┬ unirest@0.4.2
  │ ├─┬ form-data@0.2.0
  │ │ ├── async@0.9.2
  │ │ ├─┬ combined-stream@0.0.7
  │ │ │ └── delayed-stream@0.0.5
  │ │ └─┬ mime-types@2.0.14
  │ │   └── mime-db@1.12.0
  │ ├── mime@1.2.11
  │ └─┬ request@2.51.0
  │   ├── aws-sign2@0.5.0
  │   ├─┬ bl@0.9.5
  │   │ └─┬ readable-stream@1.0.34
  │   │   └── isarray@0.0.1
  │   ├── caseless@0.8.0
  │   ├── forever-agent@0.5.2
  │   ├─┬ hawk@1.1.1
  │   │ ├── boom@0.4.2
  │   │ ├── cryptiles@0.2.2
  │   │ ├── hoek@0.9.1
  │   │ └── sntp@0.2.4
  │   ├─┬ http-signature@0.10.1
  │   │ ├── asn1@0.1.11
  │   │ ├── assert-plus@0.1.5
  │   │ └── ctype@0.5.3
  │   ├── mime-types@1.0.2
  │   ├── oauth-sign@0.5.0
  │   └── qs@2.3.3
  └─┬ xml2js@0.4.16
    ├── sax@1.2.1
    └─┬ xmlbuilder@4.2.1
      └── lodash@4.13.1

すごい量のDependenciesがインストールされました。

テストに必要なこと

テストの実行には2つのパラメータが必要です。

  • 実行するテストシナリオ(Collection)
  • テストシナリオで利用する環境変数(Environment)

Environmentファイルを取得する

EnvironmentはCredentials情報などを扱ってるためか、URLでのリンクなどは許されてない模様です。そのため、Json形式でダウンロードしてテストを実行する環境へ配置しておく必要があります。

Postmanアプリから Manage Environment を開きます。

テストに利用するEnvironmentの ダウンロード ボタンをクリックします。適当なところに保存します。できればテストを実行するディレクトリがあるならば、そちらのほうが良いでしょう。

スクリーンショット_2016-06-15_17_00_07

日本語名や記号が入ったEnvironment名をつけてるとエスケープされることがあるので、概ね英語でつけておいたほうが無難です。

実行したいテストのURLを取得する

実行したいテストのURLを取得します。先ほど Run をクリックしRunnerを立ち上げた画面を再度開きます。

スクリーンショット 2016-06-15 15.15.43

Run の隣に Share があるのでこちらをクリックします。

スクリーンショット 2016-06-15 17.24.16

SHARE COLLECTION が開きます。一番上部の Get Link をクリックします。

スクリーンショット_2016-06-15_17_25_29

リンクが生成されるので、こちらをコピーしておきましょう。こちらのURLは不変です。Update Link を実行しても特にURLに変更はありません。

これでCLIでテストを実行することができます。

テストを実行する

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

newman -u POSTMAN_COLLECTION -e POSTMAN_ENVIRONMENT
  • POSTMAN_COLLECTION: 取得した実行するコレクションのURLを入力します。
  • POSTMAN_ENVIRONMENT: 取得したEnvironmentファイルのパスを入力します。

入力すると以下の様なコマンドになるかと思います。

$ newman -u https://www.getpostman.com/collections/xxxxxxxxxxxxxxxxx -e LocalEnvironment.postman_environment.json

こちらを実行してみましょう。

Missing request: c5a65cdd-3f4c-52f2-ca40-7dfd1d7ce762

Iteration 1 of 1
200 574ms 認証 [POST] https://hogehoge.com/oauth/token?type=client
    ✔ Status code is 200
200 481ms ユーザ情報取得 [GET] https://hogehoge.com/api/userinfo/gN0gersd_mPmie-wBIRtskw==
    ✔ Status code is 200
200 589ms ユーザ情報更新 [PATCH] https://hogehoge.com/api/userinfo/gN0gersd_mPmie-wBIRtskw==
    ✔ Status code is 200
200 486ms ユーザ情報取得(変更後) [GET] https://hogehoge.com/api/userinfo/gN0gersd_mPmie-wBIRtskw==
    ✔ Status code is 200
200 993ms ユーザ退会 [DELETE] https://hogehoge.com/api/userinfo/gN0gersd_mPmie-wBIRtskw==
    ✔ Status code is 200

Summary:

Parent                      Pass Count   FailCount
-------------------------------------------------------------
Folder API動作確認                      5           0

Total                               5           0

このようにCLI上から同じテストケースを実行することができます。

結果を出力させる(JSON)

先ほどのコマンドは標準出力のみなので、パイプするなりでファイルに吐き出してやらないと結果が取得できません。そのため、 -o オプションをつけることでJSON形式でテスト結果を出力することができます。

$ newman -u https://www.getpostman.com/collections/xxxxxxxxxxxxxxxxx -e LocalEnvironment.postman_environment.json -o result.json

こちらを実行すると以下の出力が追加されます

Output Log: /path/to/result.json

ログファイルのJSONが作成され、フルパスが出力されます。ちなみにこのテスト結果のJSONはえらく複雑になっています。Postmanアプリでインポートできるようになってるようです。

テストを実行するための Runnerから Import Test Run をクリックします。

スクリーンショット 2016-06-15 19.03.42

ファイルを選択します。

スクリーンショット 2016-06-15 19.05.04

正常に読み込めると以下のようにアプリで実行結果を確認することができます。

スクリーンショット_2016-06-15_19_05_29

他にもHTMLへのExportもあったのですが日本語が全て文字化けてしまって全く読めなくなってしまったので、今のところはあまり使えないかもしれません。

まとめ

今回はテストを実行する手順をまとめました。CLIを利用することでDeploy後の疎通確認のテストの自動化なども可能になりそうです。自動化まではしていませんが、新しいバージョンにDeployした時には必ずCLIでこのテストケースを実行し、全てステータスコード200でパスすることを確認するようにしています。

ここで何らかのエラーが起きた場合には、速やかに前のバージョンへ切り戻し、再度疎通確認を行い原因の解決を行うようにしたところ、APIに接続できないといった報告はほぼなくなりました。Deployした後の確認としてこういったテストは誰でも確認できるようにしておきたいところです。

参照