Appium: Windows系统桌面应用自动化测试(三) 【脚本操作】

Appium: Windows系统桌面应用自动化测试 【脚本操作】

  • 一、常用操作
    • 1、添加被测程序
      • 1.1示例一:通过程序路径指定应用程序,例如指定写字板程序路径。
      • 1.2示例二:通过程序ID指定应用程序,例如指定计算器ID。
      • 1.3 应用程序ID(AppId)
    • 2、启动参数
    • 3、元素定位
    • 4、窗口操作
    • 5、Root窗口
      • 5.1、根据示例描述编写如下代码:
    • 6、切换新窗口
      • 6.1、实现代码如下:
    • 7、文件操作
    • 8、切换输入法
  • 二、脚本实战

一、常用操作

WinApp自动化测试脚本是使用Appium客户端完成开发的,一些基本的操作方法可参考Appium的API。本节主要介绍WinApp在脚本编写时与移动端App脚本开发上不同的地方。

1、添加被测程序

设置启动程序是在启动参数中添加key为app的参数,值可以是应用程序的ID,也可以是应用程序的完整路径。

1.1示例一:通过程序路径指定应用程序,例如指定写字板程序路径。

desired_caps = {}
desired_caps['app'] = r"C:\Program Files\Windows NT\Accessories\wordpad.exe"

1.2示例二:通过程序ID指定应用程序,例如指定计算器ID。

desired_caps = {}
desired_caps["app"] = "Microsoft.WindowsCalculator_8wekyb3d8bbwe!App"

1.3 应用程序ID(AppId)

应用程序ID(AppId)是应用程序用户模型 ID (AppUserModelID),简称 AUMID。在Windows PowerShell中输入命令Get-StartApps便可看到当前用户安装的所有应用名称和 AUMID

PS C:\Users\pc> Get-StartAppsName                                  AppID
----                                  -----
Python 3.9 (64-bit)                   C:\Users\pc\AppData\Local\Programs\Python\Python39\python.exe
Google Chrome                         Chrome.JOYETIBVDRAA6DX32OHIYXNRNI
uc-devtools                           com.squirrel.uc-devtools.uc-devtools
SakuraCat                             com.tidalab.client
微信                                  D:\Program Files (x86)\Tencent\WeChat\WeChat.exe
Internet Explorer                     Microsoft.InternetExplorer.Default
闹钟和时钟                            Microsoft.WindowsAlarms_8wekyb3d8bbwe!App
计算器                                Microsoft.WindowsCalculator_8wekyb3d8bbwe!App***************************************************
*****************   省略部分内容    *****************
***************************************************
手机连接                              Microsoft.YourPhone_8wekyb3d8bbwe!App
Microsoft Store                       Microsoft.WindowsStore_8wekyb3d8bbwe!App
天气                                  Microsoft.BingWeather_8wekyb3d8bbwe!App
Solitaire Collection                  Microsoft.MicrosoftSolitaireCollection_8wekyb3d8bbwe!AppPS C:\Users\pc>

从上内容可以看到已经安装的所有应用AUMID,例如闹钟和时钟应用的AUMID就是Microsoft.WindowsAlarms_8wekyb3d8bbwe!App。

2、启动参数

WinApp自动化测试中,在创建Windows应用程序驱动会话时,可以使用的启动参数是有限的
在这里插入图片描述在这里插入图片描述
appTopLevelWindow值是窗口句柄,用于设置应用程序顶层窗口,如图
在这里插入图片描述

UIA树中就可以知道打开的写字板程序的顶层窗口为【窗格 ‘文档-写字板’】。appTopLevelWindow值是一个16进制,可以通过许多方法获取,
例如

  • hex(win32gui.FindWindow()
  • hex(int(driver.find_element(By.XX,‘XX’).get_attribute(‘NativeWindowHandle’)))

3、元素定位

WinAppDriver支持许多方式查找元素。如表7-2列出了支持的定位方式及在Accessibility Insights For Windows工具和Inspect.exe工具中显示的对应元素属性。
在这里插入图片描述
在这里插入图片描述//Button[0]

4、窗口操作

我们可以使用Selenium提供的一些API操作WinApp窗口,例如窗口最大化、设置窗口位置、设置窗口大小、关闭窗口等。

一些Selenium提供的API同样适用于WinApp窗口的方法。
在这里插入图片描述
在这里插入图片描述

5、Root窗口

如果在启动参数中app参数的值给定的是一个具体的应用程序ID或完整的路径,那么启动会话后appTopLevelWindow默认就是该应用的根节点。

例如指定的应用程序是写字板,那么启动后会话的appTopLevelWindow默认就是【窗格 ‘文档-写字板’】,后续操作都会将【窗格 ‘文档-写字板’】作为开始节点,例如通过XPATH方式查找元素,就会从该节点开始查找,窗口切换时窗口查找也是查找该节点下的窗口。

但是从图
在这里插入图片描述

UIA树中可以看到,实则还有一个节点【窗格 ‘桌面 1’】,即Root窗口,此节点才是Windows桌面最顶层的窗口,此节点的子节点才是应用程序的根节点。

如果将启动参数app的值设置为‘Root’,那么启动会话后appTopLevelWindow就是Root窗口,表示我们的系统桌面。例如将启动参数app的值设置为‘Root’,然后依次桌面应用程序控制面板和此电脑。

使用Accessibility Insights For Windows工具查看桌面上的元素,如图
在这里插入图片描述

所示。从图中可以知道,控制面板和此电脑都有Name属性,因此可以使用NAME定位方式定位元素。

5.1、根据示例描述编写如下代码:


# window_root.py
import time
from appium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains# 添加启动参数
desired_caps = {}
desired_caps['app'] = "Root"
# 客户端连接 Server,启动 Session 会话
driver = webdriver.Remote(command_executor='http://127.0.0.1:4723', desired_capabilities=desired_caps)
time.sleep(3)control_panel_element = driver.find_element(By.NAME, '控制面板')
# 双击桌面上的控制面板
ActionChains(driver).double_click(control_panel_element).perform()
time.sleep(1)my_computer_element = driver.find_element(By.NAME, '此电脑')
# 双击桌面上的此电脑
ActionChains(driver).double_click(my_computer_element).perform()
time.sleep(1)# 关闭会话
driver.quit()

运行脚本后,会观察到鼠标先双击桌面上的控制面板并打开,然后双击桌面上的回收站并打开。

注意:此操作是点击桌面上的应用程序,运行脚本时不能有窗口遮挡控制面板和回收站图标,否则会点击到对应位置最上面的窗口上。另一种解决方法是在点击桌面上的应用程序之前,通过脚本先发送快捷键 Win+d,将桌面完全显示出来。

6、切换新窗口

窗口切换与浏览器中的窗口切换相同,如果想操作新窗口,就需要先切换进新窗口。Appium能识别到的窗口是appTopLevelWindow窗口的子窗口,如果是切换appTopLevelWindow窗口的子窗口,则可以通过window_handles、current_window_handle、switch_to.window(window_name)三个API完成切换。

  • window_handles:获取所有的appTopLevelWindow下的窗口句柄。
  • current_window_handle:获得当前窗口句柄。
  • switch_to.window(window_name):切换窗口,参数window_name为窗口句柄。

提示:WinAppDriver、Appium、Selenium三者之间的兼容性处理并不是很好,所以句柄的获取会存在很多问题,因此直接使用window_handles获取窗口句柄会有些吃力的。但相信在不久的将来,该问题会得到改善。

因此,如果打开了一个新窗口,而新窗口不在当前会话的appTopLevelWindow节点下,我们就需要根据新窗口句柄启动一个新的会话,开启的新会话就将会话绑定到新窗口上。例如打开写字板程序后,点击插入绘图打开画图窗口,然后关闭画图窗口,最后关闭写字板。

6.1、实现代码如下:

# switch_window.py
import time
import win32gui
from appium import webdriver
from selenium.webdriver.common.by import By# 添加启动参数
desired_caps = {}
desired_caps['app'] = r"C:\Program Files\Windows NT\Accessories\wordpad.exe"
# 客户端连接 Server,启动 Session 会话
driver = webdriver.Remote(command_executor='http://127.0.0.1:4723', desired_capabilities=desired_caps)
time.sleep(1)
driver.set_window_size(1000, 600)# 打开绘图窗口
driver.find_element(by=By.NAME, value="绘图").click()
time.sleep(1)# 获取画图窗口句柄
paint_handle = win32gui.FindWindow(None, '位图图像 在 文档 中 - 画图')
# 配置启动参数,并且启动一个新会话
paint_session = webdriver.Remote(command_executor='http://127.0.0.1:4723',desired_capabilities={"appTopLevelWindow": hex(paint_handle)})# 点击画图窗口中的 关闭 按钮
paint_session.find_element(by=By.NAME, value="关闭").click()
# 关闭会话
paint_session.quit()# 点击写字板窗口中的 关闭 按钮
driver.close()
time.sleep(1)
driver.find_element(by=By.NAME, value="不保存(N)").click()
# 关闭会话
driver.quit()

7、文件操作

WinApp自动化上使用代码实现文件上传、文件下载、文件保存或文件另存为都是非常简单的,操作也是相同的,因为都是操作Windows系统应用程序上的窗口,我们只需要根据行为进行元素定位,元素操作即可。下面我们以文件上传为例讲解代码的实现。

由于文件上传的操作步骤都是一致的,因此可以将上传文件场景进行封装,然后调用。例如在写字板中上传图片,当打开上传图片窗口后,先定位文件路径输入框元素并且输入文件路径 ,然后点击打开按钮即可将文件上传到写字板中。实现代码如下:

# upload_file.py
import time
from appium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECdef upload_file(driver, file):# 定位文件路径输入框并输入文件路径file_input = WebDriverWait(driver, 60, 0.5).until(EC.visibility_of_element_located((By.XPATH, "//Edit[@Name='文件名(N):']")))file_input.send_keys(file)# 定位打开按钮并点击file_open_btn = WebDriverWait(driver, 60, 0.5).until(EC.visibility_of_element_located((By.XPATH, "//Button[@Name='打开(O)']")))file_open_btn.click()# 添加启动参数
desired_caps = {}
desired_caps['app'] = r"C:\Program Files\Windows NT\Accessories\wordpad.exe"
# 客户端连接 Server,启动 Session 会话
driver = webdriver.Remote(command_executor='http://127.0.0.1:4723', desired_capabilities=desired_caps)
time.sleep(1)
driver.set_window_size(1000, 600)
time.sleep(1)
# 点击图片,上传文件
(driver.find_elements(by=By.XPATH, value="//Group"))[4].click()# 文件上传
upload_file(driver, r"D:\ty.png")# 关闭程序和会话
driver.close()
driver.find_element(by=By.NAME, value="不保存(N)").click()
driver.quit()

注意:运行上面脚本时输入法需要切换到英文,如果是中文输入法,文件路径输入的结果会与预期不一致。

运行上面脚本,可以观察到先启动写字板程序,然后点击了图片图标打开了上传文件窗口,接着文件上传输入框中输入了文件路径,并且点击了打开按钮,此时可以看到写字板中已经成功插入了图片,最后关闭写字板程序,会话关闭。
在这里插入图片描述

8、切换输入法

自动化脚本在输入内容时会受到输入法的影响,例如我们原本想输入内容“D2”,但由于输入法是中文,因此得到的内容将是输入拼音D后列出的第二个汉字,完全与期望相差甚远。

我们在Windows系统上打开一个新程序后,新程序的输入法会是默认语言,例如输入法默认是中文,在Word文件中切换到了英文,当打开记事本后输入法会是默认的中文,当再切回到Word文件时输入法也会跟着切换回英文。

因此我们可以通过设置输入法的默认值达到预期的结果,操作步骤是:Windows10系统下右键点击右下角输入法,然后依次选择【设置】>>【常规】,在默认模式下将【选择输入法默认模式】下拉框选择为预取语言即可,如图标记处,就是将输入法的默认值设置为了英文。

在这里插入图片描述
但是项目自动化中我们还是会遇到需要切换输入法的场景。此时我们可以通过输入法切换的快捷键快速实现。例如笔者的默认输入法是中文,中英文切换的快捷键是Shift,改造上面代码中的文件上传函数,在文件路径输入框输入内容前先发送一个Shift快捷键,使输入法切换到英文,然后再输入文件路径。改造后的文件上传函数如下:

def upload_file(driver, file):# 定位文件路径输入框并输入文件路径file_input = WebDriverWait(driver, 60, 0.5).until(EC.presence_of_element_located((By.XPATH, "//Edit[@Name='文件名(N):']")))# 输入框输入 Shift,由中文切换到英文file_input.send_keys(Keys.SHIFT)file_input.send_keys(file)# 定位打开按钮并点击file_open_btn = WebDriverWait(driver, 60, 0.5).until(EC.presence_of_element_located((By.XPATH, "//Button[@Name='打开(O)']")))file_open_btn.click()

提示:Windows10系统下设置输入法切换的快捷键步骤是:右键点击右下角输入法,然后依次选择【设置】>>【按键】,即可在页面模式切换下找到【中/英文模式切换】、【全/半角切换】等快捷键设置项。

二、脚本实战

以操作 PC 端的微信为例,聊聊自动化的常见步骤

  • 首先,我们在本机打开 WinAppDriver 服务,让它在后台运行
    然后,我们使用 Python 编写自动化脚本
    通过 ip 地址、端口号及 PC 版微信的绝对路径,使用 Appium 打开微信
import time, os
from appium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys
from time import sleepclass Auto():def open_weixin(self, host='localhost', port=4723):# 打开WinAppDriver服务# 注意:如果手动开启,则可以注释掉# os.system(r'start "" /d "C:\Program Files\Windows Application Driver\"  "WinAppDriver.exe"')# 配置信息# 包含:平台名、系统、应用程序绝对路径desired_caps = {'platformName': 'Windows', 'deviceName': 'WindowsPC','app': r"D:\Program Files (x86)\Tencent\WeChat\WeChat.exe"}try:# 连接WinAppDriver服务,打开目标软件self.driver = webdriver.Remote('http://{}:{}'.format(host, port), desired_caps)except Exception as e:raise AssertionError(e)
  • 接着,通过「 组件元素识别工具 」拿到界面元素的属性值,执行常见的点击、移动、滑动等操作
    比如:点击「 文件传输助手 」,发送一条信息
# 给文件传输助手发送一条信息
def send_msg(self, element_name, msg):""":param element_name:元素name值:param msg::return:"""# 通过name属性,找到目标元素chat_element = self.weixin_driver.find_element_by_name(target_name)# 点击元素,进入聊天界面chat_element.click()# 找到输入框,并输入self.weixin_driver.find_element_by_name("输入").send_keys(msg)# 点击右下角的发送,发送消息出去self.weixin_driver.find_element_by_name("发送(S)").click()
  • 需要注意的是,如果涉及界面的滑动,可以使用「 ActionChains 」移动鼠标,然后使用 win32api 和 win32con 模拟屏幕滑动即可
import win32api
import win32con
from appium import webdriver
from selenium.webdriver import ActionChains# 模拟屏幕滑动
# 1、移动到某个元素区域
ActionChains(self.weixin_driver).move_to_element(self.weixin_driver.find_element_by_name("element_name")).perform()# 2、滑动界面
# 比如,向上滚动,模拟滑动
win32api.mouse_event(win32con.MOUSEEVENTF_WHEEL, 0, 0, -500)
  • 完成自动化操作后,就可以主动释放资源、关闭 WinAppDriver 服务
# 释放资源及关闭服务
def tearDownFunc(self):print("准备退出")sleep(2)# 1、释放资源self.weixin_driver.quit()# 2、关闭WinAppDriver应用程序os.system(' @taskkill /f /im WinAppDriver.exe')
  • 在实际使用过程中,可能会遇到复杂的桌面应用程序,这时我们可以通过打印驱动对象的「 page_source」元素控制树值,以此来帮助我们进行快速定位元素,进而完善自动化脚本

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/20760.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

尚硅谷Linux学习笔记

文章目录 1. Linux概述2. Linux目录结构3. Linux操作命令3.1 vim编辑命令3.1.1 一般模式3.1.2 编辑模式3.1.3 指令模式 3.2 网络相关命令3.3 系统管理3.4 帮助命令3.4.1 man 获得帮助信息3.4.2 help 获得 shell 内置命令的帮助信息3.4.3 常用快捷键 3.5 文件目录类3.5.1 pwd、e…

「提高你的CSS技能」:15个重要的CSS属性详解

这篇文章介绍了15个重要的CSS属性,旨在提高读者的CSS知识和技能。文章以清晰的方式解释了每个属性的作用和用法,并提供了相应的示例代码。通过这篇文章,读者可以了解到一些有趣且实用的CSS属性。 1:in-range 和:out-of-range 伪类 CSS的:in…

基于51单片机+SHT30设计的环境温度与湿度检测设备(IIC模拟时序)

一、项目介绍 当前文章介绍基于51单片机和SHT30传感器设计的环境温度与湿度检测设备。设备采用IIC模拟时序通信协议,能够实时监测环境的温度和湿度,并将数据通过LCD显示屏显示出来;可以广泛应用于室内环境监测、气象观测、农业温室监测等领域…

音视频开发实战03-FFmpeg命令行工具移植

一,背景 作为一个音视频开发者,在日常工作中经常会使用ffmpeg 命令来做很多事比如转码ffmpeg -y -i test.mov -g 150 -s 1280x720 -codec libx265 -r 25 test_h265.mp4 ,水平翻转视频:ffmpeg -i src.mp4 -vf hflip -acodec copy …

常用的访问控制权限模型DAC RBAC

常用的访问控制权限模型DAC RBAC 文章目录 常用的访问控制权限模型DAC RBACLinux 自主访问控制与强制访问控制术语概念存取访问控制 Access Control自主访问控制强制访问控制 基于角色的权限控制模型RBAC模型管理方法RBAC0的管理命令RBAC0的系统支持方法RBAC0的高级审查持方法 …

Table Recognition Metric: 表格识别算法评测工具包及相关评测基准数据集

Table Recognition Metric 该库用于计算TEDS指标,用来评测表格识别算法效果。可与魔搭-表格识别测试集配套使用。TEDS计算代码参考:PaddleOCR 和 DAVAR-Lab-OCR 使用说明: Install package by pypi.pip install table_recognition_metricRu…

【SCI一区】互联燃料电池混合动力汽车通过信号交叉口的生态驾驶双层凸优化(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

支付宝接入

支付宝接入 python-alipay-sdk pycryptodome一、电脑网站支付 1.1 获取支付宝密钥 沙箱网址 1.APPID 2.应用私钥 3.支付宝公钥1.2 存放密钥 在与 settings.py 的同级目录下创建 pem 文件夹pem 文件夹下创建 app_private_key.pem 和 alipay_public_key.pem app_private_key…

python pytest脚本执行工具

pytest脚本执行工具 支持获取当前路径下所有.py脚本 添加多个脚本,一起执行 import tkinter as tk from tkinter import filedialog import subprocess import os from datetime import datetimedef select_script():script_path filedialog.askopenfilename(fil…

11. 利用Tomcat服务器配置HTTPS双向认定

文章目录 Tomcat配置HTTPS1.为服务器生成证书2.为客户端生成证书3.让服务器信任客户端证书4.将该文件导入到服务器的证书库,添加为一个信任证书使用命令如下:5.查看证书库6.让客户端信任服务器证书7.配置tomcat8.验证 Tomcat配置HTTPS 1.启动cmd控制台&…

使用Pytorch加载预训练模型及修改网络结构

Pytorch有自带的训练好的AlexNet、VGG、ResNet等网络架构。详见官网 1.加载预训练模型 import torch import torchvision import torch.nn as nn import torch.optim as optim import torch.nn.functional as F import torchvision.transforms as transforms import torchvis…

逆波兰式是什么?

1. 逆波兰式是什么? 逆波兰式,也称逆波兰记法(Reverse Polish Notation,缩写为RPN),是一种在数学和计算机科学中用于表示算术表达式的方法。它的特点是操作符在操作数的后面,不需要括号来改变运…