pywinauto之PC端windows自动化测试
pywinauto是一个用纯Python编写的GUI自动化库,并为Windows GUI精心开发。最简单的是,它允许您将鼠标和键盘操作发送到Windows和Linux上的对话框和控件,而到目前为止,仅Windows才支持更复杂的基于文本的操作(正在开发Linux AT-SPI支持)。
pywinauto是一组用于自动化Microsoft Windows GUI的python模块。 最简单的是,它允许您将鼠标和键盘操作发送到窗口对话框和控件。
pywinatuo官方文档:https://pywinauto.readthedocs.io/en/latest/getting_started.html
pywinauto中文文档:https://www.kancloud.cn/gnefnuy/pywinauto_doc/1193035
一、环境安装
首先保证电脑已经安装好python、pip、 pywin32,然后会直接通过模块命令安装第三方库pywinauto:pip3 install pywinauto
其次环境检查命令行中打开python解释器,运行以下代码,windows自带的记事本会被启动,若无报错,则证明pywinauto已安装成功。
>>> from pywinauto.application import Application
>>> app = Application(backend="uia").start("notepad.exe")

如果对记事本做一些简单的操作,比如说如下:
from pywinauto.application import Application # 运行目标应用程序
app = Application(backend="win32").start("notepad.exe")
# 键入一个文本字符串
app.UntitledNotepad.Edit.type_keys("开始输入文字。。。", with_spaces=True)
# 选择一个菜单项
app.UntitledNotepad.menu_select("帮助->关于记事本")
# 单击一个按钮
app.关于记事本.确定.click()
# 关闭记事本
app["notepad.exe"].close()

注:因为我的是中文版本的记事本,所以代码里也要对号入座。
二、PC端元素定位工具介绍及判断backend
1.Backend判断
判断是被测对象是什么语言,如官方文档所示,主要是判断backend是什么类别
就是说在我们安装好Pywinauto之后,首先要确定哪种可访问性技术(pywinauto的backend)可以用于我们的应用程序。
Windows上支持的辅助功能技术列表:
Win32 API(backend=“Win32”)—目前的默认后端
MFC、VB6、VCL、简单的WinForms控件和大多数旧的遗留应用程序
MS UI自动化(backend=“uia”)
WinForms、WPF、商店应用程序、Qt5、浏览器
注意:Chrome在启动之前需要--force renderer accessibility cmd标志。由于comtypes Python库的限制,不支持自定义属性和控件。
在windows上受支持的辅助功能技术有两种:
◆ Win32 API (backend="win32") 默认backend
◆ MS UI Automation (backend="uia")
如果您不能确定程序到底适用于那种backend,可以借助于GUI对象检查工具来做,常用的检查工具有Inspect.ex,Spy++ 等。
Pywinauto中backend有两种:win32和uia,默认为win32。可使用spy++和Inspect工具判断backend适合写哪种。例如:如果使用Inspect的UIA模式,可见的控件和属性更多的话,backend可选uia,反之,backend可选win32。
如何判断程序的backend是’win32’还是’uia’呢?官方文档中推荐使用spy++和inspect来检查。有人专门整理了一下,放在github上了https://github.com/blackrosezy/gui-inspect-tool。
将Inspect.exe切换到UIA模式(使用MS UI Automation)。如果它可以显示比Spy++更多的控件及其属性,那么“uia”后端可能是您的选择。
介绍使用inspect来判断backend的类别
下载上面github链接里的相关工具并打开,点击inspect左上角的下拉列表中切换到UI Automation

然后鼠标点一下你需要测试的程序窗体,inspect就会显示相关信息。 下图为点击window文件夹的结果,inspect中显示了相关的信息,如下图所示。说明backend为uia。

相反,如下图所示为win32
2.工具介绍
Spy++ (定位元素工具(win32))
Inspect(定位元素工具(uia))
UI Spy (定位元素工具)
Swapy(可简单生成pywinauto代码)

确定自动化入口
主要是限制自动化控制进程的范围。如一个程序有多个实例,自动化控制一个实例,而保证其他实例(进程)不受影响。 主要有两种对象可以建立这种入口点——Application() , Desktop().
Application的作用范围是一个进程,如一般的桌面应用程序都为此类。
Desktop的作用范围可以跨进程。主要用于像win10的计算器这样包含多个进程的程序。这种目前比较少见。使用方法见entry-points-for-automation
三、启动并创建一个实例对象
连接应用程序,首先需要用到pywinauto.application.Application()来创建一个应用程序对象,然后再连接到应用程序。
有如下两种方法:
1.方式一:直接通过start方法打开操作的应用程序
start()用于还没有启动软件的情况。timeout为超时参数(可选),若软件启动所需的时间较长可选timeout,默认超时时间为5s。
start(self, cmd_line, timeout=app_start_timeout)
示例:
app = Application(backend = ‘uia’).start(r"E:\Office\Office14\EXCEL.exe)
2.连方式二:连接已经打开应用程序,可以通过connect连接到指定的应用程序
connect()用于连接已经启动的程序。连接一个已经运行的程序有以下几种方法:
a)process:进程id
app = Application().connect(process=2341)
b)handle:应用程序的窗口句柄
app = Application().connect(handle=0x010f0c)
c)path:进程的执行路径(GetModuleFileNameEx 模块会查找进程的每一个路径并与我们传入的路径去做比较)
app = Application().connect(path=“D:\Office14\EXCEL.exe”)
d)参数组合(传递给pywinauto.findwindows.find_elements()这个函数)
app = Application().connect(title_re=".*Notepad", class_name=“Notepad”)
注:应用程序必须先准备就绪,才能使用connect(),当应用程序start()后没有超时和重连的机制。在pywinauto外再启动应用程序,需要sleep,等程序start
四、 窗口、对话框及控件元素定位方式
打开这个窗口之后,我们要操作该窗口的话,那么就的先选中这个窗口,关于窗口的选择有一下几种方式:


1.window,dialog定位方式
1)基于title定位
a)如何获取title?
title为窗口的名称,可使用UISpy一类的定位元素工具去查找。
如图所示,该对话框中的title为Name属性值:“替换”

b)若使用定位元素工具找不到title怎么办?
使用print_control_identifiers()方法打印出当前窗口或对话框中的所有title
格式:
app.YourDialog. print_control_identifiers()
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开始查)
c)使用title定位方式的写法
Untitled_notepad = u’无标题 – 记事本’
app. Untitled_notepad.draw_outline(colour = ‘red’) #app.window(best_match=‘Untitled - Notepad’)
注:这种写法适用于英文系统,英文软件,其他语言的系统会存在编码问题,需转码再使用。
或
app[‘无标题 – 记事本’] .draw_outline(colour = ‘red’)
注:适用于除英文外其他语言的系统,不用转码
2)top_window()定位
app.top_window() #此方法可返回应用软件的最顶层窗口(是窗口,不是窗口弹出的对话框)
注:此方法目前没有经过测试,它会返回应用程序的顶级窗口,但可能不是Z-Order中的顶级窗口。
3)关键字传参
若以上方法不能满足定位元素的需求,可使用以下列表中的参数传参定位元素,参数可以组合使用。
示例:
app.window(class_name = ‘Notepad’).draw_outline(colour = ‘red’)
常用参数表:
可传参数	对应属性名称备注
class_name	ClassName
class_name_re	正则匹配window Classname
title Name	Window窗口名
title_re	正则匹配窗口名
best_match	模糊匹配类似的title
handle	句柄
framework_id	FrameworkId(一般情况下FrameworkId不是唯一的)
process	ProcessId,进程id(注意:每次启动后,进程id都会变)
control_id	control_id
control_type	ControlType()
auto_id	AutomationId
2. control定位方式
基于title定位(同window,dialog中的title定位)
app[‘your dialog title’][‘your control title’]
或
app.dlg.control
层级定位
app.window(class_name = ’Notepad’).window(class_name = ‘#32770’)
app.window(class_name = ‘Notepad’).child_window(class_name = ‘#32770’)
wpath定位
若元素值为空,或不是唯一的情况下,可使用类似selenium中xpath的定位方式,根据查子元素的序号去定位元素。
示例:
app_window = app.window(class_name=‘Qt5QWindowIcon’) #定位登录窗口
app_window.children()[1].children()[0].children()[0] .children()[2] #定位用户名输入框控件(序号从0开始查)
五、常用方法
1**.调试定位控件**
控件操作
程序窗口中的每一块内容,都是一个控件,我们要对这个窗口的某一块内容进行操作,就需要选择到对应的控件。
关于控件选择的方法有好几种,最简单的方法如下:

◆ 获取所有控件
我们可以通过print_control_identifiers()这个方法,来获取这个窗口下的直接子控件,如下:


a)print_control_identifiers(depth = None, filename = None)
以树形结构打印出所有控件可识别出的标识
depth:打印的深度,缺省时打印最大深度。
filename:将返回的标识存成文件(生成的文件与当前运行的脚本在同一个路径下)
eg:dlg. print_control_identifiers(filename =’a.txt’)
b)draw_outline(colour =’green’,thickness = 2,
fill = win32defines.BS_NULL, rect = None)
默认为在当前定位到的窗口或控件周围画出一条边界线,方便我们看出定位到了哪个控件
colour:边界线的颜色,默认为绿
thickness:线的粗细,默认为2
fill:以何种方式填充矩形(没试过,详见源码base_wrapper.py)
rect:根据坐标画出矩形(默认是在当前定位到的元素上画出一个矩形)
c) is_dialog 判断是否为dialog
2. 隐式等待
a) wait(wait_for, timeout = None, retry_interval = None)
wait_for可传入五种参数, 可以组合传参,但要以空格隔开:
exists: 窗口变成有效的句柄
visible: 窗口可见,没有隐藏
enabled: 窗口没有disable
ready: visible + enable
active: active
timeout:设置超时时间,若在n秒内没有等到窗口在wait_for中传入的几种状态,则会抛出TimeoutError。
retry_interval:超时后,间隔n秒再次重试。
Dlg.wait(“exists ready”, timeout = 5, retry_interval = 3)
b) wait_not(wait_for_not,timeout = None,retry_interval = None)
等待窗口不处于某种状态时。参数与wait传参一致。
3. 输入框输入
内容输入的方法:type_key()
Dlg.control.type_keys(“xxxxx”)
4. 菜单栏
menu_select()
eg:app.window.menu_select(Edit -> Replace)
5. 鼠标点击
a)click() 点击Button控件
b)check_by_click() 通过click()方法勾选checkbox
c)uncheck_by_click() 通过click()方法取消勾选checkbox
d)get_check_state() 返回checkbox的勾选状态(0没勾选,1勾选,2不定)
e)is_checked(勾选返回true,为勾选返回false,不定返回None)
f)check() 勾选checkbox
g)uncheck() 不勾选checkbox
h)invoke() 点击(uia mode)
i)toggle () 勾选checkbox(uia mode)
pywinauto操作鼠标的所有方法都封装在pywinauto. mouse这个模块中,使用鼠标之前。
首先要导入mouse模块,mouse模块中包含了一系列的鼠标操作事件。
◆ pywinauto. mouse
鼠标移动:move方法
move(coords=(x轴坐标,y轴坐标))
缓慢移动鼠标案例

鼠标点击:click

6. 键盘操作
“+”:Shift
“^”:Control
“%”:Alt
通过键盘完成以下操作:全选(ctrl+A) 复制(Ctrl+C) 粘贴(Ctrl+V) 回车(Enter) 粘贴(Ctrl+V)
◆ pywinauto.keyboard.send_key
pywinauto模拟操作键盘,需要使用到 pywinauto.keyboard.send_keys这个方法:

◆ 常见的按键操作
##### 字母按键用按键小写字母表示
常用的一些按键

按键修饰符

更多的键盘操作大家可以参考官网文档
pywinauto之PC端windows自动化测试的更多相关文章
- <自动化测试方案_7>第七章、PC端UI自动化测试
		第七章.PC端UI自动化测试 UI自动化测试又分为:Web自动化测试,App自动化测试.微信小程序.微信公众号UI层的自动化测试工具非常多,比较主流的是UFT(QTP),Robot Framework ... 
- python+pywinauto之PC端自动化一
		所需软件安装: 1.下载 pywinauto 安装参考: https://jingyan.baidu.com/article/414eccf6a1a3906b421f0a59.html 下载地址: h ... 
- 聊聊 PC 端自动化最佳方案 - Pywinauto
		1. 前言 大家好,我是安果! 上一篇文章,聊到 PC 端的一种自动化方案:WinAppDriver 聊聊 PC 端自动化最佳方案 - WinAppDriver 有小伙伴后台给我留言,说「 pywin ... 
- Unity读Excel 输出PC端(Windows)后不能读取的问题
		问题:在Unity中用ExcelDataReader读Excel时,在编辑器模式下可以正常读取,但是在导出PC端app后读Excel却会报空,Excel读取失败. 要点: 1.把库文件Excel.dl ... 
- Unity输出PC端(Windows) 拖拽文件到app中
		需求:给策划们写一个PC端(Window)的Excel导表工具.本来用OpenFile打开FileExplorerDialog后让他们自己选择想要添加的Excel文件就行了,结果有个需求是希望能拖拽E ... 
- Windows 之 手机访问 PC 端本地部署的站点
		测试网页在手机上的显示工具我们可以使用谷歌内核的浏览器,打开开发者工具(F12),在device那里选择设备,然后刷新来查看网页在手机上的显示效果. 但毕竟是模拟的,如果想要在真机上调试该怎么办呢. ... 
- pc端和android端应用程序测试有什么区别?(ps面试题)
		pc端和android端应用程序测试有什么区别?(ps面试题) [VIP7]大连-凭海临风(215687736) 2014/4/10 8:56:171.测试环境不同PC平台一般都是windows an ... 
- Macaca初体验-PC端(Python)
		前言: Macaca 是一套面向用户端软件的测试解决方案,提供了自动化驱动,周边工具,集成方案.由阿里巴巴公司开源:http://macacajs.github.io/macaca/ 特点: 同时支持 ... 
- 阻止pc端浏览器缩放js代码
		阻止pc端浏览器缩放js代码 众所周知:移动端页面禁止用户缩放界面只需加上<meta name="viewport" content="user-scalable= ... 
随机推荐
- Oracle批量插入有日期类型数据
			例如现在有张表 id(number) startTime(date) name(varchar2) 1 2017-08-13 zhangsan 2 2017-08-14 zhangsan 需要批量 ... 
- python使用for循环打印9*9乘法表。
			代码如下: for a in range(1, 10): for b in range(1, 10): if b <= a: print("%d*%d=%d\t" % (b, ... 
- Oracle根据实体类比对2个数据库结构差异(demo)
			源起 在公司做项目时 经常出现 实体结构和线上的数据结构以及公司开发库数据结构不匹配的问题 但是又不能直接把开发库导入到生产库因为生产库已经有实际数据了 所以弄了一个小工具 此处只做记录用 demo级 ... 
- 网络工程师和Linux运维工程师有什么区别?学哪个比较好?
			网络工程师和Linux运维工程师有什么区别?学哪个比较好? 机缘巧合下,我进入了一家从事vpn与系统集成的公司,很感谢公司能留下我这个非网络工程专业的毕业生,从对网络一窍不通,慢慢可以自己独立完成工作 ... 
- URL及short URL短网址
			URL,uniform resource locator,经常被称为网址,尤其是在使用HTTP的时候.通常是一个指向某个资源的字符串. URLs经常被用于网页(http),但也可以用于文件传输(f ... 
- 谈谈MySQL数据库索引
			在分析MySQL数据库索引之前,很多小伙伴对数据结构中的树理解不够深刻.因此我们由浅入深一步步探讨树的演进过程,再一步步引出MySQL数据库索引底层数据结构. 一.二叉树 二叉查找树也称为有序二叉查找 ... 
- 2016 Multi-University Training Contest 1 T3
			题目要求出所有合法点对间的最短路径的平均值,因此我们应当求出所有合法最短点对的最 短路径之和,再除以合法点对个数. 题目中Guard之间有着很不自然的制约关系,每个Guard的周围和同行.列都不能有其 ... 
- 在Servlet端获取html页面选中的checkbox值,request获取页面checkbox(复选框)值
			html端代码: 选项框: <input type="checkbox" name="crowd" value="选项一">选项 ... 
- 关于emgucv控制多摄像头问题
			看到这篇文章你或许已经查阅很多资料,也可能你刚准备深入研究,但是关于调用多摄像头问题我要说明一点,关于多摄像头调用 取决于你电脑本身USB控制器数量,不是说你电脑上5个usb就可以同时控制5台摄像头, ... 
- python的元类编程
			廖雪峰的python教程有python元类编程示例,综合代码如下 https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df ... 
