🌿

Github Actions × Docker で Spring Boot のマッパーのテストを自動化する

2023/01/09に公開

🌱 作成するもの

コード品質の最低限の項目として「テストが通ること」は保たれていてほしい。
テストの自動化を行い、GitHub 上でどのコミットがテストが通っているか確認できると便利。

今回は GitHub Actions 上でマッパーのテストを行う。
DB のモック化するのではなく、DB に接続して実行できるようにするため Docker を使用する。

👇 実行の流れ

  1. リポジトリのチェックアウト
  2. DB (MySQL) の Docker コンテナの起動
  3. JDK, Gradle のセットアップ
  4. DB のマイグレート実行
  5. テスト用の DB 作成
  6. テスト実行

🌱 実装

👇 環境

  • JDK: 17
  • Kotlin: 1.7.22
  • MySQL: 8.0.1
  • Spring: 3.0.1

👇 DB のマイグレーション設定

Test タスク実行前に DB のマイグレーションを必ず行うようにする。
今回 DB のマイグレーションには gradle プラグインの flyway を使用する。

下記は flyway 導入に必要な設定のみ抜粋。

build.gradle.kts
plugins {
    id("org.flywaydb.flyway") version "[version]"
}

dependencies {
    runtimeOnly("mysql:mysql-connector-java:[version]")
}

buildscript {
    dependencies {
        classpath("org.flywaydb:flyway-mysql:[version]")
    }
}

// flyway の設定は別ファイルに書き出して config で一括指定することも可能
flyway {
    // 今回はローカル環境を想定しているので SSL 接続は無効化
    url = "jdbc:mysql://[db host]:[db port]/[database]?useSSL=false"
    schemas = arrayOf("[schema]")
    user = "[username]"
    password = "[password]"
    locations = arrayOf("filesystem:[sql directory]")
    baselineVersion = "0.0.0"
    baselineOnMigrate = true
}

👇 テスト設定

テストには Kotest を使用。
テスト実行前に DB のマイグレーションを必ず行うようにする。

build.gradle.kts
tasks.withType<Test> {
    useJUnitPlatform()
    dependsOn(tasks.flywayMigrate)
}

環境を汚さないためにテスト用の DB を作成するようにする。
LIKE 句を使用して、プロダクト用の DB と同じ定義のテーブルを作成する。

TestDatabaseSchemaListener.kt
package mappertest.testConfig

@AutoScan
class TestDatabaseSchemaListener(
    // ここで DI する JdbcTemplate は DataSourceConfiguration.kt で Bean 登録しているもの
    private val jdbcTemplate: JdbcTemplate
) : ProjectListener {
    override suspend fun beforeProject() {
        jdbcTemplate.execute("CREATE DATABASE IF NOT EXISTS [TEST database]")
        jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS [TEST database].[table] LIKE [database].[table]")
    }
    // プロジェクト評価後にテスト用 DB は drop する
    override suspend fun afterProject() {
        jdbcTemplate.execute("DROP DATABASE IF EXISTS [TEST database]")
    }
}

👇 GitHub Actions のワークフロー作成

GtiHub Actions のワークフローは .github/workflows 配下に定義する。
yaml 形式で記述する。

テストが通っていることは常に確認したい項目なので、push された時をトリガーとして動作するようにした。

Docker イメージは 2 回目以降はキャッシュから起動され、2 回目は実行時間が短縮された。

.github/workflows/test.yaml
name: gradle test task

on:
  push:

jobs:
  test:
    name: set up and run gradle test
    runs-on: ubuntu-latest

    steps:
      # リポジトリにチェックアウトする
      - name: Checkout
        uses: actions/checkout@v3

   # コンテナ (MySQL) の起動
      - name: Up docker-compose
        run: docker-compose up -d

      # JDK のセットアップ
      - name: Set up jdk
        uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: temurin

      # Gradle のセットアップ
      - name: Set up gradle
        uses: gradle/gradle-build-action@v2

      # テストの実行 (test タスク内部で DB のマイグレーションなどが行われる)
      - name: Run test
        run: ./gradlew test

🌱 実行結果

ワークフローの実行結果は Actions タブから確認できる。

Github Actions の実行結果

Discussion