前言
由于测试工作的需要,对于某些场景,总是需要进行一些重复的操作,比如测试一个股票交易下单的功能,需要覆盖不同的种类代码(主板、创业板、科创板、场内基金等),这个时候使用人工的方式去测试,枯燥乏味,且效率不高,所以就想寻求一种解决方案,通过UI自动化的方式来完成重复工作。目前支持Windows平台的UI自动化工具或框架有很多,比如:Autoit、pywinauto、UIautomation、airtest 等等,这里我们使用由国人yinkaisheng开发的UIautomation框架来实现。
UIautomation框架介绍
uiautomation是yinkaisheng业余时间开发的供其自己使用的一个模块,uiautomation封装了微软UIAutomation API,支持自动化Win32,MFC,WPF,Modern UI(Metro UI), Qt, IE, Firefox等UI框架,最新版uiautomation2.0目前只支持Python 3版本,依赖comtypes和typing这两个包,但不要使用3.7.6和3.8.1这两个版本,comtypes在这两个版本中不能正常工作。
uiautomation支持在Windows XP SP3或更高版本的Windows桌面系统上运行。如果是Windows XP系统,请确保系统目录有这个文件:UIAutomationCore.dll。如果没有,需要安装补丁 KB971513 才能支持UIAutomtion.在Windows 7或更高版本Windows系统上使用uiautomation时,要以管理员权限运行Python,否则uiautomation运行时很多函数可能会执行失败或抛出异常。或者先以管理员权限运行cmd.exe,在cmd中再调用Python。
小试牛刀
工具好不好,先来试一下,先感受一下,这里我们以电脑中自带的计算器为例,简单的感受一下,实现一系列的计算,演示的步骤如下:
- 通过Win+R,打开运行窗口
- 输入calc,打开计算器程序
- 计算55*134
- 关闭计算器程序
- 结束
演示视频如下
演示代码如下
Bashfrom time import sleep
import uiautomation as auto
class Calc():
def open_calc(self):
#打开计算器
desktop=auto.PaneControl(Name='任务栏')
#点击任务栏
desktop.Click()
#Win+D ,显示桌面
desktop.SendKeys('{Win}d')
#Win+R ,打开运行界面,并输入calc,打开浏览器
desktop.SendKeys('{Win}r')
run_win = auto.WindowControl(Name='运行')
run_win_edit=run_win.EditControl(ClassName='Edit',Name='打开(O):')
run_win_edit.SendKeys("calc")
run_win_ok=run_win.ButtonControl(ClassName="Button",Name='确定')
run_win_ok.Click()
sleep(3)
def calc_auto(self):
calc_win=auto.WindowControl(ClassName='ApplicationFrameWindow',Name="计算器")
# 开始计算
calc_five=calc_win.ButtonControl(Name='五')
calc_five.Click()
calc_five.Click()
calc_mult=calc_win.ButtonControl(Name='乘以')
calc_mult.Click()
calc_one = calc_win.ButtonControl(Name='一')
calc_one.Click()
calc_three = calc_win.ButtonControl(Name='三')
calc_three.Click()
calc_four = calc_win.ButtonControl(Name='四')
calc_four.Click()
calc_equal= calc_win.ButtonControl(Name="等于")
calc_equal.Click()
sleep(3)
calc_win_close_btn = calc_win.ButtonControl(AutomationId='Close')
calc_win_close_btn.Click()
if __name__ == '__main__':
calc = Calc()
calc.open_calc()
calc.calc_auto()
UIautomation环境搭建
本文的使用的是Python 3.9的版本,Python的安装和配置不是本文的内容,故不描述,可以参考网上其他教程,Python安装完成后,使用pip install uiautomation来安装uiautomation框架,如下所示:
BashC:\Users\Administrator>pip install uiautomation
Collecting uiautomation
Downloading uiautomation-2.0.15-py3-none-any.whl (159 kB)
|████████████████████████████████| 159 kB 5.8 kB/s
Collecting comtypes>=1.1.10
Downloading comtypes-1.1.10.tar.gz (145 kB)
|████████████████████████████████| 145 kB 133 kB/s
Using legacy 'setup.py install' for comtypes, since package 'wheel' is not installed.
Installing collected packages: comtypes, uiautomation
Running setup.py install for comtypes ... done
Successfully installed comtypes-1.1.10 uiautomation-2.0.15
界面元素定位
由于我们要操作界面,所以获取界面的元素,比如按钮、文本框、下拉框等等,需要进行元素定位,这个过程我们也形象的称为"找对象",只有在准确的获取到元素的位置后,才能进行像点击、输入文本的操作,我们获取界面元素的方式有如下几种,可以结合起来使用。
第一种:通过UIautomation框架自带的脚本工具automation.py来获取元素定位,安装pip install uiautomation后,在Python的Scripts(比如C:\Python37\Scripts)目录中会有一个文件automation.py, 或者使用源码根目录里的automation.py。automation.py是用来枚举控件树结构的一个脚本,运行automation.py遍历控件时,支持下列参数:
-t int value, 延迟时间time秒,延迟指定秒数再遍历控件,
-r, 从树的根部(root: Desktop)遍历,如果不指定,从当前窗口遍历
-d, int Value, 遍历控件树的的深度depth,如果不指定,遍历整个树,和-c一起使用时,可以为负值
-f, 遍历焦点focus控件,如果不指定,从当前窗口遍历
-c, 遍历光标下的控件,如果不指定,从当前窗口遍历,如果同时指定-d, -d可以为负值,比如-d-2表示从光标下控件向上找到两层父控件,遍历这个父控件
-a, 获取光标下控件及其所有祖先(ancestor)控件
-n, 显示控件的完整name, 如果不指定,只显示前30个字符
用法示例:
automation.py –t3, 3秒后遍历当前窗口所有控件
automation.py –d2 –t3, 3秒后遍历当前窗口前三层控件
automation.py –r –d1 –t0 -n, 0秒后遍历root的第一层子控件,并显示控件完整名称
automation.py –c –t3, 3秒后遍历鼠标光标下面的控件信息
automation.py –c –t3 -d-2, 3秒后遍历鼠标光标下面的控件向上两层的父控件
第二种:使用元素定位工具,比如spy++、Inspect.exe、UIspy.exe,Microsoft Spy++是一个查看Windows操作系统的窗口、消息、进程、线程信息的工具,简单易用,功能强大;Inspect.exe也是一款控件识别工具,这两款工具都可在网络上下载,也可以通过关注【郑大钱呀】公众号,回复元素定位工具可同时获取三款工具的下载链接。
常用的控件类
由于一个界面中有很多种控件类型,所以在automation中不同的控件类型对应着不同的控件类,具体什么控件使用哪种控件类型,可以通过元素定位工具中的ControlType来判断,示例如下:
上图中的控件,就是使用EditControl这个控件类,automation支持如下的控件类:
- Control: 控制类型父类
- WindowControl: 窗口控件类
- PaneControl: 窗格控件类型
- ButtonControl: 按钮控制类型
- CheckBoxControl: 复选框控件类型
- ComboBoxControl: 组合框控件类型
- EditControl: 编辑控件类型
- ListControl: 列表控件类型
- ListItemControl: ListItem 控件类型
- MenuControl: 菜单控制类型
- MenuBarControl: 菜单栏控件类型
- MenuItemControl: 菜单项控件类型
- ScrollBarControl: 滚动条控件类型
- SliderControl: 滑块控制类型
- TabControl: 选项卡控件类型
- TabItemControl: TabItem 控件类型
- TableControl: 表控件类型
- TextControl: 文本控件类型
- TitleBarControl: 标题栏控件类型
- ToolBarControl: 工具栏控件类型
- ToolTipControl: 工具提示控件类型
- TreeControl: 树形控件类型
- TreeItemControl: 树项控件类型
- AppBarControlAppBar: 控件类型
- CalendarControl: 日历控件类型
- DataGridControl: 数据网格控件类型
- GroupControl: 群控类型
- HeaderControl: 标题控件类型
- HeaderItemControl: HeaderItem: 控件类型
- HyperlinkControl: 超链接控制类型
- ImageControl: 图像控制类型
- DataItemControl: 数据项控件类型
- DocumentControl: 文件控制类型
- ProgressBarControl: ProgressBar: 控件类型
- RadioButtonControl: 单选按钮控件类型
- SemanticZoomControl: SemanticZoom控制类型
- SeparatorControl: 分离器控制类型
- SpinnerControl: 微调控制类型
- SplitButtonControl: 拆分按钮控件类型
- StatusBarControl: 状态栏控件类型
- ThumbControl: 拇指控制类型
控件类支持的参数
- searchFromControl: 从哪个控件开始查找,如果为None,从根节点Desktop开始查找
- searchDepth: 搜索深度
- searchInterval: 搜索间隔
- foundIndex: 搜索到的满足搜索条件的控件索引,索引从1开始
- Name: 控件名字
- SubName: 控件部分名字
- RegexName: 使用re.match匹配符合正则表达式的名字,Name,SubName,RegexName只能使用一个,不能同时使用
- ClassName: 类名字
- AutomationId: 控件AutomationId
- ControlType: 控件类型
- Depth: 控件相对于searchFromControl的精确深度
- Compare: 自定义比较函数function(control: Control, depth: int)->bool
searchDepth和Depth的区别searchDepth在指定的深度范围内(包括1~searchDepth层中的所有子孙控件)搜索第一个满足搜索条件的控件Depth只在Depth所在的深度(如果Depth>1,排除1~searchDepth-1层中的所有子孙控件)搜索第一个满足搜索条件的控件。
常用方法
窗口相关方法
#查找窗口中的程序;
window = WindowContrl(searchDepth,ClassName,SubName)
#激活窗口;
window.SetActive()
#窗口置顶;
window.SetTopMost()
#窗口居中
window.MoveToCenter()
#判断此窗口是否存在;
window.Exists(maxSearchSeconds)
#关闭窗口;
window.GetWindowPattern().Close()
#窗口最大化;
window.ShowWindow(uiautomation.ShowWindow.Maximize)
#窗口最大化;
window.Maximize()
#截图;
window.CaptureToImage(‘Notepad.png’)
# 切换窗口
window.SwitchToThisWindow()
#打开控制台
automation.GetConsoleWindow()
#显示桌面;
automation.ShowDesktop()
程序关闭与打开相关方法
import subprocess,os
# 打开程序,filepath程序所在文件路径
subprocess.Popen('filepath')
#杀死程序进程
os.popen('taskkill /IM xxx.exe /F')
组合框相关方法
#查找下拉框
combox=ComboBoxControl(searchFromControl,AutomationId)
#点击组合框
combox.click()
#选择需要的选项;
combox.Select(“name”)
#展开
combox.Expand()
#折叠
combox.Collapse()
鼠标事件
#单击
Click()
#双击
DoubleClick()
#右键点击
RighClik()
#移动
MoveTo()
# 按压左鼠标
PressMouse()
#释放左鼠标
ReleaseMouse()
#按压右鼠标
RightPressMouse()
#释放右鼠标
RightReleaseMouse()
键盘事件
SendKeys("内容或按键")
sendKeys支持输入文本,也支持按键,包括组合键,具体如下:
延时等待
# 显示等待
window.SendKeys('{Ctrl}c', waitTime = 0.1)
#隐式等待
uiautomation.uiautomation.TIME_OUT_SECOND = 10
滚动条
#滚动滚动条,直到文本在窗口可见为止
ScrollIntoView()
日志
uiautomation.Logger.ColorfullyWrite('运行"<Color=Cyan>automation.py -h</Color>"显示帮助\n\n')
粘贴板
#获取剪切板的文本
GetClipboardText()
控件判断相关方法
#判断控件存在
automation.Exists()
#设置一个时间内查找到控件
automation.WaitForExist()
#重新查找控件
automation.Refind()
#判断控件是否消失
automation.Disappears()
#判断控件是否可用
element.IsEnabled
控件矩形坐标
rect = control.BoundingRectangle
BoundingRectangle#return rect.left, rect.top, rect.right, rect.bottom
rect.width() #宽度
rect.height()#高度
截图方法
CaptureToImage()
标签:控件,uiautomation,win,automation,类型,calc
From: https://www.cnblogs.com/ruiy/p/16963602.html