Web APIテスト用ローカル環境の構築


下記の記事で書いたテスト環境の構築をします。モチベーションや前提といった情報は下記の記事を参照してください。また、実験的に取り組んでいるため、この記事の内容は汎用性が低い可能性が高いです。

Web API を簡易に e2e テストしたい:技術選び編

前置き

次の環境が利用できる状態とします。この記事は Intel Mac の Docker Desktop を利用し動作確認をしています。M1 Mac など他 OS では再現できない可能性があるためご注意ください。

  • Docker (Docker Desktop)
  • Kubernetes (Docker Desktop)
  • Skaffold

kubernetes 環境にしているのは、最近勉強していてお気に入りだからです。書かないと思いますが同じようなことを docker-compose でも良いと思います。helm を利用していないのは、現状デプロイ先が k8s 環境を想定していないので、複数環境の deployment.yaml などを作る想定がないからです。

ゴール

skaffold で ローカルの kubernetes(以下 k8s)上に 認証用の WireMock1 つと DB が立ち上がること。

"ゴール"

DB

今回は Postgres を使用します。k8s 上に作成するため、deployment.yaml と service.yaml を作成します。コンテナ名は mypage-db、db 名は mypage、port は 5432 です。これらはテストするアプリケーション設定に合わせて変更します。

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mypage-db
spec:
  selector:
    matchLabels:
      app: mypage-db
  template:
    metadata:
      labels:
        app: mypage-db
    spec:
      containers:
        - name: mypage-db
          image: postgres:13
          resources:
            limits:
              memory: "128Mi"
              cpu: "500m"
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_PASSWORD
              value: password
            - name: POSTGRES_DB
              value: mypage

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: mypage-db
spec:
  selector:
    app: mypage-db
  ports:
    - port: 5432
      targetPort: 5432

skaffold.yaml

deployment と service を起動する skaffold を作成します。skaffold は使わなくても良いですが、使うと環境を立ち上げ直したりするのに便利です。deployment.yaml と service.yaml と同じ階層に作成します。

apiVersion: skaffold/v2beta28
kind: Config
deploy:
  kubectl:
    manifests:
      - ./deployment.yaml
      - ./service.yaml
portForward:
  - resourceType: service
    resourceName: mypage-db
    port: 5432
    localPort: 5432

ファイル構成

.
└── db
    ├── deployment.yaml
    ├── service.yaml
    └── skaffold.yaml

起動

適当に k8s 上に namespace を作成して起動します。db にアクセスできるよう、port-forward を同時に行います。5432 port は postgres でよく使われているので、他の port が良ければ skaffold ファイルで 別ポートを指定するなどします。

kubectl create namespace api-e2e
skaffold dev -n api-e2e --port-forward

pod の確認

kubectl -n api-e2e get po

"bash"

Running できていればデータベースに接続可能になっています。psql コマンドや DB クライアントで接続可能かを確認します。接続に失敗する場合、port-forward に失敗しているか service の作成に問題があるかもしれません。

接続確認

 psql -h localhost -U postgres -p 5432

WireMock の作成

WireMock は Mock API を簡易に構築できる便利なツールです。Docker で利用できます。e2e テスト時は Auth0 をモックにしたいため、WireMock に Auth0 から返ってくるだろうレスポンスを登録しておき、テスト中の Mock として利用する想定で立てます。DB と同様に deployment.yaml、service.yaml、skaffold.yaml を作成します。auth0 の Mock を想定しているのでそういう名前にしています。

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: auth0-mock
spec:
  selector:
    matchLabels:
      app: auth0-mock
  template:
    metadata:
      labels:
        app: auth0-mock
    spec:
      containers:
        - name: auth0-mock
          image: wiremock/wiremock:2.33.2
          resources:
            limits:
              memory: "128Mi"
              cpu: "500m"
          ports:
            - containerPort: 8080

service.yaml

port は適当に 2400 としました。

apiVersion: v1
kind: Service
metadata:
  name: auth0-mock
spec:
  selector:
    app: auth0-mock
  type: NodePort
  ports:
    - port: 2400
      targetPort: 8080

skaffold.yaml

apiVersion: skaffold/v2beta28
kind: Config
deploy:
  kubectl:
    manifests:
      - ./deployment.yaml
      - ./service.yaml

フォルダ構成

.
├── auth0
│   ├── deployment.yaml
│   ├── service.yaml
│   └── skaffold.yaml
└── db
    ├── deployment.yaml
    ├── service.yaml
    └── skaffold.yaml

起動確認

wiremock の skaffold ファイルがある階層で実行します。あるいは、-f コマンドでファイル指定します。

cd auth0
skaffold dev -n api-e2e --port-forward

# or
skaffold dev -n api-e2e -f path/to/skaffold.yaml --port-forward

kubectl -n api-e2e get po

"wiremock"

Pod が問題なく立ち上がっていたら、ブラウザから WireMock にアクセスします。今回は 2400 の port に立てているので http://localhost:2400 でアクセス可能です。WireMock の mapping を確認できる URL にアクセスします。

http://localhost:2400/__admin/mappings

下記のような画面が表示されたら成功です。2400 にそもそも繋げない場合は、port-forward などを見直してください。

{
  "mappings": [],
  "meta": {
    "total": 0
  }
}

テスト環境起動用の skaffold

DB、WireMock 共に単体の起動に問題がなければ、両方を 1 つの skaffold ファイルから起動できるようにします。1 コマンドで必要な環境が立ち上がると単純に便利だからです。DB と WireMock をそれぞれの skaffold に分けたのは、必要な時に依存関係から外しやすく、他の構成で使いたくなったときに追加しやすいからです。

.
└── k8s
    ├── auth0
    │   ├── deployment.yaml
    │   ├── service.yaml
    │   └── skaffold.yaml
    ├── db
    │   ├── deployment.yaml
    │   ├── service.yaml
    │   └── skaffold.yaml
    └── skaffold.yaml

skaffold.yaml はたくさん増えてくるので別の名前の方がわかりやすい時もあります。skaffold.yaml という名前にすると、skaffold コマンド時に-f を省略できるメリットはありますが、わかりやすい名前をつけておいた方がどの skaffold を使えば良いかが後でわかりやすくなります。といつつ、今回は全部 skaffold.yaml という名前で作るんですが。

skaffold.yaml

apiVersion: skaffold/v2beta28
kind: Config
requires:
  - path: "./auth0/skaffold.yaml"
  - path: "./db/skaffold.yaml"

起動確認

先ほど作成した skaffold.yaml がある階層で実行します。

skaffold dev -n api-e2e --port-forward

"skaffold"

想定通りの環境ができました。最初の記事で書いた通り、メールサーバーが必要なら新しく skaffold で作り、依存関係が多くてもっと WireMock が必要ならその skaffold を作り、という感じで足していきます。

依存関係を追加したり外したりがやりやすく、終了時は環境を綺麗にしてくれたりと使っていて楽しいので k8s と skaffold で作るローカル開発環境はお気に入りです。

必要な環境は作成できたので、次は E2E テストを作成して動かします。