Techtouch Developers Blog

テックタッチ株式会社の開発チームによるテックブログです

Postman をチームで運用していくためにフォーク機能を使ってみた

adventCalendar-day1

バックエンドエンジニアの misu です。TENET や羅小国戦記などわりと映画を見て最近は楽しんでいます。この記事を完成させたらクイーンズ・ギャンビットを見たいところ。。!

この記事について

前回、Postman を使って E2E テストを行う記事を書いたのですが、チームで運用してくとなると少し工夫が必要になったのでその辺の Tips を書いて行きます。

具体的には Postman のコレクションを git のようにフォークして、各開発者が開発ブランチごとに E2E テストを回せるようにしました。

内容

背景

下記図のように複数の開発者が1つのコレクションに対して、API を登録すると E2E のときに A は users API がないため CI が落ちてしまいます。B もまた然り。

f:id:techtouch:20201129195444p:plain

本当に E2E 含め開発完了しているかは、落ちた E2E の結果を見て、開発スコープ以外のものだったらよしとしてました。上記でいえば、A は users API が落ちてる分にはしょうがないと判断できます。しかし、テストが落ちているのは気持ちが悪いし、落ちている中に見過ごせないエラーがあるかもしれません。そのため、Postman のフォークの機能を使って git のように運用できるようにしました。

対策

フォークの機能を使うとこのように Postman コレクションを運用できるようになります。

f:id:techtouch:20201129202937p:plain

A はもとのコレクションを feature/articles としてフォーク。 B はもとのコレクションを feature/users としてフォーク、両者はそれぞれのコレクションを編集します。

Postman の アプリケーション上ではこのような操作になります。

f:id:techtouch:20201129203612p:plain

f:id:techtouch:20201129203718p:plain

fork すると、その名前のコレクションが作られます。

f:id:techtouch:20201129203647p:plain

そして、E2E が通ったらコレクションから PR をもとのコレクションに対して投げます。

f:id:techtouch:20201129203919p:plain

PR は Postman の Web GUI で確認ができます。

CI との連携

次にフォークしたコレクションをどうやって CI と連携しているかを説明します。今回は CircleCI を使っています。 CI は対象のブランチに対して実行されるので、ブランチに対応したコレクションを作ると CI 側から E2E テストのときに紐付けやすいです。

Postman の GUI から先程の手順のようにコレクションをフォークしてもいいのですが、ブランチ名の入力を間違えると変にハマったりするので開発時にブランチ切った後にコマンド入力でフォークできるようにしています。 Makefile の例です。

$ make fork-collection

で現在のブランチ名と同じ名前のコレクションが作られます。

BRANCH=$(shell git symbolic-ref --short HEAD)
DEVELOP_COLLECTION_ID=<fork対象にするPostman コレクション>
WORKSPACE_ID=<コレクションを登録している場所のid>

fork-collection:
    sh .env
    curl --location --request POST 'https://api.getpostman.com/collections/fork/${DEVELOP_COLLECTION_ID}?workspace=${WORKSPACE_ID}' \
        --header 'X-Api-Key:${MY_POSTMAN_KEY}' \
        --header 'Content-Type: application/json' \
        --data-raw '{"name": "${BRANCH}","label": "${BRANCH}"}'

.env ファイル

export MY_POSTMAN_KEY=test

MY_POSTMAN_KEY を各人で設定できるようにしているのは、フォークした後のコレクションを自分で編集できるようにするためです。 以前は自分の Key を Makefile に貼り付けていましたが、他の人がフォークした後にそのコレクションが権限上編集できないということで各人が Key を発行してそれを使うようにしています。

DEVELOP_COLLECTION_ID のとり方

$ curl 'https://api.getpostman.com/collections' --header 'X-Api-Key:${POSTMAN_KEY}'

WORKSPACE_ID のとり方

$ curl 'https://api.getpostman.com/workspaces' --header 'X-Api-Key:${POSTMAN_KEY}'

この辺の API は Postman API を見ました。

Circle CI 上で走る Newman (Postman のコレクションに沿ってリクエストを流すタスクランナー) がフォークしたコレクションを参照するためには、ブランチ名と一致したコレクションの id を知る必要があります。 また、デフォルトではフォーク元のコレクション id を参照できるようにもしたいです。(マージした後にも該当のブランチで E2E テストを行いたいので)

対象コレクションの id を知るためには先程の DEVELOP_COLLECTION_ID を知るために使ったAPI を使います。レスポンスは下記のように返ってきます。

{
    "collections": [
        {
            "id": "aaaa",
            "name": "XXXXX",
            "owner": "b",
            "uid": "b-aaaa",
            "fork": {
                "label": "feature/articles",
                "createdAt": "2019-08-09T03:11:01.000Z",
                "from": "cccc"
            }
        },
        {
            "id": "cccc",
            "name": "XXXXX",
            "owner": "d",
            "uid": "d-eeee"
        },
        .
        .
        .
    ]
}

そのため、push されたブランチと同じ名前の label がマッチしたらその id を collection 取得の際に使うようにします。 Makefile ではこのように書きました。一応、フォークしたコレクションがマッチしたかどうか標準出力にはいてわかるようにしています。

run-e2e:
# fork しているcollectionがない場合、origin のものを使う
    $(eval FOUND_COLLECTION_ID=$(shell curl -s 'https://api.getpostman.com/collections' --header 'X-Api-Key:${POSTMAN_KEY}' | \
        jq -r '.collections[] | select(.fork.label // "" | test("${BRANCH}")) | .id'))
    $(eval COLLECTION_ID=$(or ${FOUND_COLLECTION_ID}, ${ORIGIN_COLLECTION_ID}))
    $(if ${FOUND_COLLECTION_ID}, $(info *** use fork collection ***), $(info *** use origin collection ***))
    curl -H 'X-Api-Key:${POSTMAN_KEY}' https://api.getpostman.com/collections/${COLLECTION_ID} > e2e/origin.json
    docker  run newman newman run e2e/origin.json

これで、CI 上の E2E で開発ブランチに応じた Postman コレクションを参照することができるようになりました。

その他解決したい課題

現状 API の命名規則がバラバラなのでルールを決めて、それに沿ってない場合は CI で落とすようにしたい。 環境変数を整理したいが、エディタが激重でいじる気が起きないので簡易な CLI 作って CRUD 操作したい。

明日は、Typescript 4系の記事が投下されるみたいです。僕は全然追えてないのでどんなに言語的にリッチになっているか楽しみです!