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录制/回放工具。