WSL2でSpringBootとTestcontainersを使う

2022/10/13に公開

この記事の目的

社内での開発はProxyを経由するため様々なツールのProxy設定が面倒で、新規参入者が開発環境を構築するのに手間が掛かる。
この問題に対処するために、Proxy設定済み&最低限のツールを導入済みの状態のWSL2のイメージを配布し、開発者がそれをインポートすることで開発環境の効率化を目指す。

構築する環境のイメージ

以下のツール群が導入済みの状態

  • JDK
  • Docker
  • Maven, Gradle

導入の大きな流れ

  • WSL2のイメージをインポートし起動する
  • IDEAを使えるようにFirewallの設定などを行う
  • IDEAのプロジェクトを設定する
  • SpringBootとTestcontainersを使ったサンプルアプリを導入する

手順詳細

WSL2のイメージをインポートし起動する

前提として、WSL2自体のインストールは完了しているものとする。
もしも完了していない場合には、MSの公式サイトなどを参考にしてインストールすること。
公式サイト

ここでは記載を省略するが、AWSのS3上にイメージを置いてあるので、PresignedURLを払い出して、ユーザーにイメージをダウンロードしてもらう。

WSL2イメージインポート

対象のイメージをローカルにダウンロードして PowerShell から以下のコマンドを実行する。

wsl --import {仮想マシン名} {ディスクイメージの配置場所} {イメージの tar ファイル}

wsl --import Ubuntu-20.04_dev_java .\wsl_manual_install\Ubuntu-20.04_dev_java .\ubuntu-20.04_dev_java.tar

仮想マシンの一覧表示

wsl --list --verbose
# 短縮形として、wsl -l -v でもOK

仮想マシンの起動

wsl -d {仮想マシン名}

仮想マシンの停止

wsl --terminate {仮想マシン名}

WSL2 から仮想マシンの登録削除

wsl --unregister {仮想マシン名}

IDEAを使えるようにFirewallの設定などを行う

IDEAでWSL2上のJava環境にアクセスするためには以下の手順が必要になる。

info
Firewall設定はWindowsをリブートすると再設定が必要なようだ。
これを永続化する方法は不明(未調査)

Firewallの設定

https://www.jetbrains.com/help/idea/how-to-use-wsl-development-environment-in-product.html#debugging_system_settings

WSL2上のファイルをIDEAから開く手順

https://pleiades.io/help/idea/how-to-use-wsl-development-environment-in-product.html#open-a-project-in-wsl

こちらのポイントはpathの指定方法。
キーボードからの入力が案外面倒なので、コピペ用にpathの先頭を記載しておく。
\\wsl$

IDEAのプロジェクトを設定する

WSL2上のJavaプロジェクトは、何故か、File>New>Project from Existing Sourceから開けない(開こうとするとIDEAが落ちる)ので、File>Openで開きます。
このため、開いた後で以下の設定が必要です。

  • File>Project Structures... でSDK(JDK)を設定する
  • pom.xmlを右クリックして、Add As Maven Projectを選択する

以上により、通常の(Windows上の)プロジェクトと同じ操作感で使用できる。

SpringBootとTestcontainersを使ったサンプルアプリを導入する

Testee(ターゲットクラス)は、普通のJpaRepositoryである。(特に実装をは追加していない)

package com.example.testcontainers.domain.repository;

import com.example.testcontainers.domain.model.Todo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface TodoRepository extends JpaRepository<Todo, Integer> {
}

これのテストクラスは以下のようになる。

package com.example.testcontainers.domain.repository;

import com.example.testcontainers.domain.model.Todo;

import java.util.List;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test; // jupiterの@Testを指定すること!!
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.jdbc.Sql;
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers
@DataJpaTest(excludeAutoConfiguration = AutoConfigureTestDatabase.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class TodoRepositoryTest {

    @Autowired
    private TodoRepository todoRepository;

    @Test
    @Sql(scripts = "classpath:/scripts/init.sql")
    public void test() {
        List<Todo> todos = todoRepository.findAll();
        Assertions.assertThat(todos.size()).isEqualTo(3);
    }
}

テストのプロパティーは以下の様に設定した。
JDBCドライバーはTestcontainerが提供しているクラスを使っている。

MySQLのDockerImageのバージョン(5.7.38)をここで指定しているのが若干気持ち悪いが、時間の関係で一旦これで...

spring.datasource.url=jdbc:tc:mysql:5.7.38://hostname:port/test?TC_MY_CNF=mysql_conf
spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver
spring.datasource.username=test
spring.datasource.password=
spring.datasource.sql-script-encoding=utf-8

spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true

これで、mvn test一発で、コンテナでMySQLが勝手に立ち上がってテストが出来るので、かなり楽チンである。

課題(または制約)

  • WSL2のイメージのサイズがでかい
    これは致し方ないのだが、OSのパッチを当てるとか色々とサイズが大きいがゆえに取り回しが不便ではある。
     Cloud9を使う(VSCodeからつなげられるらしい)とか、Docker使うとかの代替手段も併用したい。
  • WSL2 BackedだとIDEAが若干不安定
    これも致し方ないが、Windows上で直接IDEAを実行するよりも、不安定(起動時に立ち上がらず落ちることがたまにある)なので、VSCodeの方が良いかもしれない。

warn
VSCodeだとCheckStyleが動かないので、これさえ何とかすればIDEAよりも良いかも?
(2022-08-18追記:VSCodeでもCheckStyleは動くことが確認とれました。)

  • DB+APIをTestcontainersで稼働させる
    これは私の師匠が目論んでいるので、来週以降で試す(かも)→ 断念

ソース

ソースはGitHubに公開しておく。
https://github.com/akiraabe/testcontainers

参考記事

以下の記事はめちゃめちゃ参考になった。ありがとうございました!

https://qiita.com/kazuki43zoo/items/588bbfab3db9d6c0199f
https://qiita.com/os1ma/items/f8d3df2c61e16a7c8b20
https://qiita.com/y518gaku/items/c7d4734c5bf6e960606d
https://b1a9idps.com/posts/test-containers/

Discussion