用python做自动化测试仪器_使用python进行windows自动化测试(1)
最近开始学习整理python在windows自动化测试中的使用,觉得挺有意思的
主要思路,在windows下,主要通过启进程,然后查找进程的句柄,然后再操作这个句柄,包括点击,填写文字,关闭,获取文字等操作
下面以一个简单的校验文件md5值的操作来介绍一个python的应用,当然python中有校验md5的函数,不用非要使用工具来校验,这里只是练习使用python来自动化操作
所用的工具有SpyLite,用于查看窗口ID,句柄等信息
工具下载
我们要达到的目的是通过md5校验工具将文件的md5值保存到一个log文档中
测试的目录结构
--automd5--
--needCheck--
checkmd5.py
SpyLite24.exe
Hash.exe
needCheck目录放需要检查md5的文件
#! /usr/bin/env python
#coding=gbk
import time,re,ctypes
import os,sys,subprocess,win32gui,win32con,win32api
import glob,time
#启进程函数
def createProcess(cmd, wait = False):
if wait:
proc = tryExcept(subprocess.Popen, cmd, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
else:
proc = tryExcept(subprocess.Popen, cmd)
if isExcept(proc):
return
if not wait:
return proc.pid
proc.communicate()
def tryExcept(func, *params, **paramMap):
try:
return func(*params, **paramMap)
except Exception, e:
return e
def isExcept(e, eType = Exception):
return isinstance(e, eType)
class BaseWindow:
@staticmethod
def parseClickConfig(clkCfg):
if clkCfg == None:
return None, None, False, 0
if type(clkCfg) == bool:
return None, None, clkCfg, 0
if type(clkCfg) == int:
return None, None, False, clkCfg
if len(clkCfg) == 2:
if type(clkCfg[0]) == int and type(clkCfg[1]) == int:
return clkCfg[0], clkCfg[1], False, 0
return None, None, clkCfg[0], clkCfg[1]
if len(clkCfg) == 3:
if type(clkCfg[2]) == bool:
return clkCfg[0], clkCfg[1], clkCfg[2], 0
return clkCfg[0], clkCfg[1], False, clkCfg[2]
return clkCfg
#点击窗口
#clkCfg:byDrv|mode|(x,y)|(byDrv,mode)|(x,y,byDrv)|(x,y,mode)|(x,y,byDrv,mode)
def clickWindow(hwnd, clkCfg = None):
if isRawWindow(hwnd):
return
topWindow(hwnd)
rect = getWindowRect(hwnd)
if not rect:
return
x, y, byDrv, mode = BaseWindow.parseClickConfig(clkCfg)
if x == None:
x = (rect[0] + rect[2]) / 2
elif x < 0:
x += rect[2]
else:
x += rect[0]
if y == None:
y = (rect[1] + rect[3]) / 2
elif y < 0:
y += rect[3]
else:
y += rect[1]
clickMouse(x, y, byDrv, mode)
#点击鼠标
CLICK_MOUSE = 0
CLICK_MOUSE_DOUBLE = 1
CLICK_MOUSE_RIGHT = 2
def clickMouse(x, y, byDrv = False, mode = CLICK_MOUSE):
moveMouse(x, y, byDrv)
downMsg, upMsg = win32con.MOUSEEVENTF_LEFTDOWN, win32con.MOUSEEVENTF_LEFTUP
if mode == CLICK_MOUSE_RIGHT:
downMsg, upMsg = win32con.MOUSEEVENTF_RIGHTDOWN, win32con.MOUSEEVENTF_RIGHTUP
win32api.mouse_event(downMsg, 0, 0, 0, 0)
win32api.mouse_event(upMsg, 0, 0, 0, 0)
if mode == CLICK_MOUSE_DOUBLE:
win32api.mouse_event(downMsg, 0, 0, 0, 0)
win32api.mouse_event(upMsg, 0, 0, 0, 0)
#移动鼠标
def moveMouse(x, y, byDrv = False):
w, h = win32api.GetSystemMetrics(0), win32api.GetSystemMetrics(1)
x, y = int(float(x) / w * 65535), int(float(y) / h * 65535)
win32api.mouse_event(win32con.MOUSEEVENTF_MOVE | win32con.MOUSEEVENTF_ABSOLUTE, x, y, 0, 0)
#获得窗口尺寸
def getWindowRect(hwnd):
rect = tryExcept(win32gui.GetWindowRect, hwnd)
if not isExcept(rect):
return rect
#置顶窗口
def topWindow(hwnd):
fgHwnd = win32gui.GetForegroundWindow()
if fgHwnd == hwnd:
return True
rst = tryExcept(win32gui.SetForegroundWindow, hwnd)
if not isExcept(rst):
return True
return getWindowClass(fgHwnd) == 'Progman' and getWindowText(fgHwnd) == 'Program Manager'
##获取窗口文字
def getWindowText(hwnd, buf = ctypes.c_buffer(1024)):
size = ctypes.sizeof(buf)
ctypes.memset(buf, 0, size)
tryExcept(win32gui.SendMessageTimeout, hwnd, win32con.WM_GETTEXT, size, buf, win32con.SMTO_ABORTIFHUNG, 10)
return buf.value.strip()
#获取窗口类名
def getWindowClass(hwnd, buf = ctypes.c_buffer(1024)):
size = ctypes.sizeof(buf)
ctypes.memset(buf, 0, size)
ctypes.windll.user32.GetClassNameA(hwnd, ctypes.addressof(buf), size)
return buf.value.strip()
#查找第一个窗口
#title:text,class,ctrlid
#parentTitle:None,hwnd,text,class
def findWindow(title, parentTitle = None, isRaw = False):
hwndList = findWindows(title, parentTitle, isRaw)
if hwndList:
return hwndList[0]
def findRawWindows(title, parentTitle = None):
return findWindows(title, parentTitle, True)
#判断是否为非正常窗口
def isRawWindow(hwnd):
return not win32gui.IsWindowVisible(hwnd) or not win32gui.IsWindowEnabled(hwnd) or ctypes.windll.user32.IsHungAppWindow(hwnd)
#查找窗口
#title:text,class,ctrlid
#parentTitle:None,hwnd,text,class
def findWindows(title, parentTitle = None, isRaw = False):
def __enumWindowHandler__(hwnd, wndList):
text = re.split('[\r|\n]+', getWindowText(hwnd))[0].strip()
clazz = getWindowClass(hwnd).strip()
ctrlId = win32gui.GetDlgCtrlID(hwnd)
wndList.append((hwnd, text, clazz, ctrlId))
if not parentTitle:
parentHwndList = [None]
elif type(parentTitle) == int:
parentHwndList = [parentTitle]
else:
parentHwndList = findRawWindows(parentTitle)
hwndSet = set()
for parentHwnd in parentHwndList:
wndList = []
#EnumWindows
if parentHwnd:
tryExcept(win32gui.EnumChildWindows, parentHwnd, __enumWindowHandler__, wndList)
else:
win32gui.EnumWindows(__enumWindowHandler__, wndList)
#FindWindowEx
hwnd, foundHwndList = None, []
while True:
hwnd = tryExcept(win32gui.FindWindowEx, parentHwnd, hwnd, None, None)
if not hwnd or isExcept(hwnd) or hwnd in foundHwndList:
break
__enumWindowHandler__(hwnd, wndList)
foundHwndList.append(hwnd)
#GetWindow
if parentHwnd:
hwnd = tryExcept(win32gui.GetWindow, parentHwnd, win32con.GW_CHILD)
else:
hwnd = tryExcept(win32gui.GetWindow, win32gui.GetDesktopWindow(), win32con.GW_CHILD)
while hwnd and not isExcept(hwnd):
__enumWindowHandler__(hwnd, wndList)
hwnd = tryExcept(win32gui.GetWindow, hwnd, win32con.GW_HWNDNEXT)
#Combine
for hwnd, text, clazz, ctrlId in set(wndList):
if type(title) == int:
if ctrlId == title:
hwndSet.add(hwnd)
elif text == title or re.match('^' + title + '$', text, re.S) or clazz == title or re.match('^' + title + '$', clazz, re.S):
hwndSet.add(hwnd)
if parentHwnd:
hwndSet.update(findRawWindows(title, hwnd))
if isRaw:
return list(hwndSet)
hwndList = []
for hwnd in hwndSet:
if not isRawWindow(hwnd):
hwndList.append(hwnd)
return hwndList
#设置窗口文字
def setWindowText(hwnd, text):
rst = tryExcept(win32gui.SendMessageTimeout, hwnd, win32con.WM_SETTEXT, 0, text, win32con.SMTO_ABORTIFHUNG, 10)
return not isExcept(rst)
#杀掉指定name的进程
def killProcessByName(pname, user = None):
killProcessByNames([pname], user)
def listFile(path, isDeep=True):
_list = []
if isDeep:
try:
for root, dirs, files in os.walk(path):
for fl in files:
_list.append('%s\%s' % (root, fl))
except:
pass
else:
for fn in glob.glob( path + os.sep + '*' ):
if not os.path.isdir(fn):
_list.append('%s' % path + os.sep + fn[fn.rfind('\\')+1:])
return _list
#杀掉指定name的进程列表
def killProcessByNames(pnameList, user = None):
cmd = 'taskkill /F /T'
if user:
cmd += ' /FI "USERNAME eq %s"' % user
for pname in pnameList:
cmd += ' /IM %s' % pname
createProcess(cmd, True)
#超时设置
def handleTimeout(func, timeout, *params, **paramMap):
interval = 0.8
if type(timeout) == tuple:
timeout, interval = timeout
while timeout > 0:
t = time.time()
rst = func(*params, **paramMap)
if rst and not isExcept(rst):
break
time.sleep(interval)
timeout -= time.time() - t
return rst
#写文件
def setFileData(filename, data, mode):
f = open(filename, mode)
f.write(data)
f.close()
if __name__ == '__main__':
if os.path.isfile('md5.log'):
os.system('del md5.log')
parentHwnd = r'Hash.*?'
#setWindowText(textblack,'123')
filedir = os.path.join(os.getcwd(),'needCheck')
filelist = listFile(filedir)
#os.chdir(filedir)
for file in filelist:
#启进程
createProcess('Hash.exe')
#查找浏览按钮
browse_button = findWindow(r'浏览.*?',parentHwnd)
#点击浏览按钮
clickWindow(browse_button)
textblack = findWindow(0x47C,'#32770')
handleTimeout(setWindowText,10,textblack,file)
open_hwnd = findWindow('打开.*?','#32770')
#点击打开按钮
clickWindow(open_hwnd)
#获取文件md5信息
#需要内容的行号
expect_content_id = [0,4]
content_hwnd = findWindow(0x3EA,r'Hash.*?')
content_text = handleTimeout(getWindowText,20,content_hwnd)
content = content_text.split('\r\n')
md5content = [i.split(': ')[1].strip() for ind, i in enumerate(content) if ind in expect_content_id]
print md5content
filename,md5value = md5content
setFileData('md5.log','文件名:'+filename+'\n'+'md5:'+ md5value+'\n\n','a')
killProcessByName('Hash.exe')
os.system('pause')
用python做自动化测试仪器_使用python进行windows自动化测试(1)相关推荐
- python做自动化界面_使用Python进行自动化测试如何切换窗口
我把我的程序写上来,请各位大佬给看看,为什么我明明打开了2个窗口,但是handle依然是一个值.导致切换窗口失败,后续的步骤都无法进行.#coding=gbkfromseleniumimportweb ...
- python浏览器自动化测试仪器_【松勤软件自动化测试】纯干货:基于Python+Selenium2登录163邮箱实例...
一.业务流程: 1.打开浏览器,自动填写用户名和密码,登录成功后跳转到相应的页面. 2.验证相应页面的url与给定的url是否一致,如果一致则测试通过,如果不一致,则不通过. 3.另外,在执行过程中如 ...
- 用python做自我介绍_用python做个自我介绍(python入门教程)_逻辑教育
原标题:用python做个自我介绍(python入门教程)_逻辑教育 本文涉及的python基础语法为:数据类型等 数字类型 1. 字符串的拼接 我们在上一章中已经简单介绍了一下字符串的创建方式,这里 ...
- python做硬件自动化测试仪器_基于Python PyVisa和GPIB的硬件测试仪器控制方法
基于Python和GPIB的硬件测试仪器控制方法 背景 在物联网通信时代,嵌入式模块开发越发广泛,自动化测试成为大家老生常谈的话题.对于一些高精度仪器,我们知道它是用GPIB控制用来测试,也希望可以通 ...
- pythonandroid自动化测试仪器_使用Python进行Android自动化测试
下面我们开始第一个简单的Android UI自动化测试 1.使用adb命令连接真机或模拟器 2.打开uiautomatorviewer工具 3.使用uiautomatorviewer工具获取应用的元素 ...
- 学会python做什么兼职_学会python能干嘛 学会python可以做哪些兼职?
学会python可以干什么都希望一段感情会有结果,谁都不希望美好的爱情最后是一场痛,但是如果一开始就想着不在乎天长地久,只在乎曾经拥有"的态度,再美好的感情也不会有好的结果. 从入门级选手到 ...
- python做logistic回归_用Python做Logistic回归
为什么写这篇文章 本人初学python,碰巧做的东西需要用一下Logistic回归,自觉这个很基础的东西应该已经有很多比较好的实现了,于是我就很自觉地问了下度娘.结果大囧==..出来的相关结果少得可怜 ...
- python做股票分析_利用Python进行股票投资组合分析(调试)
pythonsp500-robo-advisor-edition Python for Financial Analyses 需要的镜像文件和数据--Robo Advisor edition. 小结 ...
- python做淘宝_用python做个淘宝双十一满减攻略,再也不用算算算了
双十一还有不到10天,购物车已经快加满了,但是钱包里就这么多钱,如何用现有的钱买到更多喜欢的东西,成为我比较头疼的事,因为我已经被各种组合加法搞晕了 于是我决定用python做个双十一购物攻略,把复杂 ...
最新文章
- 我摊牌了,这就是我的生活
- 2018.8.18 servlet使用的会话跟踪除session外还有哪些方式
- Linux Kernel TCP/IP Stack — 网卡监控
- 浅谈图片蒙版效果-webkit-mask
- pic单片机c语言存储器定义,PIC单片机C语言程序设计1 7.PDF
- 汤姆大叔的6道javascript编程题题解
- tensorflow的优化器Optimizer
- ASP.NET 操作Cookie详解 增加,修改,删除
- jvm程序执行慢诊断手册
- Web之路笔记之三 - 使用Floating实现双栏样式
- 在nhibernate 1.2 中使用sqlite时应注意sqlite的ado.net的提供者 .
- Xcode添加include目录
- 梳理.net知识,准备考试
- Oracle 19c对VARCHAR2的限制
- 火狐浏览器设置关闭提醒
- php怎么实现收藏夹功能,前端--收藏功能的实现
- 个人网站学习实践(wordpress教程)
- 迭代器生成器思维导图
- Matlab求矩阵的最小多项式
- iSCSI存储技术全攻略【存储部落】云存储|云计算|云服务
热门文章
- iphone保修期多久_小心!iPhone翻新机,黑机,妖机,1978机千万别买!
- 【OpenStack】【Keystone】安装与配置详解
- Intel 64/x86_64/IA-32/x86处理器 - SIMD指令集 - MMX技术(3) - 组合的算术指令
- 【英语学习】【WOTD】farouche 释义/词源/示例
- 80386/386/Intel386 架构/流水线及其优化
- 由浅入深了解Thrift(二)——Thrift工作原理
- python空集合_python空集合
- PowerVR 6XT/6XE系列移动GPU
- Deferred Shading,延迟渲染(提高渲染效率,减少多余光照计算)
- 如何使用Xcode分析调试在真机运行的UE4 IOS版游戏