1、计划
压测完成后需要编写性能测试报告,报告中所需数据截图较多,使用自动化操作方便快捷,就编写一个界面工具以便后续复用。
基于PyAutoGUI图片定位的自动化截图工具–jmeter部分
使用pyautogui 库操作鼠标键盘,按钮根据截取的识别图定位。要使用库自己的截图screenshot函数,其它方式如微信截图,pygetwindow 库识别不到图片位置。
import pyautogui as pg # 图形用户界面 (GUI) 操作,控制鼠标、键盘和屏幕
pg.screenshot(path, region=region) # 坐标+宽+高 # 截图
2、jm初始化页面
- 界面开发
初始化页面,主要是对公共按钮的识别图进行截取。比如jmeter的全部清理按钮,在每次截图后要清理报告数据,不然再次打开报告数据会附加到已有报告。
- 窗口切换
截取识别图像与截取报告,都需要切换到jmeter窗口,这里写了全局函数activate_window()。
使用pygetwindow 库操作Windows窗口,切换到相应的标题窗口,默认最大化窗口。当max != 0时,窗口不最大化。
import pygetwindow as pw # 获取、管理和操作窗口
def activate_window(window_title, max=0):
"""激活指定标题片段的窗口,切换至前台最大化True"""
windows = pw.getAllTitles() # 返回所有窗口的标题列表
matching_windows = [win for win in windows if window_title.lower() in win.lower()] # 遍历列表,忽略大小写
if matching_windows:
window = pw.getWindowsWithTitle(matching_windows[0])[0] # 获取 Window 对象
window.activate() # 切换到匹配窗口
window.maximize() if max == 0 else None # 最大化窗口
return True
else:
return False
- 识别图截取
先判断跳转jmeter窗口,然后获取输入的截图范围,截图。如果成功则将记录写入JM_JSON。最后切换回‘初始化’窗口。
def init_cut(self):
"""初始化,截取识别图"""
if activate_window("Apache JMeter"): # jmeter启动判断
time.sleep(1)
else:
self.ts.xinxi("没找到名称包含【JMeter】的窗口,请检查jmeter是否启动")
return
button = self.sender().objectName() # 获取点击的按钮名称
region = (self.spinBox_1.value(), self.spinBox_2.value(), self.spinBox_3.value(), self.spinBox_4.value())
path = f'Identify/init_tu1.png'
pg.screenshot(path, region=region) # 坐标+宽+高 # 截图
if os.path.exists(path):
data = {f'{button}': path}
if not os.path.exists(JM_JSON):
# 文件不存在,直接写入新数据
with open(JM_JSON, 'w', encoding='utf-8') as f:
json.dump(data, f)
else:
# 文件存在,读取并合并数据
with open(JM_JSON, 'r', encoding='utf-8') as f:
existing_data = json.load(f)
if 'init' not in existing_data:
existing_data['init'] = {}
existing_data['init'].update(data)
# 写回更新后的数据
with open(JM_JSON, 'w', encoding='utf-8') as f:
json.dump(existing_data, f)
self.jm_first_show()
self.ts.xinxi("截图保存成功")
else:
# 文件不存在
self.ts.xinxi("截图保存失败")
activate_window("初始化", max=1)
- 实现情况
输入范围,点击 截取,切换窗口,截图显示。其它页面的识别图片截取都差不多流程,就不写了。
3、识别测试
添加了监听器按钮后,不确定识别图片是否可用,增加了识别测试功能。
- 点击功能函数:传入识别图地址,返回坐标。重试两次
locateCenterOnScreen 函数旨在查找指定图像在当前屏幕上的位置,并返回该图像中心点的坐标。
pyautogui.locateCenterOnScreen(image_path, grayscale=False, confidence=None, region=None)
参数说明:
image_path:必填参数,字符串类型。指定待查找的图像文件的路径。确保文件路径正确且图像可以被正确加载。
grayscale(可选):布尔类型。默认为 False。如果设为 True,则在进行图像匹配时,将对屏幕截图和目标图像都转化为灰度模式,这在某些情况下可能会提高匹配的准确性。
confidence(可选):浮点数类型。指定图像匹配的最低置信度阈值。如果提供了该参数,只有当匹配得分超过该阈值时,才认为找到了匹配项。较高的置信度意味着更严格的匹配要求,较低的置信度可能导致更多的假阳性结果。如果不指定,库通常会使用一个内部默认值。
region(可选):元组类型,包含四个整数 (left, top, width, height),表示在屏幕上的一个矩形区域,分别对应左上角坐标 (x, y) 和区域的宽度、高度。仅在这个区域内查找目标图像。若不提供此参数,则在整个屏幕上搜索。
def locate(self, tu):
"""根据图片地址,识别图片并点击"""
MAX_RETRIES = 2 # 重试次数
retries = 0
while retries < MAX_RETRIES:
try:
location = pg.locateCenterOnScreen(tu, confidence=0.9, grayscale=True,
region=(0, 0, move_distance_x, move_distance_y))
# 识别图片位置grayscale=True,confidence=0.9
pg.moveTo(location, duration=0.5) # 鼠标移动
pg.click(location)
return location # 成功找到并点击,返回 location
except pg.ImageNotFoundException:
retries += 1
if retries == MAX_RETRIES:
self.daochulog.append(f"经过 {retries} 次重试,仍未找到图像 {tu}。")
return False # 最大重试次数,返回 False
else:
self.daochulog.append(f"第 {retries} 次尝试定位图像 {tu} 失败,将在 0.5 秒后重试。")
time.sleep(0.5) # 延迟一段时间后再重试
except pg.FailSafeException as e:
raise e # 重新抛出异常,使其到外部停止循环。失效保护
except Exception as e:
self.daochulog.append(f"定位图像 {tu} 时发生未知异常:{e}")
return False
- 识别图,点击测试
先判断获取监听器数据,jmeter窗口,然后遍历初始化按钮与监听器的按钮,点击。日志显示窗口。
def jm_test(self):
"""识别图,点击测试"""
jtq = [item.text(0) for item in self.mkliebiao_2.selectedItems()] # 选中监听器
if not jtq:
self.ts.xinxi("请选择待测试监听器")
return
if activate_window("Apache JMeter"): # jmeter启动判断
time.sleep(1)
else:
self.ts.xinxi("没找到名称包含【JMeter】的窗口,请检查jmeter是否启动")
return
self.daochulog.append("\n识别测试----开始\n")
pg.click(100, 600)
pg.press('home') # 切换顶部,避免按钮选中
with open(JM_JSON, 'r', encoding='utf-8') as f:
data = json.load(f)
init = data.get('init', {}) # 获取tu数据
tu1 = init.get('tu1', {})
if tu1:
self.daochulog.append(f"初始化:----开始")
try:
self.locate(tu1)
except pg.FailSafeException:
self.daochulog.append("\nPyAutoGUI失效保护触发。已停止自动化操作。")
else:
self.daochulog.append(f"初始化:识别图1----未截取\n")
for key in jtq: # 监听器,识别图校验
self.daochulog.append(f"{key}----开始")
for i in range(1, 4):
tus = data[key].get(f'tu{i}', {})
if i != 3 and tus == {}:
self.daochulog.append(f"识别图{i}----未截取")
elif tus != {}:
try:
self.locate(tus)
except pg.FailSafeException:
self.daochulog.append("\nPyAutoGUI失效保护触发。已停止自动化操作。")
activate_window("Report screenshot", max=1)
- 识别测试情况
对勾选监听器进行点击,无识别图的进行提示。