有着这样一个模块, 它是完全被构建出来的, 能够被应用于自动化方面的 GUI 应用程序, 并且它支持鼠标操作, 也支持键盘操作, 在那种元素控件树较为复杂的界面当中, 它能够辅助我们去完成自动化操作。
我在工作中,主要是使用来辅助做一些操作,来完成自动化测试。
安装
先要确认本地有环境,然后可以通过命令行安装:
pip install pywinauto
倘若你是运用 ide 的话, 能够借助 ide 来进行安装, 比如说像我这般形成习惯去使用的情形下, 便能够在其中予以添加:

添加
另有一些需手动去进行安装举动的方法举措, 然而其存在着些许麻烦复杂的状况情形, 并非很是令人倾向推举 , 于此处便不予以介绍说明了。
访问技术选择
在操作应用这件事情上, 首先要做的是对应用进行访问, 而访问应用存在着主要的两种技术。其中WIN32访问技术为经由MFC、VB6、VCL以及简单控件开发而成的应用提供支撑, 另外MS UI访问技术则为WPS、QT5、WPF、Store apps等这些通过相应开发方式得到的应用提供支撑。
「win32」是归属win32 API的, 「uia」是属于MS UI的。
运行时所采用的默认方式是win32。能够借由spy++ , 或者借助工具来判定究竟适宜选用哪一种。比如: 要是所应用的是uia模式 , 并且可见的控件以及属性数目更多的情形下 , 则可以选择uia , 与之相反的状况下 , 则可以选择win32。
这里提一下常用的分析工具:
我个人常用的是和spy++。
界面
打开应用
多数情况下都是需要打开应用的,实现方式也很简单:
app = Application(backend='uia').start('D:\\WireShark\\Wireshark.exe')
参数根据实际情况选择传uia还是win32。
启动方法实际上能够传递两个参数, 除开目标应用的启动程序地址之外, 还能够传递一个, 要是不进行传递, 默认的时间是5s。如果你所针对的程序启动以及运行的速度都十分缓慢, 那么可以把设置调整得久一些。
连接应用
要是所要操控的应用已然处在启动的状态之下, 那么能够直接开展连接, 并且连接的方式存在多种可供挑选:
# 通过应用完整路径
app = Application(backend='uia').connect(path="D:\\WireShark\\Wireshark.exe")
# 通过应用进程pid进行连接
app = Application(backend='uia').connect(process=pid)
其中的pid可以通过任务管理器进行查看:
查看pid
# 通过窗口句柄
app = Application(backend='uia').connect(handle=175)
然而, 我于实际操作之际, 运用窗口句柄, 其未曾成功过, 或许是我运用的姿势有所不妥, 不过, 依旧不建议运用窗口句柄。
# 通过组合参数
app = Application(backend='uia').connect(title_re='Wire', class_name='MainWindow')
参数传递的是应用的部分名称,可以通过查询到。
,定位
此前所获取的对象全都是应用, 然而我们实际进行操作的乃是应用窗口, 在此处便要来介绍怎样去获取窗口以及对话框。
最常用的是通过title定位:
window = app.window(title='Wireshark')
倘若并不明晰定位工具里的title处于哪一位置, 呈现的是什么, 能够借助fiers()方法把所有的title都打印出来:

fiers()的效果
当借助title进行定位之际, 要留意一下中英文所产生的影响, 要是属于中文的话, 或许会存在编码方面的问题, 这种情形下, 就需要进行转码操作。
标题实际上仅仅是()办法里的一类关键字参数, ()办法能够接纳好多类的关键字参数, 并且这些参数能够组合采用, 比如像这样:
window = app.window(title='Wireshark', class_name='MainWindow')
主要参数有这些:
凭借()同样能够相对轻易地获取到窗口, 然而此方法获取到手的却是程序而言的顶级窗口, 只可无奈并非Z – Order里的顶级窗口。故而该方法于使用之际需多次进行调试。
窗口操作
窗口的操作主要有最小化、最大化、恢复、关闭窗口:
# 最小化窗口
dlg.minimize()
# 最大化窗口
dlg.maximize()
# 恢复窗口
dlg.restore()
# 关闭窗口
dlg.close()
定位
控件进行定位, 实际上跟窗口定位大体是一样差不多的, 不太明白不晓得为啥子在设计这个的时候会将窗口以及控件当作是同一类事物东西。
相较于前面针对定位窗口所采用的()方式, 在对控件进行定位之际, 建议选用(), 这是由于要是直接运用(), 一旦控件并非处于当前窗口的子控件范畴, 而是子子控件的话, 便会出现定位失败的情况, 然而()方法却不会存在此类问题, 当然与之相对应的不足之处就在于当控件的深度太深之时, 执行此方法会比较耗费时间。
()方法传递的参数和()是一样的。
控件操作
控件自带了一些操作方法:
# 单击
click_input()
# 双击
double_click_input
# 右击
right_click_input
那些不好用之际, 像你的控件没法让进行点击, 然而恰好你期望能点击一回, 能够采用那借助鼠标来操作的某些办法:
# 导入鼠标方法
from pywinauto import mouse
# 点击鼠标左键,coords传的是像素位置
mouse.click(coords=(x,y))
# wheel_dist:为正向上滚动,为负向下滚动
mouse.mouse.scroll(coords=(x,y),wheel_dist=-1)
截图
测试过程中可能会需要截图作为证据,截图的方法也比较简单:
button = app.window(best_match='Unsaved').child_window(best_match='Cancel')
if button.exists():
button..capture_as_image().save(img_path)
模拟键盘的操作
也提供了键盘操作的方法:
# 导入键盘方法
from pywinauto.keyboard import *
# 全选
send_keys("^a")
# “+”:Shift
# “^”:Ctrl
# “%”:Alt
等待机制
有几个设置等待时间的方式,这里介绍一个:
# 等待窗口,超时时间是10s,重试1次
window.wait(wait_for='ready',timeout=10,retry_inteval=1)
实战
这里简单的演示一下用自动抓包并保存:
import time
from pywinauto import Application, Desktop, mouse
from pywinauto.keyboard import send_keys
def click_control(control):
control_rect = control.rectangle()
top = control_rect.top
bottom = control_rect.bottom
left = control_rect.left
right = control_rect.right
mouse.click(coords=(int((left+right)/2), int((top+bottom)/2)))
app = Application(backend='uia').start('D:\\WireShark\\Wireshark.exe')
window = app.window(best_match='Wireshark')
time.sleep(5)
window.set_focus()
app.window(best_match='Wireshark').child_window(best_match='WLAN').double_click_input()
time.sleep(5)
app.window(best_match='正在捕获').child_window(best_match='停止').click_input()
app.window(best_match='*WLAN').child_window(best_match='文件').click_input()
app.window(best_match='*WLAN').child_window(best_match='另存为').click_input()
click_control(app.window(best_match='*WLAN').child_window(best_match='文件名(N)'))
send_keys('aaa')
app.window(best_match='*WLAN').child_window(best_match='保存').click_input()
总结
PC 端自动化测试所用到的模块主要包含这些, 这里所讲的主要运用到类, 该类用于应用程序管理方面, 比如打开与关闭应用等操作, 还用于窗口管理方面, 像最小化、最大化、关闭窗口这些操作, 以及控件操作。
其具备的功能实际上是颇为丰富多样的, 然而真正切实会被运用到的实际上仅仅只是当中极小的一块儿, 持有兴趣的同学们能够更多地前往官网去翻找查看一番。09A6.JySgQ.CoM
A9F.JySgQ.CoM
90A.JySgQ.CoM
318.JySgQ.CoM
F99.JySgQ.CoM
F8.JySgQ.CoM
393.JySgQ.CoM
8188.JySgQ.CoM
F577.JySgQ.CoM
B2.JySgQ.CoM
AC1.JySgQ.CoM
5B.JySgQ.CoM
3A8.JySgQ.CoM
2914.JySgQ.CoM
4C.JySgQ.CoM
99.JySgQ.CoM
84C.JySgQ.CoM
1B11.JySgQ.CoM
19.JySgQ.CoM
CD.JySgQ.CoM
CAE.JySgQ.CoM
87.JySgQ.CoM
AE2.JySgQ.CoM
CFF.JySgQ.CoM
0A07.JySgQ.CoM
997.JySgQ.CoM
58.JySgQ.CoM
C3AB.JySgQ.CoM
2E93.JySgQ.CoM
F7D.JySgQ.CoM
8D8.JySgQ.CoM
6EA.JySgQ.CoM
D6.JySgQ.CoM
21D8.JySgQ.CoM
BD77.JySgQ.CoM
1E34.JySgQ.CoM
2BE.JySgQ.CoM
6.JySgQ.CoM
FC.JySgQ.CoM
17.JySgQ.CoM
963.JySgQ.CoM
F2.JySgQ.CoM
8B3.JySgQ.CoM
E047.JySgQ.CoM
A4.JySgQ.CoM
B.JySgQ.CoM
D7.JySgQ.CoM
0605.JySgQ.CoM
59.JySgQ.CoM
746B.JySgQ.CoM
01E3.JySgQ.CoM
C4D.JySgQ.CoM
B1C1.JySgQ.CoM
55AC.JySgQ.CoM
D4D.JySgQ.CoM
AF7C.JySgQ.CoM
082.JySgQ.CoM
74.JySgQ.CoM
146.JySgQ.CoM
451.JySgQ.CoM
6EA8.JySgQ.CoM
665.JySgQ.CoM
14.JySgQ.CoM
46F.JySgQ.CoM
D5C.JySgQ.CoM
CA58.JySgQ.CoM
75.JySgQ.CoM
03.JySgQ.CoM
69.JySgQ.CoM
AAA4.JySgQ.CoM
B21.JySgQ.CoM
5347.JySgQ.CoM
E.JySgQ.CoM
FC3D.JySgQ.CoM
3CFA.JySgQ.CoM
738.JySgQ.CoM
4B.JySgQ.CoM
88.JySgQ.CoM
20D.JySgQ.CoM
9A8.JySgQ.CoM
C6C0.JySgQ.CoM
5F0C.JySgQ.CoM
C640.JySgQ.CoM
F43.JySgQ.CoM
95C8.JySgQ.CoM
FDC.JySgQ.CoM
CC.JySgQ.CoM
09.JySgQ.CoM
03F0.JySgQ.CoM
AB.JySgQ.CoM
B9.JySgQ.CoM
1A.JySgQ.CoM
0DD.JySgQ.CoM
99A.JySgQ.CoM
8902.JySgQ.CoM
AF.JySgQ.CoM
456.JySgQ.CoM
1F.JySgQ.CoM
2E4.JySgQ.CoM
45.JySgQ.CoM
22.JySgQ.CoM
6D6F.JySgQ.CoM
A1A.JySgQ.CoM
1B.JySgQ.CoM
84.JySgQ.CoM
DB.JySgQ.CoM
7B91.JySgQ.CoM
10.JySgQ.CoM
983F.JySgQ.CoM
BD89.JySgQ.CoM
3AD5.JySgQ.CoM
44.JySgQ.CoM
5135.JySgQ.CoM
CDA.JySgQ.CoM
95C.JySgQ.CoM
004.JySgQ.CoM
9D7.JySgQ.CoM
9CD.JySgQ.CoM
C7B0.JySgQ.CoM
40C0.JySgQ.CoM
0CD.JySgQ.CoM
1.JySgQ.CoM
378.JySgQ.CoM
33A.JySgQ.CoM
4007.JySgQ.CoM
FC14.JySgQ.CoM
17B.JySgQ.CoM
E7.JySgQ.CoM
338.JySgQ.CoM
83E.JySgQ.CoM
F305.JySgQ.CoM
833F.JySgQ.CoM
820.JySgQ.CoM
7D.JySgQ.CoM
E9.JySgQ.CoM
F966.JySgQ.CoM
7EB.JySgQ.CoM
A06.JySgQ.CoM
F18.JySgQ.CoM
497.JySgQ.CoM
FB.JySgQ.CoM
2EE.JySgQ.CoM
11D.JySgQ.CoM
9.JySgQ.CoM
85.JySgQ.CoM
B18.JySgQ.CoM
C66E.JySgQ.CoM
714.JySgQ.CoM
F12.JySgQ.CoM
FAE.JySgQ.CoM
B13A.JySgQ.CoM
BDCB.JySgQ.CoM
E6.JySgQ.CoM
6F.JySgQ.CoM
678.JySgQ.CoM
641.JySgQ.CoM
8C.JySgQ.CoM
9FC.JySgQ.CoM
14A.JySgQ.CoM
5.JySgQ.CoM
24.JySgQ.CoM
2.JySgQ.CoM
3BF.JySgQ.CoM
C234.JySgQ.CoM
26F1.JySgQ.CoM
D.JySgQ.CoM
72F.JySgQ.CoM
B4.JySgQ.CoM
41.JySgQ.CoM
2810.JySgQ.CoM
83.JySgQ.CoM
6B9.JySgQ.CoM
3035.JySgQ.CoM
E7E2.JySgQ.CoM
CC1B.JySgQ.CoM
D65.JySgQ.CoM
1EE0.JySgQ.CoM
7.JySgQ.CoM
52CD.JySgQ.CoM
6EFE.JySgQ.CoM
EC2C.JySgQ.CoM
3.JySgQ.CoM
0BD.JySgQ.CoM
C.JySgQ.CoM
F.JySgQ.CoM
CA4.JySgQ.CoM
0.JySgQ.CoM
823A.JySgQ.CoM
8.JySgQ.CoM
4.JySgQ.CoM
B7.JySgQ.CoM
C96.JySgQ.CoM
DE7.JySgQ.CoM
76B.JySgQ.CoM
1BB.JySgQ.CoM





