LogoRRR 使用 TestFX 对其 JavaFX 用户界面运行集成测试。这些测试确保核心工作流在新功能迭代、代码重构和依赖更新后仍能正常运行——并且能捕获单元测试根本无法发现的回归问题。
为何现在引入
经过 20 多个版本的迭代,LogoRRR 的复杂度已经高到仅靠手动测试难以为继的程度。代码库需要一张安全网。TestFX 使得直接驱动真实应用程序窗口成为可能——在 JUnit 测试方法中点击按钮、打开文件、检查 UI 状态。
何时投入端到端测试,始终是一个权衡的问题。项目早期,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()
}
编写前端测试的过程也推动了生产代码的改进。新增了一个 Service 层来抽象文件 I/O 和外部进程调用——这些变更在独立于测试收益之外改善了整体架构。
测试发现了什么
- 应用程序关闭行为 — 在测试环境下,从未被正确清理的资源变得一目了然
- 测试隔离 — 每个测试必须自行建立和清理状态,由此暴露了若干关于共享 UI 状态的隐性假设
- 性能基准 — 监控测试执行时间,防止缓慢测试的逐渐积累
题图摄影:Sora Shimazaki,来自 Pexels。
