InstallAnywhere (IA) 提供基於 JUnit 3 的安裝程序圖形界面自動測試框架,解決 Swing/AWT 程序自動測試難題。本文剖析框架架構、四大 Fixture、核心組件協作流程,通過完整範例演示測試用例編寫,並針對框架不足(自定義面板/邏輯不可測、Java 編寫腳本不適合複雜場景)提出擴展方案:擴展事件類型支援自定義面板與業務邏輯、引入 XML 腳本描述測試用例、改進控制器解析執行 XML。
| Fixture | 職責 |
|---|---|
| 工作目錄 | 創建測試工作目錄 |
| 臨時目錄 | 創建臨時目錄 |
| Java 程序執行 | 啟動 IA 安裝程序 (runInstall) |
| GUI 自動測試 (核心) | 測試用例控制器、事件通知服務器、自測試機器人 |
waitForWindow/waitForPanel)pressEnter/pressTab/type/pressKey)面板:Introduction → Choose Install Folders → Install Complete
public class BasicProjectAutomation extends GUIAutomationFixture {
private static final String NEW_LOCATION = "newlocation";
private static final String PRODUCT = "BasicProject";
private static final String BUILD_OUTPUT = "_Build_Output/Web_Installers/InstData/Java";
public void testInstall() {
File installer = new File("./" + PRODUCT + BUILD_OUTPUT, "install.jar");
File installDir = new File("C:/Program Files", NEW_LOCATION);
setWaitTimeout(30 * SECONDS);
runInstall(PRODUCT, installer); // 執行測試用例
assertInstallerHasCompletedSuccessfully(); // 斷言安裝成功退出
assertTrue("Install dir created", installDir.exists());
assertTrue("File copied", new File(installDir, "file-to-install.txt").exists());
}
}
private void runInstall(String productName, File installer) {
try {
launchInstaller(installer.getPath());
waitForWindow(productName);
waitForPanel("Introduction");
pressEnter(); // 點擊下一步
waitForPanel("Choose Install Folder");
pressTab(); // 定位到路徑輸入框
for (int i = 0; i < productName.length(); i++) pressKey(KeyEvent.VK_BACK_SPACE);
type(NEW_LOCATION); // 輸入新路徑
waitForPanel("Install Complete");
pressEnter(); // 完成
waitForInstallerToComplete();
} finally {
printJavaOutput("Installer");
}
}
cuspanel.shown:PANEL_NAMEcuscode:active:CUSCODE_NAMEprotected void waitForCusPanel(String s) { waitForEvent("cuspanel.shown:" + s); }
protected void waitForCusCode(String s) { waitForEvent("cuscode:active:" + s); }
自定義面板/邏輯代碼中需主動發送對應事件通知(Socket 寫入)。
| 節點 | 子節點/屬性 |
|---|---|
| Product | install、uninstall、name、installer、buildOutput |
| install/uninstall | presenter、pressTab、type、pressKey、releaseKey、waitForWindow、waitForPanel、waitForCusPanel、waitForCusCode、launchInstaller/launchUninstaller、waitForInstallerToComplete |
| 動作屬性 | pressEnter、pressTab(times)、type、pressKey(times)、releaseKey、waitForWindow、waitForPanel、waitForCusPanel、waitForCusCode、launchInstaller、launchUninstaller、name、waitForInstallerToComplete |
<?xml version="1.0" encoding="UTF-8"?>
<Product name="BasicProject" installer="install.jar" buildOutput="_Build_Output/Web_Installers/InstData/Java">
<install>
<waitForWindow>BasicProject</waitForWindow>
<waitForPanel>Introduction</waitForPanel>
<pressEnter/>
<waitForPanel>Choose Install Folder</waitForPanel>
<pressTab times="1"/>
<pressKey times="12"/>
<type>newlocation</type>
<waitForPanel>Install Complete</waitForPanel>
<pressEnter/>
<waitForInstallerToComplete/>
</install>
</Product>
新增 XML 解析器 於測試用例控制器,讀取腳本動態構建測試序列,開發者專注測試邏輯編寫,無需關注 Java 語法。