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\10.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\10.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")

运行程序后就会打开指定路径的应用程序了,接下来将说下如何操作应用窗口

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