docker-compose + GitHub ActionsでE2Eテストを自動化する
docker-composeとGitHub Actionsを組み合わせて、E2Eテストを自動実行するCI/CD環境を構築します。TypeORMのsynchronize機能を活用したテスト環境構築の実例も紹介します。
#docker #githubactions #cicd #e2e #typeorm
はじめに
前回の記事で作成したE2Eテストを、docker-composeで実行できるようにし、GitHub Actionsで自動化します。
Dockerfileの作成
E2Eテスト実行用Dockerfile
# Dockerfile.test
FROM node:14.16.1-alpine as build-stage
WORKDIR /work
COPY . /work/
RUN npm install
CMD ["npm","run","test:e2e"]
マイグレーション実行用Dockerfile
# Dockerfile.migrate
FROM node:14.16.1-alpine
WORKDIR /work
COPY ./src/databases /work/src/databases
COPY ./package.json ./package-lock.json ./ormconfig.ts ./tsconfig.json /work/
RUN npm install
CMD ["npm", "run", "typeorm", "migration:run"]
docker-compose設定
E2Eテスト用のdocker-compose設定ファイルを作成します。
# unit-test.yml
version: '3'
services:
app:
build:
context: "."
dockerfile: "Dockerfile.test"
image: app-test
container_name: app-test
ports:
- '3000:3000'
environment:
PORT: 3000
TZ: 'Asia/Tokyo'
DB_HOST: 'db'
DB_PORT: '3306'
DB_USERNAME: 'test_user'
DB_PASSWORD: 'test_password'
DB_NAME: 'test_db'
REDIS_HOST: 'redis'
REDIS_PORT: '6379'
depends_on:
- db
- redis
redis:
image: redis:5.0
container_name: redis_container-test
ports:
- "6379:6379"
db:
image: mysql:8.0
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
container_name: db_container_test
ports:
- 3306:3306
environment:
TZ: 'Asia/Tokyo'
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: test_db
MYSQL_USER: test_user
MYSQL_PASSWORD: test_password
TypeORM設定
⚠️ 警告:以下の設定を本番環境で使用するとデータが失われる可能性があります。必ずテスト専用の設定ファイルとして分離してください。
// ormconfig.test.ts
module.exports = {
type: 'mysql',
host: process.env.DB_HOST || 'localhost',
port: process.env.DB_PORT || '3306',
username: process.env.DB_USERNAME || 'test_user',
password: process.env.DB_PASSWORD || 'test_password',
database: process.env.DB_NAME || 'test_db',
// テスト環境のみ有効化:アプリケーション起動時にスキーマを自動同期
synchronize: true,
// 実行SQLをログ出力
logging: true,
entities: ['src/domain/entities/*.ts'],
migrations: ['src/databases/migrations/*.ts'],
seeds: ['src/test/databases/seeders/*.seed.{js,ts}'],
subscribers: ['src/subscribers/**/*.ts'],
cli: {
migrationsDir: 'src/databases/migrations',
entitiesDir: 'src/domain/entities',
seedersDir: 'src/databases/seeders',
subscribersDir: 'src/subscribers',
},
}
TypeORMのsynchronize: trueは、Entity定義からテーブルを自動生成する便利な機能ですが、本番環境では絶対に使用しないでください。既存のテーブル構造が上書きされ、データ損失のリスクがあります。
テスト実行
ローカルでの実行
# コンテナをビルド
docker-compose -f unit-test.yml build
# テストを実行(テスト終了後、コンテナを自動停止)
docker-compose -f unit-test.yml up --abort-on-container-exit
実行結果例
Recreating redis_container ... done
Recreating db_container ... done
Recreating app-test ... done
Attaching to redis_container-test, db_container_test, app-test
app-test |
app-test | > sample@0.0.1 test:e2e /work
app-test | > jest --config ./src/test/e2e/jest-e2e.json
app-test |
app-test | PASS src/test/e2e/contractor-reps.e2e-spec.ts (92.288 s)
app-test 契約担当者(E2E)
app-test ログインしていない場合は401が返ります
app-test ✓ OK /contractor-reps (GET) (1471 ms)
...
app-test Test Suites: 1 passed, 1 total
app-test Tests: 38 passed, 38 total
app-test Time: 92.428 s
app-test exited with code 0
GitHub Actions設定
プルリクエストのたびに自動でテストを実行するワークフローを設定します。
# .github/workflows/test.yml
name: E2E Tests
on:
pull_request:
types: [opened, synchronize]
jobs:
run-test:
name: Run E2E Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Run tests with docker-compose
run: |
docker-compose -f ./unit-test.yml build
docker-compose -f ./unit-test.yml up --abort-on-container-exit
working-directory: ./
まとめ
docker-composeとGitHub Actionsを組み合わせることで、以下のメリットが得られます:
- 環境の一貫性:本番環境に近い構成でテストを実行
- 自動化:プルリクエストごとに自動テスト実行
- 早期発見:統合不具合を早期に検出
--abort-on-container-exitフラグを使用することで、テスト完了後にコンテナが自動停止し、CI/CDパイプラインが効率的に終了します。