Slide 1

Slide 1 text

SpringBoot x MyBatis x TestContainersでSQLテストを行う エキサイト株式会社 佐々木 興平

Slide 2

Slide 2 text

免責 本資料に掲載されている情報、ロゴ、画像などの知的財産権は、各権利者に帰属します。本資料の利用は、個 人的な目的の範囲内にとどめてください。 本資料は、投資勧誘を目的とするものではありません。投資に関する決定は、ご自身の判断で行ってください。 本資料に記載されている情報は、作成時点におけるものであり、今後予告なしに変更されることがあります。本 資料の内容に基づいて行われたいかなる行為についても、作成者は一切の責任を負いません。 本資料の内容は、作成者個人の見解であり、必ずしも所属会社の公式な見解を代表するものではありません。

Slide 3

Slide 3 text

自己紹介 佐々木興平 ( X: @earu) 所属: エキサイト(株) (4年6ヶ月)(ex.セレス,CA,ぐるなび) 職種: メディア事業部事業部長 兼 メディア事業部開発責任者 やっていること: - PdM - テックリード 最近チームでよくさわっている : - SpringBoot / Java / htmx / alpine.js / Tailwind CSS / MySQL PostgreSQL / Redis / AWS 色々/ AWS copilot CLI / Terraform ポリシー: - 設計は難しくても正しいものに寄せる - 設定は簡単なものに寄せる

Slide 4

Slide 4 text

JJUG CCC 初登壇になります 今回送ったプロポーザルは下記です。 (話しやすい順に並べています) Spring-boot-adminで簡易モニタリングを行い、開発生産性を上げる SpringBoot x htmx x Alpine.js x Tailwind.css による怖くないWeb開発 Spring AI x AWS Bedrockで簡単なAIアプリケーションを作る SpringBoot x Mybatis x TestContainerでSQLテストを行う <= 採択

Slide 5

Slide 5 text

ユニットテストで SQLテストしていますか?

Slide 6

Slide 6 text

NewSQLの登場と浸透 RDBは、負荷(特に書き込み負荷)に弱く、代 替手段としてNoSQL(MongoDBやDynamo など)にするしかないと思われていた。 NewSQLの登場でこの問題が解消され、移 行も多くのRDBの機能継承しているので比 較的容易。今後のRDBに期待。

Slide 7

Slide 7 text

メディア事業部もほぼ RDBにすべてのデータを寄せている メリット - データ型がある - ある程度柔軟な検索ができる - データ移行ツールなどが充実している - キャッシュと組み合わせると結構負荷にも 耐えられる デメリット - 設計力は結構必要 - 定期的にメンテナンス時間が必要 (セキュ リティアップデートなど

Slide 8

Slide 8 text

SQLを試す環境はある ローカルマシン上 ● ローカルにDBをインストール ● ローカルにDockerで構築 ● H2Databaseを起動する(MySQL、PostgreSQL, 一部制限あり?) サーバ上 ● 開発者ごとにサンドボックススキーマを立てる Web上 ● DB<> Fiddle (MySQL, Postgres, Db2, Firebird, SQL Server SQLite, YugabyteDB, Oracle) ● SQL Fiddle (MySQL, Postgres, SQL Server SQLite) ● DB Fiddle (MySQL, Postgres, SQLite)

Slide 9

Slide 9 text

SQLを試す環境はある ローカルマシン上 ● ローカルにDBをインストール ● ローカルにDockerで構築 ● H2Databaseを起動する(MySQL、PostgreSQL, 一部制限あり?) サーバ上 ● 開発者ごとにサンドボックススキーマを立てる Web上 ● DB<> Fiddle (MySQL, Postgres, Db2, Firebird, SQL Server SQLite, YugabyteDB, Oracle) ● SQL Fiddle (MySQL, Postgres, SQL Server SQLite) ● DB Fiddle (MySQL, Postgres, SQLite) 開発者が増えたときの同一環境構築コストが 高く再現性が難しい

Slide 10

Slide 10 text

SQLテストを行うには? ● (ローカルでもリモートでも) DBを立ち上げる ● DBのマイグレーションを正確に行う ○ これを実施しないと、テストが色々な理由で失敗するようになる ● テストコードを書く 下記の3つを行う必要がある。通常、SSHやdocker composeでDBを立ち上げる必要が あるが、Testcontainersは、DBの立ち上げ部分をテストコードに書けるというのが良い。

Slide 11

Slide 11 text

DBの環境構築をどうするか? Testcontainersを使用して、テスト時に環境構築をしてもらおう

Slide 12

Slide 12 text

TestContainersとは? DB、メッセージング、Web系サービスな どテスト用のDockerコンテナを提供する ためのオープンソースになります。 モック作成や設定ファイルなどの細かい 環境設定ではなく、テストコードの中に テスト環境をコードとして定義するように 設計されています。

Slide 13

Slide 13 text

TestContainersとは?(2) Moduleの提供も順次追加されています。 これがあると専用の起動クラスやパラメー タ等が用意されるます。 RDB, VectorDB, NoSQL Database, MessageBrokerなど JavaとGoとC#に提供されているModuleが 多い Minio、Redis、pg vector などもある

Slide 14

Slide 14 text

TestContainersを立ち上げてみる DEMO

Slide 15

Slide 15 text

TestContainersを立ち上げてみる (1) - Testcontainers/Modulesのページで使用したい Modulesを検索 - Maven/Gradleのdependenciesに記載する

Slide 16

Slide 16 text

TestContainersを立ち上げてみる (2) - 各言語のテストコードでコンテナを立ち上 げる - ほぼワンソースでいける。 - @DynamicPropertySourceでJDBCの接 続先を指定する必要があるので注意

Slide 17

Slide 17 text

TestContainersを立ち上げてみる (3) - 各設定情報はインスタンス変数の中身を見るとわかる。 - ポート番号・ホスト名は動的にすることのがオススメ (固定することも可能) - 固定にすると他のコンテナが立ち上がっているときに失敗するため - これを使用して、テストコードを記述する。

Slide 18

Slide 18 text

テストデータの管理をしよう 環境構築は終わったので、テストデータの管理をどうするか考える

Slide 19

Slide 19 text

テストデータの管理の方法 テストデータを用意する必要がある。 方法1: TestcontainerにSQLファイルが入ったディレクトリをマウントする 方法2: @Sqlアノテーションを使用する 方法3: JDBCドライバのTC_INITSCRIPTでSQLを実行指定する 方法4: マイグレーションツールでテストデータを管理する

Slide 20

Slide 20 text

テストデータの管理 (方法1:マウント機能を利用する ) メリット: - SQLファイルが分散しない - マイグレーションツール等を用意しなくていい デメリット: - マイグレーションツールを使用している場合、開 発とテストで異なるものを使用するので、ダブル メンテになる

Slide 21

Slide 21 text

テストデータの管理 (方法2:@Sqlを使用する ) メリット: - SQLファイルが分散しない - マイグレーションツール等を用意しなくていい デメリット: - マイグレーションツールを使用している場合、開 発とテストで異なるものを使用するので、ダブル メンテになる可能性がある

Slide 22

Slide 22 text

テストデータの管理 (方法2:@Sqlを使用する ) @Sqlもいくつか書き方がある - script指定、SQL文指定 @Sqlはメソッドから抜けるとロールバックされるので注意 (外からの確認が難しい)

Slide 23

Slide 23 text

テストデータの管理 (方法3:JDBCのTC_INITSCRIPTで...) JDBCドライバの設定で接続時にSQLが実行できる。 メリット: - コード側で意識しなくても実行可能 デメリット: - 個別で必要な場合には全く向かない

Slide 24

Slide 24 text

テストデータの管理 (方法4:マイグレーションツールを使用 する) Flywayの場合、依存関係を解決し、 SQLファ イルを設定すると、SpringBootが起動時にマ イグレーション用のSQLが実行される。 メリット: - 普段使っているマイグレーションツール と同じものが使用でき、二重管理になら ない デメリット: - マイグレーション処理が遅い場合にテ ストで待たされる

Slide 25

Slide 25 text

DB環境・データの準備は完了 DB環境の用意 => TestcontainersでOK マイグレーション => Flyway、SQLスクリプト、@Sql など... (お好みで)

Slide 26

Slide 26 text

SpringBoot x MyBatis x Testcontainers 連携 DB環境・データの準備は完了したので、テストコードを書く。 SpringBootを使用していれば、難しいことはなく淡々とSQLに接続しているソース に対してテストコードを書くだけでいい。

Slide 27

Slide 27 text

テストコード SpringBootを使用した通常のテストコードを書くだけ になります。

Slide 28

Slide 28 text

デモ

Slide 29

Slide 29 text

まとめ SpringBootとTestcontainersは相性がよく、既存のテストコードに簡単に導入 することができました。コンテナイメージのダウンロード以外は起動も速く、生産 性は上がると思います。 環境構築が大変なのかSQLテストを書いてる現場はあまり多くない印象があり ます。Testcontainersを使用することで、この問題を解消できると思うので導入 をしてみてください。

Slide 30

Slide 30 text

ご清聴ありがとうございました !

Slide 31

Slide 31 text

Appendix. FAQ - SpringBoot Docker Compose Support との棲み分け - Dockerは開発とテストで同じものを使用するか? - コンテナイメージはTestcontainersのモジュールにあるものしか使えな いのか?

Slide 32

Slide 32 text

SpringBoot Docker Compose Support との棲み分け SpringBootにもDocker Compose Support が入っています。 開発時に別ターミナルで 「docker compose up」を打たずに、SpringBootのアプリケー ション起動時に一緒に docker-compose.ymlに書いてあるコンテナ を起動してくれます。

Slide 33

Slide 33 text

SpringBoot Docker Compose Support との棲み分け (2) テスト時は処理をDocker Composeの 起動処理をスキップするプロパティが あるので、これをセットすればOK

Slide 34

Slide 34 text

Dockerは開発とテストで同じものを使用するか? Answer. 基本的にNG 基本的には開発とテストは完全にわけて使います。同じも のを使用すると個人環境に依存しすぎてしまうので、危険 です。

Slide 35

Slide 35 text

コンテナイメージは Testcontainersのモジュール以外でも 使えるのか? Answer: YES. 汎用的にコンテナを触るようにAPIが 用意されています。起動処理やパラ メータ設定などを書く必要があります が、基本的にはどんなコンテナでも使 えます。