| 階段 | 工具 | 核心價值 |
| 結構探查 | Swing Explorer | 運行時可視化組件樹、屬性檢查、EDT 違規監控 |
| 功能測試 | FEST-Swing | 流式 API 模擬用戶操作、斷言驗證、截圖失敗分析、線程安全檢查 |
Swing Explorer:運行時 X 光機
安裝與啟動
- Eclipse/NetBeans 插件市場搜索「Swing Explorer」安裝
- 右鍵主類 → Run As → Swing Explorer
核心視圖
- 組件樹:層級結構,支持按名稱/類型過濾
- 屬性面板:選中組件的完整屬性(名稱、大小、邊框、模型數據等)
- EDT 監視器:實時檢測非 EDT 線程訪問 Swing 組件違規
- UI 快照:當前界面截圖,支持組件高亮定位
實戰:識別 HTML 編輯器文本區組件類型
源碼不可用時,Swing Explorer 單擊界面文本區 → 屬性面板顯示 javax.swing.JTextPane,秒級定位。
FEST-Swing:流式功能測試框架
核心特性
- 基於 AWT Robot 真實模擬用戶輸入(OS 級事件)
- 流式 API:
dialog.textBox("name").enterText("text")
- 組件查找按名稱/類型/屬性,免受布局變更影響
- 豐富斷言:
requireText()、requireEnabled()、requireVisible()
- JUnit 4 / TestNG 原生支持
- EDT 違規檢測:
FailOnThreadViolationRepaintManager
- 失敗自動截圖嵌入測試報告
依賴配置
org.easytesting
fest-swing
1.2.1
test
org.junit.jupiter
junit-jupiter
5.9.0
test
實戰:HTMLDocumentEditor 測試套件
測試基類
import org.fest.swing.fixture.FrameFixture;
import org.fest.swing.edt.GuiQuery;
import org.fest.swing.junit.testcase.FestSwingJUnitTestCase;
import org.junit.Before;
import org.junit.Test;
public class HTMLDocumentEditorTest extends FestSwingJUnitTestCase {
private FrameFixture editor;
@Override
protected void onSetUp() {
editor = new FrameFixture(robot(), createNewEditor());
editor.show(); // 顯示窗口並等待就緒
}
private static HTMLDocumentEditor createNewEditor() {
return execute(new GuiQuery() {
@Override protected HTMLDocumentEditor executeInEDT() {
return new HTMLDocumentEditor(); // EDT 中創建
}
});
}
}
用例 1:打開 HTML 文件
@Test
public void shouldOpenFile() {
// 點擊菜單 File > Open
editor.menuItemWithPath("File", "Open").click();
// 定位文件選擇器
JFileChooserFixture fileChooser = findFileChooser().using(robot());
// 選擇測試文件
fileChooser.setCurrentDirectory(temporaryFolder())
.selectFile(new File("helloworld.html"))
.approve(); // 點擊「打開」
// 驗證編輯器內容包含 "Hello"
assertThat(editor.textBox("document").text()).contains("Hello");
}
用例 2:改變字體顏色
@Test
public void shouldChangeFontColor() {
editor.menuItemWithPath("Color", "Yellow").click();
JTextComponentFixture textBox = editor.textBox();
textBox.enterText("Hello");
// 驗證生成的 HTML 包含黃色字體標籤
assertThat(textBox.text()).contains("Hello");
}
複雜組件測試:JTable 編輯
Sun 官方 TableDialogEditDemo 包含 ComboBox/CheckBox 編輯器的表格。FEST-Swing 一行搞定「第 0 行第 2 列選擇 ComboBox 第三項」:
dialog.table().enterValue(row(0).column(2), "Knitting");
內部自動處理:滾動顯示 → 單擊單元格 → 等待編輯器彈出 → 定位 ComboBox → 選擇項目 → 提交。
EDT 線程安全檢測
Swing Explorer EDT 監視器
運行時實時標記非 EDT 線程訪問組件的調用堆棧,圖形化展示違規路徑。
FEST-Swing 強制失敗
@BeforeClass
public static void setUpOnce() {
FailOnThreadViolationRepaintManager.install(); // 違規即拋異常終止測試
}
或繼承 FestSwingJUnitTestCase/FestSwingTestngTestCase 自動安裝。
測試失敗故障排查
1. 環境干擾(殺毒彈窗等)
FEST-Swing 失敗時自動截圖桌面,嵌入 JUnit/TestNG HTML 報告,點擊鏈接即可查看失敗瞬間全屏截圖。
2. 組件查找失敗
拋出 ComponentLookupException 並附帶完整組件層次結構:
Component hierarchy:
myapp.MyFrame[name='testFrame', title='Test']
javax.swing.JRootPane
javax.swing.JPanel[name='contentPane']
javax.swing.JTextField[name='name', text='Click Me'] ← 實際名稱為 'name' 而非 'firstName'
Swing Explorer 可視化查看層次結構,比文本堆棧直觀得多。
3. 多重匹配
Found more than one component using matcher NameMatcher[name='firstName', type=JTextField]:
javax.swing.JTextField[name='firstName', text='']
javax.swing.JTextField[name='firstName', text='']
需修正組件命名保證唯一,或使用更精確查找條件(類型+屬性組合)。
錄製/回放工具展望
FEST 團隊正開發基於 Java API 的錄製/回放工具,優勢:
- 生成面向對象、可重構、可維護的測試代碼(而非專有腳本)
- 享受 IDE 重構、調試、版本控制全工具鏈支持
- 避免傳統錄製工具「改一處、改所有錄製腳本」的維護噩夢
總結
- 先探查:Swing Explorer 秒級掌握 GUI 結構、組件類型、屬性、EDT 違規
- 再測試:FEST-Swing 流式 API 編寫可讀、強健、可維護的功能測試
- 守底線:
FailOnThreadViolationRepaintManager 捕獲線程違規
- 快排查:失敗截圖 + 組件層次結構 = 分鐘級定位根因
Swing 測試不再是噩夢。善用工具,讓 GUI 質量保證從「人工點點點」進化為「自動化回歸守門員」。
- 上一篇文章: Java Swing 全屏模式編程指南
- 下一篇文章: 類加載器進階:OSGi 環境下的代碼生成與橋接機制
Copyright ©
程式碼之家 All Rights Reserved