PC端自动化pywinauto 、uiautomation+pyautogui+opencv

主要方案

  • pywinauto 、uiautomation 用于通过界面控件定位(这里更建议使用pywinauto )

    • 在这里插入图片描述
  • pyautogui 模拟键鼠操作元素,主要用来弥补某些控件无法通过属性定位

  • opencv 可以通过图片定位某个坐标,或者用来做图片比对断言

  • 值得注意的是,如果使用了坐标、图片则需要保证执行电脑的分辨率永不会变化

定位方式

  • 窗口控件的属性,常用的就下面几种
    • ID
    • 类名
    • XML路径语言
    • CSS选择器
    • Name
    • 连接文本
    • 标签名
  • 通过图片定位(开发并不一定给所有的控件加属性),所以这个时候就需要用到通过图片去找到对应控件的坐标
  • 直接通过坐标定位,主要用于复杂图片,图片识别度不够找不到图片的场景,或者控件的图片本身就是动态的,就通过屏幕的x、y坐标直接使用pyautogui去操作

控件定位工具

在这里插入图片描述

框架结构

UI自动化由于界面变动,维护成本较高,仍建议采用传统的PO模式
在这里插入图片描述
PO理念是自动化测试的一种设计思想,对应用的页面类进行分层设计,包括:元素管理层、操作管理层、业务逻辑管理。

简单理解就是:一个页面一个类,一个元素一个方法。

元素管理层:页面控件定位,通过元素属性、坐标、图片等方式定位,比如定位导入按钮 。
操作管理层:定位元素后,获取元素对象,进行操作,封装成页面动作,比如单击导入按钮。
业务逻辑层:多个页面动作组成的一个完整的业务逻辑,比如导入模型数据(单击导入按钮-单击选择模型数据-单击确定按钮)。
测试用例层:多个业务逻辑组成的一个完整的测试用例,比如导入模型数据-调整特征点-导出工程-验证工程内调整的特征点数据。

优点:尽可能方便后期维护,提高代码可读性,让用例只关注与业务逻辑。

按照以上结构封装,元素变了只用改元素,交互变了只用改交互,业务变了只用改业务,就不需要一边动就得改跟多的用例了

调用逻辑

在这里插入图片描述

脚本示例

  • 启动应用程序:

    • 使用 pywinauto 的 Application.start() 方法启动应用程序。
  • 点击登录按钮:

    • 使用 pywinauto 的 child_window() 方法找到登录按钮,并调用 click() 方法点击。
  • 识别头像图片并点击:

    • 使用 OpenCV 的模板匹配功能在屏幕上查找头像图片,并返回其中心坐标。

    • 使用 pyautogui.click() 点击头像位置。

  • 点击图片放大按钮:

    • 使用 pyautogui.click() 点击指定的放大按钮坐标。
  • 断言图片是否被放大:

    • 使用 OpenCV 的模板匹配功能比较原始图片和放大后的图片。

    • 如果放大后的图片匹配度更高,则断言图片已放大。

import time
import cv2
import numpy as np
import pyautogui
from pywinauto import Application

# 1. 启动应用程序
app_path = r"C:\Path\To\YourApp.exe"  # 替换为你的应用程序路径
app = Application(backend="uia").start(app_path)
time.sleep(5)  # 等待应用程序启动

# 2. 找到登录按钮并点击
window = app.window(title_re=".*你的应用标题.*")  # 替换为你的应用窗口标题
login_button = window.child_window(title="登录", control_type="Button")
login_button.click()
print("点击登录按钮")

# 3. 使用 OpenCV 识别头像图片并点击
def find_image_on_screen(template_path, threshold=0.8):
    """在屏幕上查找图片并返回中心坐标"""
    screenshot = pyautogui.screenshot()
    screenshot = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
    template = cv2.imread(template_path, cv2.IMREAD_COLOR)
    result = cv2.matchTemplate(screenshot, template, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    if max_val >= threshold:
        center_x = max_loc[0] + template.shape[1] // 2
        center_y = max_loc[1] + template.shape[0] // 2
        return center_x, center_y
    else:
        return None

# 查找头像图片
avatar_template_path = r"C:\Path\To\avatar_template.png"  # 替换为头像图片路径
avatar_position = find_image_on_screen(avatar_template_path)
if avatar_position:
    pyautogui.click(avatar_position)
    print(f"点击头像位置: {
      
      avatar_position}")
else:
    print("未找到头像图片")

# 4. 使用 pyautogui 点击图片放大按钮
zoom_button_position = (100, 200)  # 替换为放大按钮的坐标
pyautogui.click(zoom_button_position)
print(f"点击放大按钮位置: {
      
      zoom_button_position}")

# 5. 使用 OpenCV 断言图片是否被放大
def assert_image_zoomed(original_template_path, zoomed_template_path, threshold=0.8):
    """断言图片是否被放大"""
    original_template = cv2.imread(original_template_path, cv2.IMREAD_COLOR)
    zoomed_template = cv2.imread(zoomed_template_path, cv2.IMREAD_COLOR)
    screenshot = pyautogui.screenshot()
    screenshot = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
    original_result = cv2.matchTemplate(screenshot, original_template, cv2.TM_CCOEFF_NORMED)
    zoomed_result = cv2.matchTemplate(screenshot, zoomed_template, cv2.TM_CCOEFF_NORMED)
    _, original_max_val, _, _ = cv2.minMaxLoc(original_result)
    _, zoomed_max_val, _, _ = cv2.minMaxLoc(zoomed_result)
    if zoomed_max_val > original_max_val and zoomed_max_val >= threshold:
        print("图片已放大")
    else:
        print("图片未放大")

# 断言图片是否被放大
original_image_path = r"C:\Path\To\original_image.png"  # 替换为原始图片路径
zoomed_image_path = r"C:\Path\To\zoomed_image.png"  # 替换为放大后的图片路径
assert_image_zoomed(original_image_path, zoomed_image_path)

封装思路

  • 软件启动方法封装为单例模式,启动后激活窗口,并检查窗口;配合conftest pytest.fixture使用
  • 元素查找(包含通过属性、坐标、图片返回元素的坐标)
  • 元素操作进行二次封装,封装成通用方法,比如传入坐标操作、传入图片路径操作、传入空间属性操作(包含常见的键盘鼠标操作)
  • 断言封装成通过方法(包含通过属性、图片、进程检查)
  • 结束软件封装成通过方法(包含通过点击软件界面退出、直接结束进程退出)
  • 异常捕获,用例失败时截图,便于报告解读

文件目录参考


-pages 主要存放元素的定位、元素的操作、业务逻辑(比如一个上传动作、一个订单生成动作等)
-test_case 主要存放执行的用例,调用业务逻辑方法就可实现
-test_data 主要存放测试需要用到的数据
-static 存放通过图片定位的图片,通过图片断言的的图片
-commons 通用方法键鼠、cmd、断言、图片日志
-utils 通用方法 文件操作、JSON操作、yaml操作、通过ftp流转文件
-config 常用配置 账号密码、安装包路径、项目路径、项目文件路径(图片、日志、报告等)、应用的进程名称、窗口名称、等待时间等等