はじめに
自宅管理システムのSpring Bootのバージョンアップをしないと。と思いつつ、テストがめんどくさい。と思い。
MockMvc でコントローラから一気通貫テストしているので大丈夫とは思いつつ。
TyhymeLeafとかJavaScriptとかはテストしていない。から、この際、E2Eテストを入れてみたいなと。
E2Eテストは、自宅のPHPのアプリでPlaywrightを入れていたけど、Java版とか無いのかな?と思ったら、あったので入れてみた。
Java版のPlaywrightの公式サイト
導入
サンプルはGeminiに作って貰い、ローカルでサクッと動いた。
・UserFlowE2ETest
・gradle
testImplementation "com.microsoft.playwright:playwright:1.61.0"
ハマったこと
ローカルでサクッと動いたけど、JenkinsのCI環境への導入時にハマりまくりましたので、残します。
前提
JenkinsからDockerを起動し、Docker上でgradleからUT実行をしています。
その1 Dockerイメージ上でplaywrightを実行。
元々以下イメージを利用していたのですが、色々ライブラリ足らず+ダウンロードがむっちゃ遅い。
FROM gradle:jdk25 AS builder
どうしようかと思い、調べたら以下のサイトに出会う
・大変お世話になったサイト
playwright入りの公式のDockerイメージがあったかと。(冷静に考えると確かに。)
せっかくなので最新を指定。
FROM mcr.microsoft.com/playwright/java:v1.61.0 AS builder
その2 他のUTと同じノリで書いたらトランザクション関連でハマる。
・他のUT
@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles("test")
@Transactional
@Sql
@WithUserDetails("admin")
public class MovieControllerTest {
初期データ投入とロールバックをしたかったので、同じノリで以下のように書いたら動かず。
※ ローカルだと動いた気がしたのですが、たぶん気のせいか?
@ActiveProfiles("test")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Transactional
@Sql
class UserFlowE2ETest {
Gemini曰く、「Transactional」だと初期投入しているトランザクションとE2Eテストのトランザクションが別になり、E2Eテストから初期投入データを参照できていない。とのこと。
ふむ。なので、即コミットに変更。動いた。
@ActiveProfiles("test")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Sql(scripts = "/com/tarosuke777/hms/UserFlowE2ETest.sql",
executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD,
config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))
class UserFlowE2ETest {
とはいえ、今度はE2Eテスト以外のUTが全滅。
何故かというと、E2Eテストで初期投入したデータが残っているらしく、全滅。
なので、E2Eテスト後に全削除したら、全て正常終了。
@ActiveProfiles("test")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Sql(scripts = "/com/tarosuke777/hms/UserFlowE2ETest.sql",
executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD,
config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))
@Sql(scripts = "/com/tarosuke777/hms/UserFlowE2ETest_cleanup.sql",
executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD,
config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))
class UserFlowE2ETest {
Gemini曰く、E2Eテストと他のテストでDBを分けたほうが良いのでは?等を提案されているのでそこらへんは追々、検討。
その3 Jenkins上からUTエラーの詳細が分からず。
これは、Playwrightというより元からの問題を放置していて、今回顕在化したのですが。
・仕組み
1)Jenkinsでリポジトリをチェックアウト
2)docker compose で、ビルド(テスト含む)、コンテナ起動
ビルド時は、JenkinsのワークスペースからソースをDockerイメージ内にコピー
ビルド時のテスト結果が「app/build/reports/problems/problems-report.html」に出力されるのですが、Dockerイメージ内にあると。
> Task :test FAILED
[Incubating] Problems report is available at: file:///app/build/reports/problems/problems-report.html
7 actionable tasks: 7 executed
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':test'.
> There were failing tests. See the report at: file:///app/build/reports/tests/test/index.html
あれ?どうやって、見ればよい?と。
最終的には、Jenkinsのコンソールに出力して解決しました。
が、色々考えて、Jenkinsのワークスペースにもコピーするようにしました。
こちらは、別記事にしようかと。
振り返り
書いてみると、コンパクトになりましたが他にも色々右往左往していました(笑)
いずれも、Geminiに言われるがままやっていたのですが、改めて考えるとGeminiからの話をちゃんと理解し、考えていたらもっとサクッとできたかも。
とはいえ、新しいことを理解するのは負荷が上がるから、ついつい目先の答えに飛びついてしまったのですが、急がば回れ。でちゃんと理解したほうが早かったのかな?と思いつつ、結果論だから、何とも言えない気もした今日この頃。