自动化测试工具自动化工具Pyautogui和Pywinauto详细介绍和使用

发布时间 2023-04-29 10:22:36作者: shuzihua
  1. 自动化测试工具介绍和使用
  2. PC端应用程序自动化测试——pywinauto、pywin32、pyautogui
  3. 详解Python中pyautogui库的最全使用方法
  4. 自动化测试工具自动化工具Pyautogui和Pywinauto详细介绍和使用
 
 
 
1、自动化测试工具介绍和使用
  • 一. Pywinauto库的介绍
  • 二、 pyautogui库的介绍和使用
    • 2.1 博客推荐
    • 2.2 如何实现测试自动化呢?
    • 2.3 常见的使用方法介绍
      • 2.3.1 故障保险方法
      • 2.3.2 获取屏幕的分辨率和鼠标的实时位置
      • 2.3.3 模拟鼠标单击(左、右、中)、双击、滚动、移动、拖动方法
        • 2.3.3.1 点击方法
        • 2.3.3.2左击,右击方法
        • 2.3.3.3 滚动方法
        • 2.3.3.4 鼠标移动方法
        • 2.3.3.5 鼠标拖动方法
      • 2.3.4 模拟键盘操作
        • 2.3.4.1 键盘按下或按键组合
        • 2.3.4.2 键盘写入
        • 2.3.4.3 键盘和鼠标按下和松开,和鼠标拖动异曲同工
  • 三、pyautogui简单实例
    • 3.1 打开百度网页并输入内容,点击回车
在PC端应用程序自动化测试工具有三种,即对于C/S架构来说:Pyautogui、Pywinauto和Pywin32,其中对于浏览器B/S架构来说还可以使用selenium来进行web端的自动化(这个以后在写),因为Pywin32我用的比较少,下面着重介绍其他软件。
 
一. Pywinauto库的介绍
pywinauto 模块主要用于应用控制(打开、关闭应用等)窗口控制(最大化、最小化窗口等),也可以等位到控件,并对控件进行操作,如点击、编辑等。具体使用方法如下:
#对于首次使用这个包的用户,需要安装包,安装命令如下: #在cmd里面输入:pip isntall pywinauto from pywinauto.application import Application #导入Application类 app = Application(backend="uia") #实例化 #backend 属性有2个取值:win32 和 uia,win32 为默认值,根据应用程序的属性来进行查看,常用的小工具有inspect.exe、SpyLite.exe,具体下载链接在下面 path = r"" #这里填入想要打开程序的绝对路径 app.start(path) #启动程序 app.connect(path) #连接程序或者app.connect(process=3308),这里填入的是一个应用程序的进程号,在任务管理器中可以看到 app.kill() #这里是强制杀死程序
百度网盘链接
提取码:xi2l
推荐内容
 
 
 
 
 
二、 pyautogui库的介绍和使用
2.1 博客推荐
由于网上对这个工具介绍很多,我这里推荐三个我认为写的很好的博客分享给大家:
pyautogui详解
pyautogui和自动化测试框架的结合使用
pyautogui使用教程
2.2 如何实现测试自动化呢?
①、这个工具可以通过坐标来进行点击,即需要不同的坐标,如果页面元素位置发生改变,则坐标不管用了。
②、通过图片在进行定位,事先在页面截图,在通过在页面上进行查找,如果没有找到则返回None,找到了就返回一个类型(左上角坐标x,左上角坐标y,长,宽),如果返回的是center中心坐标(x,y),则是一个类型Point(x=680, y=135),则可以通过该结果来进行判断、断言
③、这个工具还可以使用热键来进行操作,就可以实现键盘的操作,实现自动化,但是由于pyautogui本身对图片识别率较低,便引入了opencv来提升识别率,通过灰度值得调整可以快速准确的识别定位图片
④、但是pyautogui的图片是跟分辨率有关系,所以复用性不高,即在其他电脑上想要使用,要么将所有的电脑的分辨率调成一样;或者将窗口设置成一样大小(即分辨率一样)
⑤、 由于pyautogui是通过图片来进行定位,则需要专门的图片存储来进行管理,则这会加大成本,因此这也是它的局限性。
⑥、由于通过图片定位,这无疑需要花费较多的时间来进行查找,对于一些比较看重时间的项目就不太适合。所以仁者见仁智者见智了。
2.3 常见的使用方法介绍
2.3.1 故障保险方法
import pyautogui pyautogui.PAUSE = 1 #即pyautogui每次调用完程序后等待时间,也可以和time.sleep()结合起来使用 pyautogui.FAILSAFE = True #在程序执行错误时,可以将鼠标移到左上角(0,0),让程序停止下来,避免后续的无用功
2.3.2 获取屏幕的分辨率和鼠标的实时位置
import pyautogui import time size = pyautogui.size() #获取屏幕分辨率 time.sleep(1) position = pyautogui.position() #获取鼠标当前位置 print(f"屏幕的尺寸:{size},当前鼠标的位置:{position}")
2.3.3 模拟鼠标单击(左、右、中)、双击、滚动、移动、拖动方法
2.3.3.1 点击方法
参考源码,发现点击有以下几种方法:①通过x,y坐标②通过坐标序列③,通过图片点击,④,通过图片返回坐标进行点击,⑤,通过像素定位点击,欢迎大家补充!!!
import pyautogui #第一种方法通过x,y坐标点击 import time pyautogui.hotkey("win","d") #热键win+D 最小化pycharm time.sleep(1) pyautogui.click() #可以不填参数,即在当前位置进行点击 pyautogui.click(x=100,y=100,clicks=2,duration=0.1,interval=0.2,tween="linear",button="PRIMARY",logScreenshot="gg") #x,y如果是整数,则就是坐标
参数解释
clicks:点击次数,默认是1次,2就是双击duration:点击持续时间,默认为0.0interval:点击间隔时间,默认为0.0tween:鼠标的移动模式,默认是简单的线性吐温,可以不管,如需了解详细信息,请参阅PyTweening模块文档button:鼠标按键,默认左键,可选(left,middle,right,primary,secondary)logScreenshot:表示点击时开始截图,这里填入截图名字,默认None,不截图_pause:不推荐使用“暂停”参数。调用“pyautogui"或者sleep()函数来实现暂停。
#第二种方法 import pyautogui import time pyautogui.hotkey("win","d") time.sleep(1) pyautogui.click(x=(100,100)) #让x=(),序列化x也能进行点击操作,这种只针对x;y不能使用这种方法,会报错。 #第三种方法 pyautogui.click(x="gg.PNG",duration=0.1,clicks=2) #预先截图,点击两次;只针对x pyautogui.click(1000,600) #在空白处点击一次,防止第二次运行失败
#第四种方法 import pyautogui import time import cv2 pyautogui.hotkey("win","d") time.sleep(1) result = pyautogui.locateOnScreen(image="gg.PNG", grayscale=False, confidence=0.9) #这个函数是将你预先截取的图片在页面进行查找,如果找到了就返回找到位置的(图片左上角坐标x,y,长,宽),没有找到则返回None print(type(result),result) #<class 'pyscreeze.Box'> Box(left=75, top=5, width=74, height=73) center= pyautogui.center(result) #这个函数是返回result的中心坐标 print(type(center),center) #<class 'pyscreeze.Point'> Point(x=112, y=41) pyautogui.click(center) #单击 #####第二种获取中心坐标方法 center= pyautogui.locateCenterOnScreen(image ="gg.PNG",grayscale= False,confidence=0.9) #这种方法是和上面两个函数的结合使用 print(type(center),center) #<class 'pyscreeze.Point'> Point(x=112, y=41) pyautogui.click(center) #单击
参数解释:
image:这里填入图片的路径,绝对路径和相对路径都可以grayscale:grayscale=True代表去饱和度,可以消除显示器饱和度导致的颜色偏差而导致图片定位失败的问题,可以提升速度confidence:表示灰度值,值越高定位越准,但可能失败,建议0.8或者0.9
#####第5种方法,通过像素定位来点击 x,y = center #这是上面获取的中心坐标 print(type(x),type(y)) #<class 'numpy.int64'> <class 'numpy.int64'> posi_pixel = pyautogui.pixel(int(x),int(y)) print(pyautogui.pixel(int(x),int(y))) #这里装换格式 if pyautogui.pixel(int(x),int(y))[0] == 0: #<class 'tuple'>取下标 print("找到了") pyautogui.click(center) #### 也可以手动输入坐标来查找 posi_pixel = pyautogui.pixel(100,100) #返回一个像素组成的元祖,如(255,255,255)
2.3.3.2左击,右击方法
方法和click()方法大同小异,只是少了一个button参数。
import pyautogui import time import cv2 pyautogui.hotkey("win","d") time.sleep(1) pyautogui.leftClick(x=100,y=100,clicks =2) #鼠标左击两次 pyautogui.rightClick(x=100,y=100,clicks =2) #鼠标右击两次 pyautogui.middleClick(x=100,y=100,clicks =2) #鼠标滚轮击两次 pyautogui.tripleClick() #这个方法是3次连续点击
2.3.3.3 滚动方法
import pyautogui time.sleep(1) pyautogui.scroll(clicks=200,x=100,y=100) #在坐标(100,100)处向上滚动200像素 pyautogui.scroll(clicks=-200,x=100,y=100) #在坐标(100,100)处向下滚动200像素 # 如有指定的需求。(目前仅有Linux支持)水平滚动 pyautogui.hscroll(clicks=100) # 垂直滚动 pyautogui.vscroll(clicks=-200)
2.3.3.4 鼠标移动方法
具体参数前面都有讲解
import pyautogui import time pyautogui.moveTo(200,200) #绝对移动,从当前位置移动到指定位置 time.sleep(1) pyautogui.move(1000,100) #相对移动,在原来的基础上再次移动即(x+1000,y+100) pyautogui.moveRel(1000,100) #同上
2.3.3.5 鼠标拖动方法
import pyautogui import time pyautogui.dragTo(100,100) #鼠标绝对拖动 pyautogui.drag(200,100) #鼠标相对推动(x+200,y+100) pyautogui.dragRel(100,100) #同上
2.3.4 模拟键盘操作
2.3.4.1 键盘按下或按键组合
import pyautogui import time pyautogui.press(keys="enter",presses=2) #按enter键两次 pyautogui.hotkey("enter","enter") #热键,连续两次按enter pyautogui.hotkey("ctrl","c") pyautogui.hotkey("ctrl","v")
2.3.4.2 键盘写入
import pyautogui import time pyautogui.hotkey("win","d") time.sleep(1) pyautogui.click(x="gg.PNG",clicks=2,duration=0.1) pyautogui.write(["1","2"],interval=1) #可以依次写入,也可以一次性写入 pyautogui.write("12",interval=0.1) #同上 pyautogui.typewrite("12",interval=0.1) #同上 pyautogui.typewrite(["1","2"],interval=1) #同上
2.3.4.3 键盘和鼠标按下和松开,和鼠标拖动异曲同工
import pyautogui import time pyautogui.mouseDown() #按下 pyautogui.mouseUp() #松开 pyautogui.keyDown() #按键按下 pyautogui.keyUp() #按键松开 time.sleep(3)
三、pyautogui简单实例
3.1 打开百度网页并输入内容,点击回车
具体步骤:截浏览器的图标、截浏览器输入框图标,获得坐标,点击,输入地址,点击回车,代码如下:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # @time :2022/8/23 9:38 # @Author :南风知我意 # @FileName :exam import pyautogui import time def get_position(path,value): center = pyautogui.locateCenterOnScreen(image=path, grayscale=True, confidence=value) return center def open_baidu(): url = "http://www.baidu.com" pyautogui.hotkey("win","d") time.sleep(1) center = get_position(path="gg.PNG",value=0.9) pyautogui.click(center,clicks=2,duration=0.1) time.sleep(1) center = get_position(path="max.PNG",value=0.9) pyautogui.click(center) time.sleep(1) center = get_position(path="url_input.PNG",value=0.9) pyautogui.click(center,clicks=1) time.sleep(1) pyautogui.write(url,interval=0.1) pyautogui.press("enter",presses=2) time.sleep(1) center = get_position(path="input_content.PNG",value=0.9) pyautogui.click(center) time.sleep(1) pyautogui.write("hhhh",interval=0.1) #这是在百度搜索框输入内容 time.sleep(1) pyautogui.press("enter",presses=2) #按了两次回车 if __name__ == '__main__': open_baidu()
# 自动化# 测试工具# python
 
 
详解Python中pyautogui库的最全使用方法
在使用Python做脚本的话,有两个库可以使用,一个为PyUserInput库,另一个为pyautogui库。就本人而言,我更喜欢使用pyautogui库,该库功能多,使用便利。下面给大家介绍一下pyautogui库的使用方法。在cmd命令框中输入pip3 install pyautogui即可安装该库!
PyAutoGUI帮助文档:
https://blog.csdn.net/qq_34053552/article/details/79776671
pyautogui图形自动化:
https://blog.csdn.net/qq_43017750/article/details/90575240
常用操作
我们在pyautogui库中常常使用的方法,如下:
import pyautogui pyautogui.PAUSE = 1 # 调用在执行动作后暂停的秒数,只能在执行一些pyautogui动作后才能使用,建议用time.sleep pyautogui.FAILSAFE = True # 启用自动防故障功能,左上角的坐标为(0,0),将鼠标移到屏幕的左上角,来抛出failSafeException异常 1234
# 判断(x,y)是否在屏幕上 x, y = 122, 244 pyautogui.onScreen(x, y) # 结果为true width, height = pyautogui.size() # 屏幕的宽度和高度 print(width, height) 鼠标操作 12345678
我们在pyautogui库对于鼠标的使用方法大体如下:
import pyautogui currentMouseX, currentMouseY = pyautogui.position() # 鼠标当前位置 print(currentMouseX, currentMouseY) # 控制鼠标移动,duration为持续时间 for i in range(2): pyautogui.moveTo(100, 100, duration=0.25) # 移动到 (100,100) pyautogui.moveTo(200, 100, duration=0.25) pyautogui.moveTo(200, 200, duration=0.25) pyautogui.moveTo(100, 200, duration=0.25) for i in range(2): pyautogui.moveRel(50, 0, duration=0.25) # 从当前位置右移100像素 pyautogui.moveRel(0, 50, duration=0.25) # 向下 pyautogui.moveRel(-50, 0, duration=0.25) # 向左 pyautogui.moveRel(0, -50, duration=0.25) # 向上 123456789101112131415161718
# 按住鼠标左键,把鼠标拖拽到(100, 200)位置 pyautogui.dragTo(100, 200, button='left') # 按住鼠标左键,用2秒钟把鼠标拖拽到(300, 400)位置 pyautogui.dragTo(300, 400, 2, button='left') # 按住鼠标左键,用0.2秒钟把鼠标向上拖拽 pyautogui.dragRel(0, -60, duration=0.2) # pyautogui.click(x=moveToX, y=moveToY, clicks=num_of_clicks, interval=secs_between_clicks, button='left') # 其中,button属性可以设置成left,middle和right。 pyautogui.click(10, 20, 2, 0.25, button='left') pyautogui.click(x=100, y=200, duration=2) # 先移动到(100, 200)再单击 pyautogui.click() # 鼠标当前位置点击一下 pyautogui.doubleClick() # 鼠标当前位置左击两下 pyautogui.doubleClick(x=100, y=150, button="left") # 鼠标在(100,150)位置左击两下 pyautogui.tripleClick() # 鼠标当前位置左击三下 pyautogui.mouseDown() # 鼠标左键按下再松开 pyautogui.mouseUp() pyautogui.mouseDown(button='right') # 按下鼠标右键 pyautogui.mouseUp(button='right', x=100, y=200) # 移动到(100, 200)位置,然后松开鼠标右键 # scroll函数控制鼠标滚轮的滚动,amount_to_scroll参数表示滚动的格数。正数则页面向上滚动,负数则向下滚动 # pyautogui.scroll(clicks=amount_to_scroll, x=moveToX, y=moveToY) pyautogui.scroll(5, 20, 2) pyautogui.scroll(10) # 向上滚动10格 pyautogui.scroll(-10) # 向下滚动10格 pyautogui.scroll(10, x=100, y=100) # 移动到(100, 100)位置再向上滚动10格 # 缓动/渐变函数可以改变光标移动过程的速度和方向。通常鼠标是匀速直线运动,这就是线性缓动/渐变函数。 # PyAutoGUI有30种缓动/渐变函数,可以通过pyautogui.ease*?查看。 # 开始很慢,不断加速 pyautogui.moveTo(100, 100, 2, pyautogui.easeInQuad) # 开始很快,不断减速 pyautogui.moveTo(100, 100, 2, pyautogui.easeOutQuad) # 开始和结束都快,中间比较慢 pyautogui.moveTo(100, 100, 2, pyautogui.easeInOutQuad) # 一步一徘徊前进 pyautogui.moveTo(100, 100, 2, pyautogui.easeInBounce) # 徘徊幅度更大,甚至超过起点和终点 pyautogui.moveTo(100, 100, 2, pyautogui.easeInElastic) 12345678910111213141516171819202122232425262728293031323334353637383940
对于我们要获取鼠标在屏幕中的位置,我们可以采用如下代码:
# 案例获取鼠标的位置,方便复制我们定位的鼠标坐标点到代码中 import pyautogui import time # 获取鼠标位置 def get_mouse_positon(): time.sleep(5) # 准备时间 print('开始获取鼠标位置') try: for i in range(10): # Get and print the mouse coordinates. x, y = pyautogui.position() positionStr = '鼠标坐标点(X,Y)为:{},{}'.format(str(x).rjust(4), str(y).rjust(4)) pix = pyautogui.screenshot().getpixel((x, y)) # 获取鼠标所在屏幕点的RGB颜色 positionStr += ' RGB:(' + str(pix[0]).rjust(3) + ',' + str(pix[1]).rjust(3) + ',' + str(pix[2]).rjust( 3) + ')' print(positionStr) time.sleep(0.5) # 停顿时间 except: print('获取鼠标位置失败') if __name__ == "__main__": get_mouse_positon() 12345678910111213141516171819202122232425
也可以使用pyautogui库帮助文档的方法,不过本人认为使用上面的方法,更加便利。pyautogui库帮助文档的获取鼠标位置的方法如下:
import pyautogui print('Press Ctrl-C to quit.') try: while True: # Get and print the mouse coordinates. x, y = pyautogui.position() positionStr = 'X:' + str(x).rjust(4) + ' Y:' + str(y).rjust(4) pix = pyautogui.screenshot().getpixel((x, y)) # 获取鼠标所在屏幕点的RGB颜色 positionStr += ' RGB:(' + str(pix[0]).rjust(3) + ',' + str(pix[1]).rjust(3) + ',' + str(pix[2]).rjust(3) + ')' print(positionStr, end='') # end='' 替换了默认的换行 print('\b' * len(positionStr), end='', flush=True) # 连续退格键并刷新,删除之前打印的坐标,就像直接更新坐标效果 except KeyboardInterrupt: # 处理 Ctrl-C 按键 print('\nDone.') 1234567891011121314
键盘操作
Python客栈送红包、纸质书
我们在pyautogui库对于键盘的使用方法大体如下:
import pyautogui pyautogui.typewrite('Hello world!') # 输入Hello world!字符串 pyautogui.typewrite('Hello world!', interval=0.25) # 每次输入间隔0.25秒,输入Hello world! pyautogui.press('enter') # 按下并松开(轻敲)回车键 pyautogui.press(['left', 'left', 'left', 'left']) # 按下并松开(轻敲)四下左方向键 pyautogui.keyDown('shift') # 按下`shift`键 pyautogui.keyUp('shift') # 松开`shift`键 pyautogui.keyDown('shift') pyautogui.press('4') pyautogui.keyUp('shift') # 输出 $ 符号的按键 pyautogui.hotkey('ctrl', 'v') # 组合按键(Ctrl+V),粘贴功能,按下并松开'ctrl'和'v'按键 # pyautogui.KEYBOARD_KEYS数组中就是press(),keyDown(),keyUp()和hotkey()函数可以输入的按键名称 pyautogui.KEYBOARD_KEYS = ['\t', '\n', '\r', ' ', '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 'accept', 'add', 'alt', 'altleft', 'altright', 'apps', 'backspace', 'browserback', 'browserfavorites', 'browserforward', 'browserhome', 'browserrefresh', 'browsersearch', 'browserstop', 'capslock', 'clear', 'convert', 'ctrl', 'ctrlleft', 'ctrlright', 'decimal', 'del', 'delete', 'divide', 'down', 'end', 'enter', 'esc', 'escape', 'execute', 'f1', 'f10', 'f11', 'f12', 'f13', 'f14', 'f15', 'f16', 'f17', 'f18', 'f19', 'f2', 'f20', 'f21', 'f22', 'f23', 'f24', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'final', 'fn', 'hanguel', 'hangul', 'hanja', 'help', 'home', 'insert', 'junja', 'kana', 'kanji', 'launchapp1', 'launchapp2', 'launchmail', 'launchmediaselect', 'left', 'modechange', 'multiply', 'nexttrack', 'nonconvert', 'num0', 'num1', 'num2', 'num3', 'num4', 'num5', 'num6', 'num7', 'num8', 'num9', 'numlock', 'pagedown', 'pageup', 'pause', 'pgdn', 'pgup', 'playpause', 'prevtrack', 'print', 'printscreen', 'prntscrn', 'prtsc', 'prtscr', 'return', 'right', 'scrolllock', 'select', 'separator', 'shift', 'shiftleft', 'shiftright', 'sleep', 'space', 'stop', 'subtract', 'tab', 'up', 'volumedown', 'volumemute', 'volumeup', 'win', 'winleft', 'winright', 'yen', 'command', 'option', 'optionleft', 'optionright'] 1234567891011121314151617181920212223242526272829303132333435
弹窗操作
我们在pyautogui库对于弹出窗口的使用方法大体如下:
import pyautogui # 显示一个简单的带文字和OK按钮的消息弹窗。用户点击后返回button的文字。 pyautogui.alert(text='', title='', button='OK') b = pyautogui.alert(text='要开始程序么?', title='请求框', button='OK') print(b) # 输出结果为OK # 显示一个简单的带文字、OK和Cancel按钮的消息弹窗,用户点击后返回被点击button的文字,支持自定义数字、文字的列表。 pyautogui.confirm(text='', title='', buttons=['OK', 'Cancel']) # OK和Cancel按钮的消息弹窗 pyautogui.confirm(text='', title='', buttons=range(10)) # 10个按键0-9的消息弹窗 a = pyautogui.confirm(text='', title='', buttons=range(10)) print(a) # 输出结果为你选的数字 12345678910111213
# 可以输入的消息弹窗,带OK和Cancel按钮。用户点击OK按钮返回输入的文字,点击Cancel按钮返回None。 pyautogui.prompt(text='', title='', default='') # 样式同prompt(),用于输入密码,消息用*表示。带OK和Cancel按钮。用户点击OK按钮返回输入的文字,点击Cancel按钮返回None。 pyautogui.password(text='', title='', default='', mask='*') 12345
图像操作
我们在pyautogui库对于图像的使用方法大体如下:
import pyautogui pyautogui.screenshot(r'C:\Users\ZDH\Desktop\PY\my_screenshot.png') # 截全屏并设置保存图片的位置和名称 im = pyautogui.screenshot(r'C:\Users\ZDH\Desktop\PY\my_screenshot.png') # 截全屏并设置保存图片的位置和名称 print(im) # 打印图片的属性 # 不截全屏,截取区域图片。截取区域region参数为:左上角XY坐标值、宽度和高度 pyautogui.screenshot(r'C:\Users\ZDH\Desktop\PY\region_screenshot.png', region=(0, 0, 300, 400)) pix = pyautogui.screenshot().getpixel((220, 200)) # 获取坐标(220,200)所在屏幕点的RGB颜色 positionStr = ' RGB:(' + str(pix[0]).rjust(3) + ',' + str(pix[1]).rjust(3) + ',' + str(pix[2]).rjust(3) + ')' print(positionStr) # 打印结果为RGB:( 60, 63, 65) pix = pyautogui.pixel(220, 200) # 获取坐标(220,200)所在屏幕点的RGB颜色与上面三行代码作用一样 positionStr = ' RGB:(' + str(pix[0]).rjust(3) + ',' + str(pix[1]).rjust(3) + ',' + str(pix[2]).rjust(3) + ')' print(positionStr) # 打印结果为RGB:( 60, 63, 65) # 如果你只是要检验一下指定位置的像素值,可以用pixelMatchesColor(x,y,RGB)函数,把X、Y和RGB元组值穿入即可 # 如果所在屏幕中(x,y)点的实际RGB三色与函数中的RGB一样就会返回True,否则返回False # tolerance参数可以指定红、绿、蓝3种颜色误差范围 pyautogui.pixelMatchesColor(100, 200, (255, 255, 255)) pyautogui.pixelMatchesColor(100, 200, (255, 255, 245), tolerance=10) # 获得文件图片在现在的屏幕上面的坐标,返回的是一个元组(top, left, width, height) # 如果截图没找到,pyautogui.locateOnScreen()函数返回None a = pyautogui.locateOnScreen(r'C:\Users\ZDH\Desktop\PY\region_screenshot.png') print(a) # 打印结果为Box(left=0, top=0, width=300, height=400) x, y = pyautogui.center(a) # 获得文件图片在现在的屏幕上面的中心坐标 print(x, y) # 打印结果为150 200 x, y = pyautogui.locateCenterOnScreen(r'C:\Users\ZDH\Desktop\PY\region_screenshot.png') # 这步与上面的四行代码作用一样 print(x, y) # 打印结果为150 200 # 匹配屏幕所有与目标图片的对象,可以用for循环和list()输出 pyautogui.locateAllOnScreen(r'C:\Users\ZDH\Desktop\PY\region_screenshot.png') for pos in pyautogui.locateAllOnScreen(r'C:\Users\ZDH\Desktop\PY\region_screenshot.png'): print(pos) # 打印结果为Box(left=0, top=0, width=300, height=400) a = list(pyautogui.locateAllOnScreen(r'C:\Users\ZDH\Desktop\PY\region_screenshot.png')) print(a) # 打印结果为[Box(left=0, top=0, width=300, height=400)] 1234567891011121314151617181920212223242526272829303132333435363738
参考资料
PyAutoGUI帮助文档:
https://blog.csdn.net/qq_34053552/article/details/79776671
pyautogui图形自动化,击败重复性办公任务:
https://blog.csdn.net/qq_43017750/article/details/90575240
 
 
 
 
PC 端自动化测试使用到的 python 模块主要有 pywinauto、win32gui、pyautogui,主要功能如下:
pywinauto:主要使用到 Application 类,用于应用程序管理(打开与关闭应用等)、窗口管理(最小化、最大化、关闭窗口)
pywin32:包含 win32gui、win32api、win32con 3个子模块,用于窗口管理(定位窗口、显示和关闭窗口、获取窗口位置等)
pyautogui:屏幕控制(截屏等)、鼠标控制(移动鼠标、单击、双击、右击、拖拽等)、键盘控制(编辑、按键等)
在 pycharm 中运行以下代码,以安装上述包:
install.py
import os
mirror = " -i https://pypi.douban.com/simple"
os.system("python -m pip install --upgrade pip" + mirror) # 更新 pip
os.system("pip install pywinauto" + mirror) # 安装 pywinauto
os.system("pip install pypiwin32" + mirror) # 安装 pypiwin32 和 pywin32
os.system("pip install pyautogui" + mirror) # 安装 pyautogui
注意:安装 pywin32 模块时,使用的是 pypiwin32,否则在导入包时会报错。
查看窗口标题、窗口类、窗口边界坐标、子窗口标题、子窗口类、鼠标位置等信息,可以使用 inspect.exe 和 UISpy.exe 等工具。
2 pywinauto
pywinauto 模块主要用于应用控制(打开、关闭应用等)窗口控制(最大化、最小化窗口等),也可以等位到控件,并对控件进行操作,如点击、编辑等。
对于 pywinauto 模块,主要使用其中的 Application 类,需要导入包,并定义一个 Application 类的对象。
from pywinauto.application import Application
app = Application(backend="win32")
说明:backend 属性有2个取值:win32 和 uia,win32 为默认值,backend 取值不同,接口调用差异较大。
2.1 应用控制
打开应用
app.start(app_path)
app.start(r"C:\Program Files (x86)\Tencent\QQ\Bin\QQ.exe")
连接应用
app.connect(path=app_path)
app.connect(path=r"C:\Program Files (x86)\Tencent\QQ\Bin\QQ.exe")
关闭应用
app.kill()
说明:待连接的应用必须是已经打开的应用,连接应用是为了将 app 对象与目标应用绑定,以实现对目标应用的控制。
2.2 窗口控制
(1)定位窗口
定位到窗口(class_name:窗口类名,title:窗口标题)
dlg = app.window(class_name, title)
dig = app.class_name
dlg = app[title]
判断窗口是否存在
dlg.exists()
(2)获取窗口信息
app.Notepad.print_control_identifiers()
输出如下:
Notepad - '无标题 - 记事本' (L629, T124, R1359, B749)
['Notepad', '无标题 - 记事本Notepad', '无标题 - 记事本']
child_window(title="无标题 - 记事本", class_name="Notepad")
|
| Edit - '' (L638, T187, R1350, B711)
| ['无标题 - 记事本Edit', 'Edit']
| child_window(class_name="Edit")
|
| StatusBar - '' (L638, T711, R1350, B740)
| ['StatusBar UTF-8', '无标题 - 记事本StatusBar', 'StatusBar 第 1 行,第 1 列', 'StatusBar 100%', 'StatusBar Windows (CRLF)', 'StatusBar']
| child_window(class_name="msctls_statusbar32")
(3)最小化、最大化、恢复、关闭窗口
最小化窗口
dlg.minimize()
最大化窗口
dlg.maximize()
恢复窗口
dlg.restore()
关闭窗口
dlg.close()
2.3 控件控制
由于 windows 上一些控件的 class_name、title 等信息通常缺失,较难定位到具体控件,但记事本的各窗口和控件信息较全,本节以记事本为例,介绍控件的简单操作。
from pywinauto.application import Application
from time import sleep
app = Application(backend="win32")
app = app.start(r"C:\WINDOWS\system32\notepad.exe") # 启动记事本
app = app.start(r"notepad.exe") # backend 取值为 win32 时,可以这样写
sleep(1)
app.Notepad["Edit"].TypeKeys(u"您好,记事本,我是 pywinauto") # 定位到输入框,并输入文本
sleep(1)
app.Notepad.MenuSelect(u'文件->另存为(&A)...') # 另存为
sleep(1)
app[u'另存为']['Edit'].TypeKeys(u"xxx.txt") # 输入文件名
sleep(1)
app[u'另存为'][u'保存'].Click() # 保存
sleep(1)
if app[u'另存为'].exists():
app[u'确认另存为'][u"是"].Click() # 替换原文件
3 pywin32
pywin32 包含 win32gui、win32api、win32con 3个子模块,主要用于窗口管理(定位窗口、显示和关闭窗口、窗口前置、窗口聚焦、获取窗口位置等),通常用的较多的是 win32gui,因此本文仅对此子模块进行介绍。在应用时,需要导入如下包:
import win32gui
import win32con
3.1 定位窗口
hwnd = win32gui.FindWindow(lpClassName=None, lpWindowName=None) # 查找窗口,不找子窗口,返回值为0表示未找到窗口
hwnd = win32gui.FindWindowEx(hwndParent=0, hwndChildAfter=0, lpszClass=None, lpszWindow=None) # 查找子窗口,返回值为0表示未找到子窗口
hwnd = win32gui.FindWindow("Notepad", u"无标题 - 记事本")
拓展:可以通过判断 hwnd 是否为0,确定窗口是否存在。
3.2 显示窗口
(1)显示方式
win32gui.ShowWindow(hwnd, win32con.SW_SHOWNORMAL)
SW_HIDE:隐藏窗口并激活其他窗口。nCmdShow=0。
SW_SHOWNORMAL:激活并显示一个窗口。如果窗口被最小化或最大化,系统将其恢复到原来的尺寸和大小。应用程序在第一次显示窗口的时候应该指定此标志。nCmdShow=1。
SW_SHOWMINIMIZED:激活窗口并将其最小化。nCmdShow=2。
SW_SHOWMAXIMIZED:激活窗口并将其最大化。nCmdShow=3。
SW_SHOWNOACTIVATE:以窗口最近一次的大小和状态显示窗口。激活窗口仍然维持激活状态。nCmdShow=4。
SW_SHOW:在窗口原来的位置以原来的尺寸激活和显示窗口。nCmdShow=5。
SW_MINIMIZE:最小化指定的窗口并且激活在Z序中的下一个顶层窗口。nCmdShow=6。
SW_SHOWMINNOACTIVE:窗口最小化,激活窗口仍然维持激活状态。nCmdShow=7。
SW_SHOWNA:以窗口原来的状态显示窗口。激活窗口仍然维持激活状态。nCmdShow=8。
SW_RESTORE:激活并显示窗口。如果窗口最小化或最大化,则系统将窗口恢复到原来的尺寸和位置。在恢复最小化窗口时,应用程序应该指定这个标志。nCmdShow=9。
SW_SHOWDEFAULT:依据在STARTUPINFO结构中指定的SW_FLAG标志设定显示状态,STARTUPINFO 结构是由启动应用程序的程序传递给CreateProcess函数的。nCmdShow=10。
(2)判断窗口是否最小化
若最小化,则将其显示
if win32gui.IsIconic(hwnd):
win32gui.ShowWindow(hwnd, win32con.SW_SHOWNORMAL)
(3)关闭窗口
win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)
(4) 窗口置前并获得焦点
win32gui.SetForegroundWindow(hwnd) # 设置前置窗口
win32gui.SetFocus(hwnd) # 设置聚焦窗口
3.3 屏幕信息
(1)获取窗边界
left, top, right, bottom = win32gui.GetWindowRect(hwnd) # 获取窗口边界
(2)屏幕缩放比
import win32api, win32con, win32print, win32gui
def get_screen_scale_rate():
x = win32api.GetSystemMetrics(0) # 屏幕缩放后的宽度分辨率
hDC = win32gui.GetDC(0)
w = win32print.GetDeviceCaps(hDC, win32con.DESKTOPHORZRES) # 屏幕真实的宽度分辨率
return w/x
注意:在获取屏幕缩放比时,不要和 pyautogui 包同时使用,否则 x=w。
4 pyautogui
pyautogui 模块主要用于屏幕控制(获取屏幕尺寸、截屏等)、鼠标控制(移动鼠标、单击、双击、右击、拖拽、滚动等)、键盘控制(编辑、按键等)。在使用此模块时,需要导入如下包:
import pyautogui
4.1 屏幕控制
(1)获取屏幕分辨率
screenWidth, screenHeight = pyautogui.size()
(2)截屏
pyautogui.screenshot("my_screenshot.png", region=(100,100,500,500)) # region 为截屏区域,忽略表示截全屏
img = pyautogui.screenshot()
img.save('my_screenshot.png')
(3) 查找图片
coords = pyautogui.locateOnScreen('target_capture.png') # 在当前屏幕中查找指定图片(图片是当前屏幕某个区域的截图)
x, y = pyautogui.center(coords) # 获取定位到的图中间点坐标
x, y = locateCenterOnScreen('target_capture.png') # 返回查找到的截图中心坐标
说明:此方法通常用于定位到控件。
4.2 鼠标控制
(1)获取鼠标位置与移动鼠标
获取鼠标位置
x, ypyautogui.position()
移动鼠标(x, y 为绝对位置,xOffset, yOffset 为相对偏移量,tween:渐变函数)
pyautogui.moveTo(x=100, y=100, duration=2, tween=pyautogui.linear)
pyautogui.moveRel(xOffset=None, yOffset=10, duration=0.0, tween=pyautogui.linear) # 相对原来的位置移动
(2)点击
单击鼠标(x, y 为点击位置,clicks:点击次数,interval:点击间隔,botton:取值有'left', 'middle', 'right',对应鼠标的左、中、右,duration:点击持续时间,tween:渐变函数)
pyautogui.click(x=None, y=None, clicks=1, interval=0.0, button='left', duration=0.0, tween=pyautogui.linear)
pyautogui.click(x, y) # 单击
pyautogui.rightClick(x, y) # 右击
pyautogui.middleClick(x, y) # 中击
pyautogui.doubleClick(x, y) # 双击
(3) 拖拽
鼠标拖拽
pyautogui.dragTo(x=427, y=535, duration=3, button='left')
鼠标相对拖拽
pyautogui.dragRel(xOffset=100, yOffset=100, duration=3, button='left', mouseDownUp=False)
(4)滚动
pyautogui.scroll(-500) # 向下滚 500 格
4.3 键盘控制
输入文本
pyautogui.typewrite(message='Hello world!', interval=0.25)
按键
pyautogui.press('esc')
pyautogui.press(['left', 'left', 'left']) # 依次按多个按键
组合热键(从左到右依次按下按键,再从右到左依次松开按键)
pyautogui.hotkey('ctrl', 'c')
常用按键说明如下:
ctrl、shift、alt、esc、backspace、win:同键盘
capslock、numlock、scrolllock、insert、delete、home、end、pageup、pagedown、pause、printscreen:同键盘
f1、f2、f3、...、f12:同键盘
enter、return、\n:Enter键
tab、\t:Tab键
up、down、left、right:箭头键
————————————————
版权声明:本文为CSDN博主「little_fat_sheep」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_37602827/article/details/108308991
 
 
 
 
鄙人也是第一次:
  查了资料都是手机APP、Windows应用程序的自动化,为什么没有Linux应用程序的自动化测试?探索期间有个Airtest网易出的自动化测试功能强大,但是还不支持Linux,娃娃哈哈哈~
然后了解到了python中的pyautogui跨平台自动化框架。自动输入、自动点击都自动了,但是如何断言啊,我还想使用unittest框架生成测试报告
  苦思:就是把pyautogui官方文档好好看看,绝对有你需要的方法~有了方法在哪里使用就看你自己了。
  断言:预先把结果截图,比如密码不能为空,点击提交时会有提示:密码不能为空。那我们就先把密码不能为空这个提示截图,然后再使用pyautogui中的Locate Functions 去断言
附上我的源码:
  
0
 
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2020/6/2 下午2:58 # @Author : AiShuiShui-艾谁谁 # @Site : # @File : test_login.py import os import sys sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) # 解决在服务器导包错误 import unittest from assertpy import assert_that # 很好的断言工具 from log import logging1 # 自己写的log对象 import subprocess # 用来异步执行linux命令很好用 import airtest # 一款基于图像识别和poco控件识别的一款UI自动化测试工具 import time import pyautogui import os import importlib # 重新加载包 importlib.reload(logging1) import configparser # 加载配置文件 cf = configparser.ConfigParser() cf.read('./config.ini') client_app_name = cf.get("server", "app_name") deb_path = cf.get("client", "client_deb_file") # 你的包需要放的位置,按需修改 pyautogui.FAILSAFE = True # 鼠标移动到左上角停止程序 pyautogui.PAUSE = 1 # 执行每个函数后停止1s logger = logging1.get_logger() import HTMLTestRunner import warnings # 解决警告问题 importlib.reload(logging1) # 更新log文件后重新加载 pyautogui.FAILSAFE = True # 鼠标移动到左上角停止程序 pyautogui.PAUSE = 1 # 执行每个函数后停止1 logger = logging1.get_logger() start_cmd = 'client' end_cmd = 'pkill client' password = "××××" class TestLogIn(unittest.TestCase): def setUp(self) -> None: warnings.simplefilter('ignore', ResourceWarning) # 解决警告 """ 先打开应用程序 :return: """ cmd = start_cmd subprocess.Popen(cmd) time.sleep(2) def tearDown(self) -> None: warnings.simplefilter('ignore', ResourceWarning) """ 每次测试完毕,都需要关闭应用程序 :return: """ cmd = end_cmd os.system(cmd) def test_1(self): """ 判断页面元素完整性 :return: """ login_ui = pyautogui.locateOnScreen('../screenshot/2020-06-08_16-27.png', confidence=0.9) # 如果没有找到则返回none,如果是none,那意味这有问题 confidence允许稍微的色素差 pyautogui.screenshot("../result_screenshot/login_ui.png") assert_that(login_ui).is_not_equal_to(None) # 不为none才是正确的结果 def test_2(self): """ 插入加密狗,输入空的密码,提示密码不能为空 :return: """ buttonkmslocation = pyautogui.locateOnScreen("../screenshot/请输入登录密码.png", confidence=0.9) # 获取中心点(结合上面) buttonkmspoint = pyautogui.center(buttonkmslocation) print(buttonkmspoint) # 获取到中心点后点击, pyautogui.click(buttonkmspoint) time.sleep(1) # 不输入密码点击登录 pyautogui.moveRel(0, 50) pyautogui.click() # 当前页面是不是包含密码不能为空 buttonkmslocation1 = pyautogui.locateOnScreen("../screenshot/密码不能为空.png", confidence=0.9) print(buttonkmslocation1) # 如果不为空就证明找到了 pyautogui.screenshot("../result_screenshot/密码不能为空.png") assert_that(buttonkmslocation1).is_not_equal_to(None) time.sleep(1) def test_3(self): """ 插入加密狗,输入的错误的密码,提示密码错误 :return: """ buttonkmslocation = pyautogui.locateOnScreen("../screenshot/请输入登录密码.png", confidence=0.9) # 获取中心点(结合上面) buttonkmspoint = pyautogui.center(buttonkmslocation) print(buttonkmspoint) # 获取到中心点后点击, pyautogui.click(buttonkmspoint) time.sleep(1) # 输入密码点击登录 pyautogui.typewrite("123", interval=0.5) pyautogui.moveRel(0, 50) pyautogui.click() # 当前页面包含密码错误提示 buttonkmslocation1 = pyautogui.locateOnScreen("../screenshot/error_password.png", confidence=0.9) print("已经在屏幕上捕获到:", buttonkmslocation1) # 如果不为空就证明找到了 pyautogui.screenshot("../result_screenshot/密码错误.png") assert_that(buttonkmslocation1).is_not_equal_to(None) time.sleep(1) def test_4(self): """ 插入加密狗,输入正确的密码,进入主页面 :return: """ buttonkmslocation = pyautogui.locateOnScreen("../screenshot/请输入登录密码.png", confidence=0.9) # 获取中心点(结合上面) buttonkmspoint = pyautogui.center(buttonkmslocation) print(buttonkmspoint) # 获取到中心点后点击, pyautogui.click(buttonkmspoint) time.sleep(1) # 输入密码点击登录 pyautogui.typewrite(password, interval=0.5) # interval作用是每输入一个等待0.5s,模拟人输入 pyautogui.moveRel(0, 50) pyautogui.click() # 当前页面已经进入主页面包含 buttonkmslocation1 = pyautogui.locateOnScreen("../screenshot/sn_no.png", confidence=0.9) print("已经在屏幕上捕获到:", buttonkmslocation1) # 并且截屏一张,方便查看 pyautogui.screenshot("../result_screenshot/进入登录页面.png") assert_that(buttonkmslocation1).is_not_equal_to(None) time.sleep(1) if __name__ == '__main__': suit = unittest.TestSuite() suit.addTest(TestLogIn('test_1')) suit.addTest(TestLogIn('test_2')) suit.addTest(TestLogIn('test_3')) suit.addTest(TestLogIn('test_4')) now = time.strftime('%m_%d_%H-%M-%S') with open("../result_report_html/%s.html" % now, "wb") as fp: runner = HTMLTestRunner.HTMLTestRunner( stream=fp, title="测试报告", description="登录报告" ) runner.run(suit)
 
 
0
注意:如果使用了unittest框架的话,一定要在终端执行你的python脚本,要不然你的报告永远都没有办法生成,网上的方法找了,没用哦,都是相互抄袭;