Unix/Linux下有界面的軟件相當少,另外其下的界面開發一般基于GTK+庫,完全異于Windows下。所以,通常大家討論的界面自動化開發是Windows下的應用程序。但Unix/Linux下也有些GUI自動化測試工具,比如運行在X11(Mac OS X)環境下的GNU Xnee,運行在Unix/Linux下支持GNOME的GNU/Linux Desktop Testing Project (GNU/LDTP)等等。
從零開始開發界面自動化工具可以如下走:
1. 采用Hook技術,截取鍵盤信息、鼠標信息、事件信息來得到界面的HWnds、Controls、Properties,此類程序一般命名為*SPY*;
2. 采用Win32函數FindWindow/FindWindowEx來一級一級的識別窗口,或EnumWindows/EnumChildWindows枚舉窗口再用GetClassName、GetWindowText(GetWindowTextA)/ GetWindowTextW分別獲取窗口類名、窗口標題欄,Win32優點在于更快和更可靠(MSAA和UI Automation對某些界面元素不能應用,MSAA沒用SendMessageTimeout);
例:使用EnumChildWindows
BOOL CALLBACK EnumChildProc(HWND hwndChild,LPARAM lParam) { TCHAR szWndTitle[1024]; int nLen = GetWindowText(hwndChild,szWndTitle,1024); return TRUE; } HWND hNMMainWnd = FindWindowEx(NULL,NULL,NULL,"DemoForm"); EnumChildWindows(hNMMainWnd,EnumChildProc,NULL); 例:檢查checkbox選中 HWND hwndCB = FindWindow(NULL,"DemoForm"); hwndCB = FindWindowEx(hwndCB,NULL,NULL,"Check1"); GetDlgItem(hwndCB,00400000); int a = (int)::SendMessage(hwndCB, BM_GETCHECK, 0, 0); 例:IE地址欄自動輸入 HWND hWnd = FindWindow("IEFrame",NULL); SetForegroundWindow(hWnd); //前端顯示 hWnd = FindWindowEx(hWnd,NULL,"WorkerW",NULL); hWnd = FindWindowEx(hWnd,NULL,"ReBarWindow32",NULL); hWnd = FindWindowEx(hWnd,NULL,"ComboBoxEx32",NULL); hWnd = FindWindowEx(hWnd,NULL,"ComboBox",NULL); hWnd = FindWindowEx(hWnd,NULL,"Edit",NULL); CRect rect; GetWindowRect(hWnd,&rect); ClipCursor(&rect); ClipCursor(NULL); mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0); mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0); for(int i=0; i<10; i++) { keybd_event(65,0,0,0); keybd_event(65,0,KEYEVENTF_KEYUP,0); Sleep(500); }3. 等待界面出現的過程中,加入同步機制,直到界面元素Clickable;
使界面元素Clickable的途徑:
l 移動窗口
l 設置焦點
l 擴展原型
l 滾動
4. 采用MS提供的已封裝好的MSAA庫(通用于Windows Vista之前的OS但不包括Win98)或者Windows UI Automation庫(支持Windows Vista及以后),此庫已集成在最新的VS 2008中的WPF里面。利用這些已經封裝好的庫能對所有標準的Windows控件進行自動化識別。但對非標準控件支持不好,比如騰訊公司的QQ系列。
總結,Windows界面自動化主要用到的APIs
1. Win32/Win64
2. UI Automation/MSAA
3. DOM等其它擴展,主要支持Web程序
附錄A:extern "C" __declspec(dllexport)
__declspec(dllexport)聲明動態導出函數;“C”表示按照標準C進行編譯,extern "C" 保證輸出的函數按C的方式命名,即在原函數名前加下劃線前綴“_”。
附錄B:MSAA庫中函數列表
[oleacc.dll]
AccessibleObjectFromWindow
CreateStdAccessibleObject
GetRoleTextW
LresultFromObject
ObjectFromLresult
DllRegisterServer
DllUnregisterServer
AccessibleChildren
AccessibleObjectFromEvent
AccessibleObjectFromPoint
CreateStdAccessibleProxyA
CreateStdAccessibleProxyW
DllCanUnloadNow
DllGetClassObject
GetOleaccVersionInfo
GetProcessHandleFromHwnd
GetRoleTextA
GetStateTextA
GetStateTextW
IID_IAccessible
IID_IAccessibleHandler
LIBID_Accessibility
WindowFromAccessibleObject
[Msaatext.dll]
DllCanUnloadNow
DllGetClassObject
DllRegisterServer
DllUnregisterServer
附錄C:前沿
據傳微軟采用一種基于Win32消息、MSAA、DOM等技術;一種基于UI Automation技術;一種支持MSAA、IE和UI Automation錄制/回放工具。