Newman (Command line Postman) をGitHub Actionsで動かしてAPI結合テストを自動化した

# はじめに

[Postman](https://www.getpostman.com/)を使ってRESTful API開発の動作検証を毎回ローカルで手動実行していましたがまあ面倒でした。
調べたら[Newman](https://learning.getpostman.com/docs/postman/collection-runs/command-line-integration-with-newman/)というPostmanのランナースクリプトをCLIで実施できるツールが公式から提供されていると知ったので[GitHub Actions](https://github.co.jp/features/actions)に組み込んで楽になりました。

GitHub Actionsで動かすまでがちょっと時間がかかったので知見をシェアする記事になります。

# 前提

* PostmanとNewmanに関して
[PostmanとNewmanを組み合わせて、CI/CDに組み込むREST APIの自動テストを作ろう！](https://qiita.com/developer-kikikaikai/items/74cedc67643ca93d2e0b)
の記事などで概要を予習済みであること。
* Docker-composeでAPIサーバなコンテナ+MySQLなどのミドルウェアなコンテナでローカル開発環境をセットしている。
* GitHubホストランナーの`Ubuntu 18.04 LTS`を利用(プライベートランナーではない)

# Main content

GitHub ActionsのWorkflow上でNewmanを実行させテストが通った設定を記載します。

## 構成

```
├── Dockerfile
├── docker-compose.yml
├── docker-compose.ci.yml
├── .github/workflows/
│   ├── test.yml
```

## Docker Compose files

```docker-compose.yml
version: '3'
services:
  api:
    container_name: api-server
    build: .
    ports:
      - "5000:5000"
      - "8081:8081"
    environment:
      - DB_USER=root
      - DB_PASS=mysql
      - DB_PORT=3306
      - DB_HOST=db
      - DB_DATABASE=great_db
    depends_on:
      - db

  db:
    image: mysql:5.7.22
    container_name: mysql
    command: mysqld --character-set-server=utf8mb4
    volumes:
      - ./db/init:/docker-entrypoint-initdb.d
      - ./db/mysql/conf.d:/etc/mysql/conf.d
    restart: always
    hostname: db
    environment:
      - MYSQL_ROOT_PASSWORD=mysql
      - MYSQL_DATABASE=mixlunch
```

```docker-compose.ci.yml
version: '3'
services:
  db:
    ports:
      - "13306:3306" # ポイント①
```

## GitHub Actions Workflows Yaml file

```.github/workflows/test.yml
name: Test
on: push
jobs:

  integration:
    name: Integration test
    runs-on: ubuntu-latest
    steps:

    - name: Setup for integration test
      run: sudo npm install -g newman # ポイント②

    - name: Checkout code
      uses: actions/checkout@v2

    - name: Build the docker-compose stack # Docker Composeを実行
      run: docker-compose -f docker-compose.yml -f docker-compose.ci.yml up -d

    - name: Sleep to wait for preparing of containers
      run: sleep 15 # ポイント③

    - name: Run test suite #Newmanコマンドを実行しテスト実施
      run: newman run -e Local.postman_environment.json postman_collection.json
```

# ポイント

## ポイント① Ubuntu GitHubホストランナーにはMySQL, npm, Docker Composeなどがプリインストールされている。

[Software installed on GitHub-hosted runners](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/software-installed-on-github-hosted-runners#ubuntu-1804-lts)のページで確認することができますが、GitHub ActionsのランナーのUbuntuにはメジャーなミドルウェアやツール、プログラミング言語のランタイムがインストール済みです。

なので今回MySQLコンテナのポートを3306で外開けすると既にGitHubランナーがMySQLを持っていてポートを確保しているのでWorkflow上でNGが出ました。そのためCI用に差別化ファイルを作る意味でも`13306`ポートで上書いています。

## ポイント② Ubuntu GitHubホストランナーはWorkflow上でsudoし放題

Newmanはデフォルトでインストールされていないのでインストールされているnpmを使って`npm install -g newman`でコマンドをインストールしようとしましたが権限エラーが出ました。

調べると、GitHub ActionsのWorkflow上では公式ドキュメントの[こちら](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/virtual-environments-for-github-hosted-runners#administrative-privileges-of-github-hosted-runners)にあるように

> The Linux and macOS virtual machines both run using passwordless sudo. When you need to execute commands or install tools that require more privileges than the current user, you can use sudo without needing to provide a password.

とパスワードとか無しで`sudo`を使えるとのことでそうしたら確かにNewmanがインストールできました。

## ポイント③ Dockerコンテナの準備が整うまでNewman実行を待つ

`docker-compose up -d`のコマンドとしての終了直後にNewmanを実行してもMySQLコンテナの準備が完了しておらずでテストがNGになってしまったので力技で`sleep`コマンドを使うことで今回は15秒待たせました。
15秒はローカルで試したちょっと余裕あるなとわかった数字なだけで根拠無しです。
イケてないのでうまいやり方が見つかればアップデートします。

# おわりに

Newmanで利用するPostmanのテストスクリプトをきちんとすればアプリケーション内のテストで、MySQLを立ち上げ→テーブル作成→Fixture挿入→Truncate処理という開発コストのかかる操作をせずともCIで結合レベルの自動テストができることがわかりました。

Postman、Newmanというツール依存になるので汎用性とのバランスになりますがPostmanでのGUI上の操作管理のしやすさを考慮するとスピード感で出て非常に良いソリューションだと感じます。

# 参考

* https://github.community/t5/GitHub-Actions/How-to-use-docker-compose-with-GitHub-Actions/td-p/37824
* https://qiita.com/developer-kikikaikai/items/74cedc67643ca93d2e0b