JavaFX 自動テスト

JavaFX 自動テスト

TestFX で LogoRRR をテストする

LogoRRRTestFX を使って JavaFX UI の統合テストを実行しています。これらのテストにより、新機能の追加、内部整理、依存関係の更新後も主要な操作が正常に動作することを確認でき、ユニットテストでは検出できない回帰を捕捉できます。

なぜ今なのか

20回以上のリリースを経て、LogoRRR は手動テストだけでは十分でないほど複雑になっていました。コードベースには、自動で問題を見つける仕組みが必要でした。TestFX を使えば、実際のアプリウィンドウを操作できます。ボタンのクリック、ファイルの開閉、UI 状態の検査などを、すべて JUnit テストメソッドから実行できます。

画面操作テストをいつ増やすかは、いつも判断が必要です。プロジェクト初期は UI の変化が速すぎてテストが追いつけません。しかし主要な流れが安定してきたとき、テストは負担ではなく開発を進める力になります。そのタイミングが 24.3.0 で訪れました。

実装

Scala の簡潔な構文は、小さなテスト DSL を構築するのに自然と向いています。ファイルを開く、閉じるボタンをクリックする、タブペインが空であることを確認する、といった小さな操作が読みやすい構成要素になります。

@Test def openAndCloseTab(): Unit = {
    checkForEmptyTabPane()
    openFile(path)
    checkForNonEmptyTabPane()
    clickOn(lookup(UiNodes.LogFileHeaderTabs).query[StackPane](), MouseButton.SECONDARY)
    waitAndClickVisibleItem(CloseTabMenuItem.uiNode(fileId))
    checkForEmptyTabPane()
}

UI テストを書くことで、本番コードにも改善が生まれました。ファイル I/O と外部プロセス呼び出しを抽象化する新しいサービス層が追加され、テストのためだけでなく設計そのものも整理されました。

テストで発見されたこと

  • アプリのシャットダウン動作 — 適切にクリーンアップされていなかったリソースがテストで明らかになりました
  • テストの独立性 — 各テストは独自に準備と後片付けを行う必要があり、共有 UI 状態に関するいくつかの微妙な前提が明らかになりました
  • パフォーマンスのベースライン — テスト実行時間に注目することで、テストの緩やかな遅延の蓄積を防げます
TestFX が LogoRRR のテストスイートを実行中。ユーザーが行う操作と同じ流れを自動で実行

ヘッダー写真:Sora Shimazaki(Pexels)