Python pywinauto PC端自动化测试核心代码封装类
以下是一个基于pywinauto的自动化测试核心代码封装类的完整代码实例,其中包含多个函数实例并加上中文注释
import pywinauto
import time
class PywinautoWrapper:
def __init__(self, app_path):
"""
初始化函数,传入应用程序的路径
"""
self.app_path = app_path
self.app = pywinauto.Application().start(self.app_path)
def get_app(self):
"""
获取应用程序对象
"""
return self.app
def get_main_window(self):
"""
获取主窗口对象
"""
return self.app.top_window()
def get_control(self, control_type, control_name, parent=None):
"""
获取控件对象
"""
if parent is None:
parent = self.get_main_window()
return parent.child_window(control_type=control_type, best_match=control_name)
def get_controls(self, control_type, control_name, parent=None):
"""
获取多个控件对象
"""
if parent is None:
parent = self.get_main_window()
return parent.child_windows(control_type=control_type, best_match=control_name)
def click_control(self, control_type, control_name, parent=None, double_click=False):
"""
点击控件
"""
control = self.get_control(control_type, control_name, parent)
if double_click:
control.double_click_input()
else:
control.click_input()
def right_click_control(self, control_type, control_name, parent=None):
"""
右键点击控件
"""
control = self.get_control(control_type, control_name, parent)
control.right_click_input()
def set_text(self, control_type, control_name, text, parent=None):
"""
设置控件文本
"""
control = self.get_control(control_type, control_name, parent)
control.set_text(text)
def get_text(self, control_type, control_name, parent=None):
"""
获取控件文本
"""
control = self.get_control(control_type, control_name, parent)
return control.get_text()
def get_value(self, control_type, control_name, parent=None):
"""
获取控件值
"""
control = self.get_control(control_type, control_name, parent)
return control.get_value()
def is_checked(self, control_type, control_name, parent=None):
"""
判断控件是否被选中
"""
control = self.get_control(control_type, control_name, parent)
return control.is_checked()
def check(self, control_type, control_name, parent=None):
"""
选中控件
"""
control = self.get_control(control_type, control_name, parent)
control.check()
def uncheck(self, control_type, control_name, parent=None):
"""
取消选中控件
"""
control = self.get_control(control_type, control_name, parent)
control.uncheck()
def select(self, control_type, control_name, item_text, parent=None):
"""
选择下拉框中的项
"""
control = self.get_control(control_type, control_name, parent)
control.select(item_text)
def get_selected_text(self, control_type, control_name, parent=None):
"""
获取下拉框中当前选中的项的文本
"""
control = self.get_control(control_type, control_name, parent)
return control.get_selected_text()
def get_selected_index(self, control_type, control_name, parent=None):
"""
获取下拉框中当前选中的项的索引
"""
control = self.get_control(control_type, control_name, parent)
return control.get_selected_index()
def get_item_count(self, control_type, control_name, parent=None):
"""
获取下拉框中的项的个数
"""
control = self.get_control(control_type, control_name, parent)
return control.item_count()
def select_radio_button(self, control_type, control_name, parent=None):
"""
选择单选按钮
"""
control = self.get_control(control_type, control_name, parent)
control.select()
def is_enabled(self, control_type, control_name, parent=None):
"""
判断控件是否可用
"""
control = self.get_control(control_type, control_name, parent)
return control.is_enabled()
def is_visible(self, control_type, control_name, parent=None):
"""
判断控件是否可见
"""
control = self.get_control(control_type, control_name, parent)
return control.is_visible()
def is_exist(self, control_type, control_name, parent=None):
"""
判断控件是否存在
"""
try:
control = self.get_control(control_type, control_name, parent)
return True
except:
return False
def wait_for_control(self, control_type, control_name, timeout=10, parent=None):
"""
等待控件出现
"""
if parent is None:
parent = self.get_main_window()
parent.wait('exists enabled visible ready', timeout=timeout)
return self.get_control(control_type, control_name, parent)
def wait_for_control_disappear(self, control_type, control_name, timeout=10, parent=None):
"""
等待控件消失
"""
if parent is None:
parent = self.get_main_window()
parent.wait_not('exists enabled visible', timeout=timeout)
def wait_for_text(self, control_type, control_name, text, timeout=10, parent=None):
"""
等待控件文本出现
"""
if parent is None:
parent = self.get_main_window()
control = self.wait_for_control(control_type, control_name, timeout=timeout, parent=parent)
control.wait('text=' + text, timeout=timeout)
def wait_for_value(self, control_type, control_name, value, timeout=10, parent=None):
"""
等待控件值出现
"""
if parent is None:
parent = self.get_main_window()
control = self.wait_for_control(control_type, control_name, timeout=timeout, parent=parent)
control.wait('value=' + value, timeout=timeout)
def wait_for_enabled(self, control_type, control_name, timeout=10, parent=None):
"""
等待控件可用
"""
if parent is None:
parent = self.get_main_window()
control = self.wait_for_control(control_type, control_name, timeout=timeout, parent=parent)
control.wait('enabled', timeout=timeout)
def wait_for_disabled(self, control_type, control_name, timeout=10, parent=None):
"""
等待控件不可用
"""
if parent is None:
parent = self.get_main_window()
control = self.wait_for_control(control_type, control_name, timeout=timeout, parent=parent)
control.wait_not('enabled', timeout=timeout)
def wait_for_visible(self, control_type, control_name, timeout=10, parent=None):
"""
等待控件可见
"""
if parent is None:
parent = self.get_main_window()
control = self.wait_for_control(control_type, control_name, timeout=timeout, parent=parent)
control.wait('visible', timeout=timeout)
def wait_for_invisible(self, control_type, control_name, timeout=10, parent=None):
"""
等待控件不可见
"""
if parent is None:
parent = self.get_main_window()
control = self.wait_for_control(control_type, control_name, timeout=timeout, parent=parent)
control.wait_not('visible', timeout=timeout)
def wait_for_exist(self, control_type, control_name, timeout=10, parent=None):
"""
等待控件存在
"""
if parent is None:
parent = self.get_main_window()
parent.wait('exists', timeout=timeout)
return self.get_control(control_type, control_name, parent)
def wait_for_not_exist(self, control_type, control_name, timeout=10, parent=None):
"""
等待控件不存在
"""
if parent is None:
parent = self.get_main_window()
parent.wait_not('exists', timeout=timeout)
def wait_for_clickable(self, control_type, control_name, timeout=10, parent=None):
"""
等待控件可点击
"""
if parent is None:
parent = self.get_main_window()
control = self.wait_for_control(control_type, control_name, timeout=timeout, parent=parent)
control.wait('enabled visible ready', timeout=timeout)
def wait_for_not_clickable(self, control_type, control_name, timeout=10, parent=None):
"""
等待控件不可点击
"""
if parent is None:
parent = self.get_main_window()
control = self.wait_for_control(control_type, control_name, timeout=timeout, parent=parent)
control.wait_not('enabled visible ready', timeout=timeout)
以下是一个使用pywinauto库实现自动化测试的核心代码封装类,其中包含了多个常用的函数实例并加上了中文注释,方便开发者理解和使用。
import time
import pywinauto
from pywinauto.keyboard import send_keys
from pywinauto.win32structures import RECT
from pywinauto.controls.win32_controls import ButtonWrapper, EditWrapper, ComboBoxWrapper, ListBoxWrapper
class AutoTest:
def __init__(self):
self.app = None
self.dlg = None
self.ctrl = None
# 启动应用程序
def start_app(self, path):
self.app = pywinauto.application.Application(backend="uia")
self.app.start(path)
self.app.wait_cpu_usage_lower(threshold=5, timeout=60)
self.dlg = self.app.window(title_re=".*", visible_only=True)
# 关闭应用程序
def close_app(self):
self.app.kill()
# 查找窗口
def find_window(self, title=None, class_name=None, handle=None, active_only=True):
if title is not None:
self.dlg = self.app.window(title=title, active_only=active_only)
elif class_name is not None:
self.dlg = self.app.window(class_name=class_name, active_only=active_only)
elif handle is not None:
self.dlg = self.app.window(handle=handle)
else:
raise ValueError("参数错误:需要指定窗口标题、类名或句柄")
return self.dlg
# 查找控件
def find_control(self, ctrl_type, ctrl_name=None, parent=None, index=0):
if parent is None:
parent = self.dlg
if ctrl_type == "Button":
self.ctrl = parent.child_window(class_name="Button", title=ctrl_name, found_index=index)
elif ctrl_type == "Edit":
self.ctrl = parent.child_window(class_name="Edit", found_index=index)
elif ctrl_type == "ComboBox":
self.ctrl = parent.child_window(class_name="ComboBox", found_index=index)
elif ctrl_type == "ListBox":
self.ctrl = parent.child_window(class_name="ListBox", found_index=index)
elif ctrl_type == "TreeView":
self.ctrl = parent.child_window(class_name="SysTreeView32", found_index=index)
elif ctrl_type == "TabControl":
self.ctrl = parent.child_window(class_name="SysTabControl32", found_index=index)
else:
raise ValueError("参数错误:不支持的控件类型")
return self.ctrl
# 获取控件类名
def get_control_class_name(self, ctrl):
return ctrl.class_name()
# 获取控件标题
def get_control_title(self, ctrl):
return ctrl.window_text()
# 获取控件句柄
def get_control_handle(self, ctrl):
return ctrl.handle
# 获取控件矩形区域
def get_control_rect(self, ctrl):
rect = ctrl.rectangle()
return (rect.left, rect.top, rect.width(), rect.height())
# 获取控件是否启用
def is_control_enabled(self, ctrl):
return ctrl.is_enabled()
# 获取控件是否可见
def is_control_visible(self, ctrl):
return ctrl.is_visible()
# 获取控件是否选中
def is_control_checked(self, ctrl):
return ctrl.get_check_state() == 1
# 获取控件是否存在
def is_control_exists(self, ctrl):
return ctrl.exists()
# 获取控件中的文本内容
def get_control_text(self, ctrl):
return ctrl.get_text()
# 设置控件中的文本内容
def set_control_text(self, ctrl, text):
ctrl.set_text(text)
# 获取控件中的选项列表
def get_control_items(self, ctrl):
if isinstance(ctrl, ComboBoxWrapper):
return ctrl.texts()
elif isinstance(ctrl, ListBoxWrapper):
return ctrl.items()
else:
raise ValueError("参数错误:不支持的控件类型")
# 获取控件中选中的项
def get_control_selected_item(self, ctrl):
if isinstance(ctrl, ComboBoxWrapper):
return ctrl.get_selected_text()
elif isinstance(ctrl, ListBoxWrapper):
return ctrl.get_selected_text()
else:
raise ValueError("参数错误:不支持的控件类型")
# 设置控件中选中的项
def set_control_selected_item(self, ctrl, text):
if isinstance(ctrl, ComboBoxWrapper):
ctrl.select(text)
elif isinstance(ctrl, ListBoxWrapper):
ctrl.select(text)
else:
raise ValueError("参数错误:不支持的控件类型")
# 获取控件中的子项
def get_control_children(self, ctrl):
return ctrl.children()
# 获取控件中的父项
def get_control_parent(self, ctrl):
return ctrl.parent()
# 获取控件中的兄弟项
def get_control_siblings(self, ctrl):
return ctrl.siblings()
# 点击控件
def click_control(self, ctrl):
ctrl.click()
# 双击控件
def double_click_control(self, ctrl):
ctrl.double_click()
# 右击控件
def right_click_control(self, ctrl):
ctrl.right_click()
# 拖拽控件
def drag_control(self, ctrl, x, y):
ctrl.drag_mouse_input(button="left", pressed="", absolute=False, coords=(x, y))
# 放置控件
def drop_control(self, ctrl, x, y):
ctrl.drop_mouse_input(coords=(x, y))
# 模拟键盘输入
def send_keys(self, keys):
send_keys(keys)
# 模拟键盘组合键
def send_key_combination(self, keys):
send_keys(keys, with_spaces=True)
# 模拟鼠标滚轮滚动
def mouse_wheel(self, ctrl, direction="up", amount=1):
if direction == "up":
ctrl.mouse_wheel_input(wheel_dist=120 * amount)
elif direction == "down":
ctrl.mouse_wheel_input(wheel_dist=-120 * amount)
else:
raise ValueError("参数错误:不支持的滚动方向")
# 等待控件出现
def wait_control_appear(self, ctrl, timeout=10):
ctrl.wait('visible', timeout)
# 等待控件消失
def wait_control_disappear(self, ctrl, timeout=10):
ctrl.wait_not('visible', timeout)
# 等待控件启用
def wait_control_enable(self, ctrl, timeout=10):
ctrl.wait('enabled', timeout)
# 等待控件禁用
def wait_control_disable(self, ctrl, timeout=10):
ctrl.wait_not('enabled', timeout)
# 等待控件选中
def wait_control_check(self, ctrl, timeout=10):
ctrl.wait('checked', timeout)
# 等待控件未选中
def wait_control_uncheck(self, ctrl, timeout=10):
ctrl.wait_not('checked', timeout)
# 等待控件存在
def wait_control_exists(self, ctrl, timeout=10):
ctrl.wait('exists', timeout)
# 等待控件不存在
def wait_control_not_exists(self, ctrl, timeout=10):
ctrl.wait_not('exists', timeout)
# 等待控件文本内容
def wait_control_text(self, ctrl, text, timeout=10):
ctrl.wait('text=' + text, timeout)
# 等待控件标题
def wait_control_title(self, ctrl, title, timeout=10):
ctrl.wait('title=' + title, timeout)
# 等待控件类名
def wait_control_class_name(self, ctrl, class_name, timeout=10):
ctrl.wait('class_name=' + class_name, timeout)
# 等待窗口出现
def wait_window_appear(self, title=None, class_name=None, handle=None, timeout=10):
self.find_window(title=title, class_name=class_name, handle=handle)
self.dlg.wait('visible', timeout)
# 等待窗口消失
def wait_window_disappear(self, title=None, class_name=None, handle=None, timeout=10):
self.find_window(title=title, class_name=class_name, handle=handle)
self.dlg.wait_not('visible', timeout)
# 等待窗口启用
def wait_window_enable(self, title=None, class_name=None, handle=None, timeout=10):
self.find_window(title=title, class_name=class_name, handle=handle)
self.dlg.wait('enabled', timeout)
# 等待窗口禁用
def wait_window_disable(self, title=None, class_name=None, handle=None, timeout=10):
self.find_window(title=title, class_name=class_name, handle=handle)
self.dlg.wait_not('enabled', timeout)
# 等待窗口存在
def wait_window_exists(self, title=None, class_name=None, handle=None, timeout=10):
self.find_window(title=title, class_name=class_name, handle=handle)
self.dlg.wait('exists', timeout)
# 等待窗口不存在
def wait_window_not_exists(self, title=None, class_name=None, handle=None, timeout=10):
self.find_window(title=title, class_name=class_name, handle=handle)
self.dlg.wait_not('exists', timeout)
# 等待窗口标题
def wait_window_title(self, title, timeout=10):
self.dlg.wait('title=' + title, timeout)
# 等待窗口类名
def wait_window_class_name(self, class_name, timeout=10):
self.dlg.wait('class_name=' + class_name, timeout)
# 获取窗口矩形区域
def get_window_rect(self, title=None, class_name=None, handle=None):
self.find_window(title=title, class_name=class_name, handle=handle)
rect = self.dlg.rectangle()
return (rect.left, rect.top, rect.width(), rect.height())
# 移动窗口到指定位置
def move_window(self, title=None, class_name=None, handle=None, x=None, y=None, width=None, height=None):
self.find_window(title=title, class_name=class_name, handle=handle)
rect = self.dlg.rectangle()
if x is None:
x = rect.left
if y is None:
y = rect.top
if width is None:
width = rect.width()
if height is None:
height = rect.height()
self.dlg.move_window(x, y, width, height)
# 最大化窗口
def maximize_window(self, title=None, class_name=None, handle=None):
self.find_window(title=title, class_name=class_name, handle=handle)
self.dlg.maximize()
# 最小化窗口
def minimize_window(self, title=None, class_name=None, handle=None):
self.find_window(title=title, class_name=class_name, handle=handle)
self.dlg.minimize()
# 还原窗口
def restore_window(self, title=None, class_name=None, handle=None):
self.find_window(title=title, class_name=class_name, handle=handle)
self.dlg.restore()
# 关闭窗口
def close_window(self, title=None, class_name=None, handle=None):
self.find_window(title=title, class_name=class_name, handle=handle)
self.dlg.close()
# 截图窗口
def screenshot_window(self, title=None, class_name=None, handle=None, filename=None):
self.find_window(title=title, class_name=class_name, handle=handle)
rect = self.dlg.rectangle()
self.app.capture_as_image(RECT(rect)).save(filename)
# 截图控件
def screenshot_control(self, ctrl, filename=None):
rect = ctrl.rectangle()
self.app.capture_as_image(RECT(rect)).save(filename)
# 等待指定时间
def wait(self, seconds):
time.sleep(seconds)
# 执行命令
def execute_command(self, command):
self.app.top_window().type_keys(command + "{ENTER}")
# 执行脚本
def execute_script(self, script):
exec(script)
# 执行外部程序
def execute_program(self, path, args=None):
self.app.start(path, args)
# 获取系统菜单
def get_system_menu(self, title=None, class_name=None, handle=None):
self.find_window(title=title, class_name=class_name, handle=handle)
return self.dlg.menu()
# 获取菜单项
def get_menu_item(self, menu, path):
return menu.get_menu_path(path)
# 点击菜单项
def click_menu_item(self, menu, path):
menu.get_menu_path(path).click()
# 获取子菜单
def get_sub_menu(self, menu, path):
return menu.get_menu_path(path).submenu()
# 获取子菜单项
def get_sub_menu_item(self, menu, path, sub_path):
return menu.get_menu_path(path).submenu().get_menu_path(sub_path)
# 点击子菜单项
def click_sub_menu_item(self, menu, path, sub_path):
menu.get_menu_path(path).submenu().get_menu_path(sub_path).click()
# 获取弹出菜单
def get_popup_menu(self, title=None, class_name=None, handle=None):
self.find_window(title=title, class_name=class_name, handle=handle)
return self.dlg.popup_menu()
# 获取弹出菜单项
def get_popup_menu_item(self, menu, path):
return menu.get_menu_path(path)
# 点击弹出菜单项
def click_popup_menu_item(self, menu, path):
menu.get_menu_path(path).click()
# 获取焦点
def get_focus(self, ctrl):
ctrl.set_focus()
# 失去焦点
def lose_focus(self, ctrl):
ctrl.set_focus()
# 模拟鼠标移动
def move_mouse(self, x, y):
pywinauto.mouse.move(coords=(x, y))
# 模拟鼠标左键按下
def press_mouse_left(self, x, y):
pywinauto.mouse.press(coords=(x, y))
# 模拟鼠标左键释放
def release_mouse_left(self, x, y):
pywinauto.mouse.release(coords=(x, y))
# 模拟鼠标右键按下
def press_mouse_right(self, x, y):
pywinauto.mouse.right_press(coords=(x, y))
# 模拟鼠标右键释放
def release_mouse_right(self, x, y):
pywinauto.mouse.right_release(coords=(x, y))
# 模拟鼠标中键按下
def press_mouse_middle(self, x, y):
pywinauto.mouse.middle_press(coords=(x, y))
# 模拟鼠标中键释放
def release_mouse_middle(self, x, y):
pywinauto.mouse.middle_release(coords=(x, y))
# 模拟鼠标滚轮按下
def press_mouse_wheel(self, direction="up"):
if direction == "up":
pywinauto.mouse.wheel_up()
elif direction == "down":
pywinauto.mouse.wheel_down()
else:
raise ValueError("参数错误:不支持的滚动方向")
# 模拟鼠标滚轮释放
def release_mouse_wheel(self, direction="up"):
if direction == "up":
pywinauto.mouse.wheel_up()
elif direction == "down":
pywinauto.mouse.wheel_down()
else:
raise ValueError("参数错误:不支持的滚动方向")
# 模拟鼠标移动到控件上
def hover_control(self, ctrl):
ctrl.mouse_move()
# 模拟鼠标移动到坐标上
def hover_position(self, x, y):
pywinauto.mouse.move(coords=(x, y))
# 模拟鼠标拖拽
def drag_mouse(self, x1, y1, x2, y2):
pywinauto.mouse.drag(coords=(x1, y1), button="left", target_coords=(x2, y2))
# 模拟鼠标放置
def drop_mouse(self, x, y):
pywinauto.mouse.drop(coords=(x, y))
# 模拟鼠标拖拽并放置
def drag_drop_mouse(self, x1, y1, x2, y2):
pywinauto.mouse.drag(coords=(x1, y1), button="left", target_coords=(x2, y2))
pywinauto.mouse.drop(coords=(x2, y2))
# 模拟鼠标单击
def click_mouse(self, x, y):
pywinauto.mouse.click(coords=(x, y))
# 模拟鼠标双击
def double_click_mouse(self, x, y):
pywinauto.mouse.double_click(coords=(x, y))
# 模拟鼠标右击
def right_click_mouse(self, x, y):
pywinauto.mouse.right_click(coords=(x, y))