9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

シーエー・アドバンスAdvent Calendar 2024

Day 3

docker composeでe2eテストの立ち上がりと終了を管理

Last updated at Posted at 2024-12-02

この記事は何か

e2eでよくある、代表的な「待つ」のうち

  1. サービスが実行できるのを「待つ」
  2. サイトのテスト部分が現れるのを「待つ」

1番目の、サービスが実行できるのを「待つ」をdocker-compose.ymlを使って管理する方法について書いていきます。

対象

  • e2eテスト前に、何かしらサービスが実行できるまで「wait-on」などで、「待つ」処理を挟んでいる人

やること

  • docker-composeでe2eテストを実行
  • docker-compose.ymlの「depends_on」で立ち上がる順番を管理
  • テスト実行するコンテナは別で立ち上げる
  • テスト実行するコンテナが終わり次第、すべてのコンテナを終了させる(--abort-on-container-exit

取り扱わない事

  • e2eテストフレームワークの詳細や実行内容

メリット

  • wait-onや自作shellで、dockerのサービスが「port開く待ち」の記述しなくてOK
  • 今あるdocker-compose.ymlを大きく変えなくてOK
  • テスト終わったら、テスト実行が終わったことを判定したり、テスト後の「終了」を記述するのも書かなくてOK

サンプル docker-compose.yml

よくある、dbとwebの構成です。

今回、webnext.jsで、テストフレームワークはplaywright使っています

docker-compose.yml
services:
  db:
    image: postgres:17
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydatabase
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d mydatabase"]
      interval: 2s
      timeout: 3s
      retries: 5
    networks:
      - mynetwork

  web:
    build:
      context: .
      target: deps
    ports:
      - "3000:3000"
    volumes:
      - .:/usr/src/app
    depends_on:
      db:
        condition: service_healthy
    command: npx next dev
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"]
      interval: 2s
      timeout: 3s
      retries: 10
    networks:
      - mynetwork

volumes:
  pgdata:

サービス実行コマンド

docker-compose up

を実行すると、dbがヘルスチェック通り次第、webが立ち上がります。

healthチェックをserviceごとに書いておくと、順番が守られて立ち上がるようになります。

参考:https://docs.docker.com/compose/how-tos/startup-order/

テスト実行コンテナを用意

docker-compose.yml
services:
  db:
    image: postgres:17
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydatabase
    ports:
      - '5432:5432'
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U user']
      interval: 2s
      timeout: 3s
      retries: 5
    networks:
      - mynetwork

  web:
    build:
      context: .
      target: deps
    ports:
      - '3000:3000'
    volumes:
      - .:/usr/src/app
    depends_on:
      db:
        condition: service_healthy
    command: npm run dev
    healthcheck:
      test: ['CMD-SHELL', 'curl -f http://localhost:3000 || exit 1']
      interval: 2s
      timeout: 3s
      retries: 5
    networks:
      - mynetwork

+  e2e:
+    profiles:
+      - e2e-group
+    build:
+      context: .
+      target: test
+    volumes:
+      - .:/usr/src/app
+    depends_on:
+      web:
+        condition: service_healthy
+    environment:
+      - CI=true
+    command: npm run e2e
+    networks:
+      - mynetwork

volumes:
  pgdata:

networks:
  mynetwork:

dockerfile
FROM node:22 AS deps

# Set the working directory
WORKDIR /usr/src/app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install dependencies
RUN npm install

# HEALTHCHECK --start-period=5s CMD curl -fs localhost:3000/health || exit 1


+ FROM node:22 AS test

# Set the working directory
+ WORKDIR /usr/src/app

# Copy the node_modules from the deps stage
+ RUN npx playwright install --with-deps

# Copy the rest of the application code
+ COPY --from=deps /usr/src/app/node_modules ./node_modules

# Copy the rest of the application code
+ COPY . .

ポイント

  • docker-compose.ymlでbuildのターゲット追加のほうが、既存のイメージなどに影響を与えず追加するだけでよくなるのでおすすめです
  • docker-compose.ymlprofilesを追加することで、既存のコマンドを変えなくて済みます

テスト実行コマンド

docker-compose.ymlにprofilesを追加したので、e2eをテストで実行するとき、下記コマンドになります。

docker compose --profile test-group up --abort-on-container-exit --exit-code-from e2e

--exit-code-from servicee2eに指定することで、そのサービスの終了コード(exit code)をメインプロセスの終了コードとして反映させるために使用されます。
このオプションを使用すると、テストの成功・失敗結果や、コンテナ内で実行した処理の終了コードを取得できます。

profilesの指定がないservice + profilesで指定したグループが立ち上がるようになりました。

動作の流れ

docker compose --profile test-group up --abort-on-container-exit --exit-code-from e2e

db → web → e2e の順番で立ち上がる

e2eコンテナのテストが終わり次第、e2e、web、dbのコンテナが終了

Github Actions

終了時のシグナルも流れてくるので(成功 → 0、異常 → 1)、Github Actionsでも条件わけして通知もできます

.github/workflows/test.yml

name: Test

on:
  push:
  workflow_dispatch:

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Test
        run: docker compose --profile test-group up --abort-on-container-exit --exit-code-from e2e

      - name: Notify Slack
        if: always() # ステータスに関わらず送信
        # if: success() # 成功したとき送信
        # if: failure() # 失敗したとき送信
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          fields: message,eventName,ref,workflow,job,took
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

参考

9
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?