Pywinauto之Windows UI 自動化1

  • 2019 年 10 月 8 日
  • 筆記

前言,公司要搭建自動化測試環境,涉及到對設備軟體的燒錄操作,在網上找了些資料,發現pywinauto這個python庫,能很好的支援PC端跑自動化,為此,記錄下學習過程

一、環境搭建

1、pywinauto安裝:pip install -U pywinauto

安裝完成後在終端中輸入:from pywinauto.application import Application若沒有出現錯誤提示,則說明該模組安裝成功,相關pywinauto操作指引詳見

官方文檔https://pywinauto.readthedocs.io/en/latest/getting_started.html

2、工具介紹

Spy++ (定位元素工具(win32))

Inspect(定位元素工具(uia))

UI Spy (定位元素工具)

Swapy(可簡單生成pywinauto程式碼)

二、pywinauto操作使用

1、導入模組from pywinauto.application import Application

2、判斷是被測對象是什麼語言,如官方文檔所示,主要是判斷backend是什麼類別

Once you have installed pywinauto - how do you get going? The very first necessary thing is to determine which accessibility technology (pywinauto』s backend) could be used for your application.    The list of supported accessibility technologies on Windows:    Win32 API (backend="win32") - a default backend for now  MFC, VB6, VCL, simple WinForms controls and most of the old legacy apps  MS UI Automation (backend="uia")  WinForms, WPF, Store apps, Qt5, browsers  Notes: Chrome requires --force-renderer-accessibility cmd flag before starting. Custom properties and controls are not supported because of comtypes Python library restrictions.    AT SPI on Linux and Apple Accessibility API are in the long term plans so far.

3、如何判斷程式的backend是』win32』還是』uia』呢?官方文檔中推薦使用spy++和inspect來檢查。有人專門整理了一下,放在github上了https://github.com/blackrosezy/gui-inspect-tool。

Switch Inspect.exe into UIA mode (using MS UI Automation). If it can show more controls and their properties than Spy++, probably the "uia" backend is your choice.

4、介紹使用inspect來判斷backend的類別

>下載上面github鏈接里的相關工具並打開,點擊inspect左上角的下拉列表中切換到UI Automation

>然後滑鼠點一下你需要測試的程式窗體,inspect就會顯示相關資訊。 下圖為點擊window文件夾的結果,inspect中顯示了相關的資訊,如下圖所示。說明backend為uia。

>相反,如下圖所示為win32

5、確定自動化入口

主要是限制自動化控制進程的範圍。如一個程式有多個實例,自動化控制一個實例,而保證其他實例(進程)不受影響。 主要有兩種對象可以建立這種入口點——Application() , Desktop().

Application的作用範圍是一個進程,如一般的桌面應用程式都為此類。

Desktop的作用範圍可以跨進程。主要用於像win10的計算器這樣包含多個進程的程式。這種目前比較少見。使用方法見entry-points-for-automation

三、控制項定位方式

1、window,dialog定位方式

1、基於title定位

a)如何獲取title?

title為窗口的名稱,可使用UISpy一類的定位元素工具去查找。

如圖所示,該對話框中的title為Name屬性值:「打開」

b)若使用定位元素工具找不到title怎麼辦?

使用print_control_identifiers()方法列印出當前窗口或對話框中的所有title

格式:

app.YourDialog. print_control_identifiers()

D:pythonpython3.6.1python36.exe D:/work/test/2019_07_25/python_PC.py  Control Identifiers:    Dialog - 'UpgradeDownload - R21.0.0001'    (L250, T250, R1690, B1010)  ['UpgradeDownload - R21.0.0001Dialog', 'UpgradeDownload - R21.0.0001', 'Dialog', 'Dialog0', 'Dialog1']  child_window(title="UpgradeDownload - R21.0.0001", control_type="Window")     |     | Dialog - 'Download'    (L727, T525, R1213, B736)     | ['Download', 'DownloadDialog', 'Dialog2']     | child_window(title="Download", control_type="Window")     |    |     |    | Button - '是(Y)'    (L1015, T690, R1103, B720)     |    | ['Button', '是(Y)Button', '是(Y)', 'Button0', 'Button1']     |    | child_window(title="是(Y)", auto_id="6", control_type="Button")     |    |     |    | Button - '否(N)'    (L1113, T690, R1201, B720)     |    | ['Button2', '否(N)', '否(N)Button']     |    | child_window(title="否(N)", auto_id="7", control_type="Button")     |    |     |    | Image - ''    (L755, T580, R787, B612)     |    | ['', 'Image', '0', '1']     |    | child_window(auto_id="20", control_type="Image")     |    |     |    | Static - 'Load latest pac file?nn.0.3.206share_nxosROMDebugMS16GP-F1V1.1.1_2019.07.08_15.01.19GP-F1_ms16_V1.1.1_pacGP-F1_ms16_V1.1.1.pac'    (L795, T580, R1173, B650)     |    | ['Load latest pac file?nn\10.0.3.206\share_nxos\ROM\Debug\MS16\GP-F1\V1.1.1_2019.07.08_15.01.19\GP-F1_ms16_V1.1.1_pac\GP-F1_ms16_V1.1.1.pac', 'Static', 'Load latest pac file?nn\10.0.3.206\share_nxos\ROM\Debug\MS16\GP-F1\V1.1.1_2019.07.08_15.01.19\GP-F1_ms16_V1.1.1_pac\GP-F1_ms16_V1.1.1.pacStatic', 'Static0', 'Static1']     |    | child_window(title="Load latest pac file?nn.0.3.206share_nxosROMDebugMS16GP-F1V1.1.1_2019.07.08_15.01.19GP-F1_ms16_V1.1.1_pacGP-F1_ms16_V1.1.1.pac", auto_id="65535", control_type="Text")     |    |     |    | TitleBar - ''    (L730, T528, R1210, B550)     |    | ['2', 'TitleBar', 'TitleBar0', 'TitleBar1']     |    |    |     |    |    | Button - '關閉'    (L1163, T521, R1212, B541)     |    |    | ['Button3', '關閉', '關閉Button', '關閉0', '關閉1', '關閉Button0', '關閉Button1']     |    |    | child_window(title="關閉", control_type="Button"

2. control定位方式

a)基於title定位(同window,dialog中的title定位)

app[『your dialog title』][『your control title』]或app.dlg.control

b)層級定位

app.window(class_name=』Notepad』).window(class_name=『#32770』)

app.window(class_name=『Notepad』).child_window(class_name=『#32770』)

c)wpath定位

若元素值為空,或不是唯一的情況下,可使用類似selenium中xpath的定位方式,根據查子元素的序號去定位元素。示例:

app_window = app.window(class_name=『Qt5QWindowIcon』) #定位的)登錄窗口

app_window.children()[1].children()[0].children()[0] .children()[2] #定位用戶名輸入框控制項(序號從0開始查)

四、操作實例

這裡以展訊平台的燒錄工具[UpgradeDownload.exe]來記錄下自動化實現操作過程

1、首先是啟動應用程式

格式:start(self, cmd_line, timeout=app_start_timeout)

使用程式路徑啟動Demo:

app=Application().start(r"D:toolszhanxunpingtaiUPGRADEDOWNLOAD_R21.0.0001UPGRADEDOWNLOAD_R21.0.0001UpgradeDownload.exe")

2、實現程式碼

from pywinauto import Application  app = Application(backend="uia").start(r"D:toolszhanxunpingtaiUPGRADEDOWNLOAD_R21.0.0001UPGRADEDOWNLOAD_R21.0.0001BinUpgradeDownload.exe")

運行程式後就會打開指定路徑的應用程式了,接下來將說下如何操作應用窗口

~~~~~~~~~~~~~~~~~~