WinApp自动化测试之脚本常规操作

前篇文章中,我们简单介绍WinApp Driver工具,今天我们来讲讲WinApp自动化测试脚本常规操作。 

常用操作

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

添加被测程序

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

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

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

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

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

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

PS C:\Users\pc> Get-StartApps

Name                                  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!App


PS C:\Users\pc>

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

启动参数

WinApp自动化测试中,在创建Windows应用程序驱动会话时,可以使用的启动参数是有限的,可以使用的启动参数如表7-1。

表7-1 WinApp启动参数

appTopLevelWindow值是窗口句柄,用于设置应用程序顶层窗口,如图7-8的UIA树中就可以知道打开的写字板程序的顶层窗口为【窗格 '文档-写字板'】。appTopLevelWindow值是一个16进制,可以通过许多方法获取,例如hex(win32gui.FindWindow())、hex(int(driver.find_element(By.XX, 'XX').get_attribute('NativeWindowHandle')))。

元素定位

WinAppDriver支持许多方式查找元素。如表7-2列出了支持的定位方式及在Accessibility Insights For Windows工具和Inspect.exe工具中显示的对应元素属性。

表7-2 WinApp 元素定位

窗口操作

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

表7-3列举了一些Selenium提供的API同样适用于WinApp窗口的方法。

表7-3 WinApp 窗口操作API

使用Root窗口

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

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

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

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

使用Accessibility Insights For Windows工具查看桌面上的元素,如图7-9所示。从图中可以知道,控制面板和此电脑都有Name属性,因此可以使用NAME定位方式定位元素。

图 7-9 查看桌面元素

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

# 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,将桌面完全显示出来。

切换新窗口

窗口切换与浏览器中的窗口切换相同,如果想操作新窗口,就需要先切换进新窗口。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节点下,我们就需要根据新窗口句柄启动一个新的会话,开启的新会话就将会话绑定到新窗口上。例如打开写字板程序后,点击插入绘图打开画图窗口,然后关闭画图窗口,最后关闭写字板。

实现代码如下:

# 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()

运行上面脚本会观察到,首先启动写字板程序,然后点击写字板中的绘图图标打开画图工具。紧接着画图工具关闭,关闭写字板时提示“是否保存”,并点击了不保存按钮,关闭了写字板。

文件操作

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 EC


def 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()

注意:运行上面脚本时输入法需要切换到英文,如果是中文输入法,文件路径输入的结果会与预期不一致。关于输入法切换操作请阅读7.3.4.7小节。

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

图 7-10 文件上传

切换输入法

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

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

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

图 7-11 设置输入法的默认值

但是项目自动化中我们还是会遇到需要切换输入法的场景。此时我们可以通过输入法切换的快捷键快速实现。例如笔者的默认输入法是中文,中英文切换的快捷键是Shift,改造7.3.7小节代码中的文件上传函数,在文件路径输入框输入内容前先发送一个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系统下设置输入法切换的快捷键步骤是:右键点击右下角输入法,然后依次选择【设置】>>【按键】,即可在页面模式切换下找到【中/英文模式切换】、【全/半角切换】等快捷键设置项。

最后: 为了回馈铁杆粉丝们,我给大家整理了完整的软件测试视频学习教程,朋友们如果需要可以自行免费领取【保证100%免费】

在这里插 入图片描述

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/wx17343624830/article/details/131611109