Python下编写Windows自动化测试软件
https://www.jianshu.com/p/be3c46c7a905
uiautomation模块学习笔记
前段时间,由于个人需要,在网上查找了一些关于Windows平台下自动化测试的资料,最后找到了一款相当不错的Python模块:uiautomation,直接pip install uiautomation即可方便地获取这个模块。在学习这个模块的同时,记些笔记,方便自己以后查阅,也方便大家翻阅。
0x00 概述
这个库在Github上是开源的,地址:https://github.com/yinkaisheng/Python-UIAutomation-for-Windows
而且作者是一名中国人,还是南京人,让我感觉十分亲切。
这个库可以说是十分贴合实际,在Windows平台下,绝大部分软件都要遵循Windows的规范,也就是说窗口啊,句柄啊、控件啊这些东西,都是通用的,Windows向外提供了这些接口。先感谢一下yinkaisheng,他的工作就是进一步给这些接口做了整合,给Python的开发者提供了接口。这极大地方便了想要用Python开发自动化测试程序的人。
0x01 作者的readme文档
- 这个模块是基于Windows的UIA技术实现的,系统最低需要WindowsXP SP3,支持MFC、WinForm、WPF、Metro UI(从Windows8开始Windows系统开发的一种新的窗口)、Qt和火狐,也就是说基于.Net技术的所有Windows窗体程序都支持,而其他的软件,比如基于DirectUI开发的,这个模块可能难以获取到其中的信息。
- 作者将这个模块开源了,基于Apache2.0,这以为着源代码可以任意复制,修改,使用以及再发布,赞!
- 安装方法很简单,在已有Python和pypi环境的电脑上运行
pip install uiautomation
即可安装,并且主程序automation.py也会自动复制到Python的Scripts文件夹下。 - 同时作者也提供了C++ dll的源码,但是在这里就不去涉及了。可以看出作者是名十分敬业的开发人员!
可以简单运行一下automation.py,直接运行的效果就是3秒后遍历当前活动窗口的所有控件。对QQ运行的效果:
可见效果十分明显,窗口内的控件信息全部都显示出来了,包括控件类型,控件的名称,控件的位置(以像素为单位),句柄,控件树深度等。同时,所有信息会保存到当前目录下的@AutomationLog.txt文件中,方便查阅。
- 作者提供了一个Demo,用于控制记事本程序:
import subprocess
import uiautomation as automation
print(automation.GetRootControl())
subprocess.Popen('notepad.exe')
notepadWindow = automation.WindowControl(searchDepth = 1, ClassName = 'Notepad')
print(notepadWindow.Name)
notepadWindow.SetTopmost(True)
edit = notepadWindow.EditControl()
edit.SetValue('Hello')
edit.SendKeys('{Ctrl}{End}{Enter}World')
GetRootControl()方法将返回根控件,也就是整个Windows可视化的桌面(这么理解没错吧)
WindowControl(searchDepth=1,ClassName='Notepad')方法将创建一个WindowsControl对象,参数的作用是细化如何找到我们想要的控件,可用的参数有searchFromControl=None,searchDepth=0xFFFFFFF,searchWaitTime=SEARCH_INTERVAL,foundIndex=1,Name,SubName,ClassName,Depth等,可以去源码下的Control类的初始化方法init看一下这些参数怎么用。
接下来作者介绍了一个小工具Inspect.exe,这个工具是微软提供的,可以用来探测UI的内容,这个程序自动集成在微软的Windows SDK中,我电脑上正好安装了Visual Studio和Windows SDK,应该可以找到这个程序。果然在工具集中找到了这个程序:
可以看到使用效果非常好,窗口的构造一目了然!
最后作者放了一些自己使用该模块的截图,可以看到,功能十分强大:
0x02 简单了解实现原理
作者在readme文档中外链了一篇博文,简单介绍了实现原理,为了能更好地掌握这个库的使用,这篇原理我也简单的学习一下。(原文链接)
在最早的Windows开发中是没有自动化测试的概念的。1997年微软在操作系统中集成了MASS(Microsoft Active Accessibility)组件,但是微软开发MASS组件的初衷并不是为了自动化测试,而是提供了一套接口,让开发者们可以方便的开发残疾人士辅助软件,比如读屏软件等。伴随着自动化测试的应用越来越广泛,微软正视了自动化测试的需求,在MASS的基础上,对其重新封装设计并实现了UIAutomation的类库(.NET)。从Win7系统开始的后续Windows操作系统都整合了Windows Automation API的所有功能。作者在阅读了MSDN上的《UI Automation Client Programmer's Guide》和CodeMagazine上的《Creating UI Automation Client Applications》两篇文章后,用Python和C++对UIAutomation做了一层简单的封装,方便了想要用Python开发自动化测试应用而对.Net平台又不太熟悉的人,比如我。
0x03 API学习摘要
之前也已经提到,这个模块是作者对UIA用C++和Python简单的做了一层封装,只要能理解面向对象编程,学习难度也不是很大。正好,我在作者的CSDN博客里面找到了作者使用此模块的实例(原文链接),就以此为学习的入口,代码如下:
#!python3
# -*- coding: utf-8 -*-
"""
本脚本可以获取QQ2017(v8.9.4)群所有成员详细资料,请根据提示做对应的操作
作者:yinkaisheng@foxmail.com
"""
import time
import uiautomation as automation
def GetPersonDetail():
detailWindow = automation.WindowControl(searchDepth= 1, ClassName = 'TXGuiFoundation', SubName = '的资料')
details = ''
for control, depth in automation.WalkControl(detailWindow):
if isinstance(control, automation.EditControl):
details += control.Name + control.CurrentValue() + '\n'
details += '\n' * 2
detailWindow.Click(-10, 10)
return details
def main():
automation.Logger.WriteLine('请把鼠标放在QQ群聊天窗口中的一个成员上面,3秒后获取\n')
time.sleep(3)
listItem = automation.ControlFromCursor()
if listItem.ControlType != automation.ControlType.ListItemControl:
automation.Logger.WriteLine('没有放在群成员上面,程序退出!')
return
consoleWindow = automation.GetConsoleWindow()
if consoleWindow:
consoleWindow.SetActive()
qqWindow = listItem.GetTopWindow()
list = listItem.GetParentControl()
allListItems = list.GetChildren()
for listItem in allListItems:
automation.Logger.WriteLine(listItem.Name)
answer = input('是否获取详细信息?按y和Enter继续\n')
if answer.lower() == 'y':
automation.Logger.WriteLine('\n3秒后开始获取QQ群成员详细资料,您可以一直按住F10键暂停脚本')
time.sleep(3)
qqWindow.SetActive()
#确保群里第一个成员可见在最上面
left, top, right, bottom = list.BoundingRectangle
while allListItems[0].BoundingRectangle[1] < top:
automation.Win32API.MouseClick(right - 5, top + 20)
for listItem in allListItems:
if listItem.ControlType == automation.ControlType.ListItemControl:
if automation.Win32API.IsKeyPressed(automation.Keys.VK_F10):
if consoleWindow:
consoleWindow.SetActive()
input('\n您暂停了脚本,按Enter继续\n')
qqWindow.SetActive()
listItem.RightClick()
menu = automation.MenuControl(searchDepth= 1, ClassName = 'TXGuiFoundation')
menuItems = menu.GetChildren()
for menuItem in menuItems:
if menuItem.Name == '查看资料':
menuItem.Click()
break
automation.Logger.WriteLine(listItem.Name, automation.ConsoleColor.Green)
automation.Logger.WriteLine(GetPersonDetail())
listItem.Click()
automation.SendKeys('{Down}')
if __name__ == '__main__':
main()
input('press Enter to exit')
我用的环境是Pycharm2017.2社区版和Python3.6,这个模块的内容主要集中在uiautomation.py文件中,学习方法就是去这个文件里看相关的代码。先简单看一下这个代码,看看里面有哪些看不懂的,看不懂的地方就是要学习的地方。
首先是automation.WindowControl,这看起来是个对象,但是还不知道这个对象有哪些方法和属性,下面的WalkControl和EditControl应该也是对象,从命名上看可能直接代表了窗体中的不同控件。control.CurrentValue应该是属性,下面的detailWindow.Click()应该是模拟鼠标点击的方法。再看main()函数,Logger.WriteLine()方法应该是跟日志有关,ControlFromCursor()可能是从鼠标获取控件的方法......
这样看一遍大概就知道应该去源码里面找哪些定义了,我们利用PyCharm的跳转定义功能可以很容易地找到定义这些类和方法的代码,都在uiautomation.py这个文件中。源码就不贴了,通过跳转功能可以很容易地理解其中的方法与类之间的逻辑关系。这个文件中主要定义了“控件”这个类,就是两千多行处的Class Control(.............):这一大段代码,里面包含了所有对控件的方法和基本的属性。方法有获取控件名称啊,内容啊等,属性有位置啊,是否Active啊这些。然后由Control类派生出各个子类,代表具体的各种控件,比如WindowControl类表示窗口,EditControl类表示输入框,ButtonControl类代表按钮等等,几乎涵盖所有Win窗体程序的所有控件。并且作者在很多类下面做了详细的注释,阅读起来应该没有什么困难。理解的难点应该是这里面有大量关于WinForm开发的知识,需要一点基础。
那么当我们将这些方法与类的定义搞清楚之后,我们就能读懂这个实例的功能了。通过组合运用各个空间的属性和方法,实现从QQ群窗口中获得QQ群的信息。包括群号、群成员信息、聊天记录等信息,并保存到文本文件。
0x04 后记
- 果然多看,多写才是提升实力的根本途径,教材看一百遍不如自己摸索一遍!
- Life is short,use Python!
作者:8f7aac77586a
链接:https://www.jianshu.com/p/be3c46c7a905
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
Python下编写Windows自动化测试软件的更多相关文章
- 分别在.NET Framework 与 .NET Core 框架下 编写Windows Service(windows服务程序)
前言,为什么会分别在两个框架下编写Windows Service,是因为最近在做区块链这块,使用的是NEO(小蚁区块链)的相关技术,NEO使用的是.net core 2.1,业务上需要写两个程序,一个 ...
- python实现编写windows服务
使用python编写windows服务 最近测试服务器上经常发生磁盘空间不足,每次手动清除比较麻烦,所以写个windows服务定时清理下.中间也遇到过几个坑,一起记录下来. 1.python实现win ...
- python下如何处理windows的路径名
f = open(r'e:\迅雷下载\TEK-071\test.txt','r') 在windows下\会被认为是转义字符,所以需要在字符串前加上r,来告诉计算机后面的字符串是没有转义的.
- [Python爬虫] 在Windows下安装PIP+Phantomjs+Selenium
最近准备深入学习Python相关的爬虫知识了,如果说在使用Python爬取相对正规的网页使用"urllib2 + BeautifulSoup + 正则表达式"就能搞定的话:那么动态 ...
- 利用Python编写Windows恶意代码!自娱自乐!勿用于非法用途!
本文主要展示的是通过使用python和PyInstaller来构建恶意软件的一些poc. 利用Python编写Windows恶意代码!自娱自乐!勿用于非法用途!众所周知的,恶意软件如果影响到了他人的生 ...
- 转 windows下安装pycharm并连接Linux的python环境 以及 windows 下notepad ++编辑 linux 的文件
######sample 1:windows下安装pycharm并连接Linux的python环境 https://www.cnblogs.com/junxun/p/8287998.html wind ...
- windows下修复Linux引导 and linux下几个常用软件
在这里,我选择的是deepinLinux,不用说,高端大气上档次! Linux下引导修复 在win7上安装好了Linux,一不小心Linux系统启动不了 (一不小心的过程,想使用root登录图像界面, ...
- Windows下cmd的替代软件——PowerCmd
Powercmd 是一款运行在windows下的cmd增强软件(A Better Command Prompt Replacement Tool),当前最新的版本为2.2. 官方提供试用版,貌似没有功 ...
- 在ubuntu下编写python(python入门)
在ubuntu下编写python 一般情况下,ubuntu已经安装了python,打开终端,直接输入python,即可进行python编写. 默认为python2 如果想写python3,在终端输入p ...
随机推荐
- nginx返回file not found原因
nginx返回file not found原因1 确实没有这个文件2 没有权限访问这个网站目录!!!
- .net core 在 View 中使用 Jquery 无效问题
问题描述: 在 View 视图中使用模板 _Layout.cshtml,其中模板已经调用了 Jquery.js ,但是在 View 视图下写 js 无效.后来通过浏览器查看自己写的 js 压根没加载出 ...
- 中级java面试经历
2018年已经远去,2019年悄然而至.跳槽不仅是为了涨薪,更是为了锻炼自己,提高自己的能力.树挪死,人挪活.在一个公司呆的时间越长,就越老油条,从而失去不断前进的动力.现在下面就主要讲述我这一个月面 ...
- pychram 激活码
转自博客:https://blog.csdn.net/may_ths/article/details/84032217 激活码到期时间: 2020.06 K6IXATEF43-eyJsaWNlbnNl ...
- netcore3.0 webapi集成Swagger 5.0,Swagger使用
Swagger使用 1.描述 Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务. 作用: 1.接口的文档在线自动生成. 2.功能测试 本文转自 ...
- AnyProxy代理
背景:当一个公司测试团队有多个人的时候,只需搭建一个AnyProxy服务,其它小伙伴浏览器上打开AnyProxy页面,手机上设置代理就能抓到http.https请求了.解决了部分人电脑不正经的小伙伴f ...
- ping程序和tracert(traceroute)背后的故事--ICMP协议
为路由器生,为交换机死,为了Ping通奋斗一辈子-----tracert.cn 上面是一个网络工程师的个人定位,很有意思,哈哈!那么我们来看看ping和tracert都是什么吧 PING (Packe ...
- spring boot EnableAutoConfiguration exclude 无效
本文链接:https://blog.csdn.net/ID19870510/article/details/79373386 首先讲一下SpringBootApplication注解源码定义为 @Ta ...
- php 逻辑题
越长大约发现,高中学的数学,都还给了数学老师,一点都没有留住. 最近遇到了一个 逻辑题,然后想了半天,后来做出来了,我就发现了,我可能是一个假的理科生.很简单的样子. 废话不说,看看这道题吧. /** ...
- springMVC 任意文件读取相关路径
在做检查的时候,发现一个路径是可以去读取文件的,但是平时的/etc/目录下都无法读取到,只能先读取web目录下的文件尝试. 因为知道是springMVC框架,所以可以先尝试该路径 ../../WEB- ...