UI自动化测试重点思考--失败用例重跑
- 失败用例重跑
- 验证码校验
- 多个句柄跳转
- 文件上传
-
- [使用 input 元素上传文件](#使用 input 元素上传文件)
- [使用 pywinauto 上传文件](#使用 pywinauto 上传文件)
- 元素定位的难点
失败用例重跑
目的
在我们使用selenium+pytest做UI自动化的时候偶尔会遇到因为特殊情况
比如浏览器加载失败、网络波动等等导致用例运行失败(可能单独运行没
问题),对于这些场景产生的用例结果不是我们想要的,那这么可以避免
这种情况,如果对代码进行这些异常情况的处理也是一个实现方式但是过
于浪费时间和精力,此时我们就可以采用pytest框架本身支持的一种方
式,对于错误的用例进行重试,达到我们的目的。
安装第三方的库
安装 pytest-rerunfailures:首先,你需要安装 pytest-rerunfailures 插件。你可以通过 pip 来安装:
python
pip install pytest-rerunfailures
使用方法
- 配置重试次数(所有用例)
默认情况下,pytest-rerunfailures 插件会在每个失败的测试用例之后立即重试一次。如果需要,你可以通过命令行选项或配置文件来指定重试次数。例如,你可以在命令行中指定重试 3 次:
python
pytest --reruns 3 <your_test_file.py>
- 在用例上使用flaky装饰器(单个用例)
在这个示例中,test_example 测试函数被 pytest.mark.flaky 标记,并配置了重试次数为 5 次 (reruns=5),以及重试延迟时间为 5 秒 (reruns_delay=5)。
python
import pytest
@pytest.mark.flaky(reruns=5, reruns_delay=5)
def test_example():
# Your test code here
assert 1 == 2
- pytest.ini中写下reruns参数即可
在 pytest.ini 文件中,你可以通过添加 pytest-rerunfailures 插件的相关配置来实现失败用例的重跑。以下是如何配置 pytest-rerunfailures 插件的示例:
python
[pytest]
addopts = --reruns 3
验证码校验
多个句柄跳转
多窗口处理方法
这个多窗口之间跳转处理,在实际selenium自动化测试经常遇到。就是,你点击一个链接,这个链接会在一个新的tab打开,然后你接下来要查找元素在新tab打开的页面,所以这里需要用到swithTo方法。
需要获取当前浏览器多窗口句柄,然后根据判断跳转新句柄还是旧句柄
python
#(1)获取当前窗口句柄
driver.current_window_handle
#(2)获取所有窗口句柄
driver.window_handles
#(3)切换指定句柄窗口
driver.switch_to.window(handle)
#(4)关闭当前的句柄
driver.close()
#(5)关闭当前的句柄
driver.quit()
多窗口句柄实战
python
from selenium import webdriver
import time
# 启动浏览器
driver = webdriver.Chrome()
# 打开网页
driver.get("http://example.com")
# 获取当前窗口句柄
main_window_handle = driver.current_window_handle
# 点击一个链接,打开新窗口
driver.find_element_by_link_text("Open New Window").click()
# 等待新窗口打开
time.sleep(2)
# 获取所有窗口句柄
all_window_handles = driver.window_handles
# 切换到新窗口
for handle in all_window_handles:
if handle != main_window_handle:
driver.switch_to.window(handle)
break
# 在新窗口中进行操作
driver.find_element_by_id("element_id_in_new_window").click()
# 关闭新窗口
driver.close()
# 切换回主窗口
driver.switch_to.window(main_window_handle)
# 关闭浏览器
driver.quit()
文件上传
使用 input 元素上传文件
在大多数的情况下,在页面的源代码中只能找到一个input的元素,如果是在界面中可以直接看到这个元素时,当你想要上传文件的话,可以通过 selenium 的
send_keys 方法
就能完成文件的上传,在参数中传入本地文件的路径。
python
from selenium import webdriver
# 启动浏览器
driver = webdriver.Chrome()
# 打开网页
driver.get("http://example.com")
# 定位上传文件的 input 元素
upload_input = driver.find_element_by_xpath("//input[@type='file']")
# 输入文件路径
upload_input.send_keys("/path/to/your/file.txt")
# 等待上传完成
# Add any further processing here
# 关闭浏览器
driver.quit()
使用 pywinauto 上传文件
如果你的文件上传窗口是一个标准的 Windows 对话框,你可以使用
pywinauto 库
来模拟用户操作,以选择文件并上传。
python
from pywinauto import Desktop
# 启动文件上传对话框
app = Desktop(backend="uia").open(r"C:\Windows\explorer.exe")
# 定位文件上传对话框
upload_dialog = app["打开"]
# 输入文件路径
upload_dialog["Edit"].type_keys(r"C:\path\to\your\file.txt")
# 点击打开按钮
upload_dialog["打开(&O)"].click()
# 等待上传完成
# Add any further processing here
# 关闭文件上传对话框
upload_dialog.close()
# 关闭程序
app.close()
元素定位的难点
时间等待因素
经常会遇到如登录功能,其中会出现一个中间的跳转页面,如果你的代码在执行完登录之后直接进行登录成功页面的操作的时候,必然会出现定位不到元素的问题,这时候隐式和显示等待都不起作用,主要原因就是新的页面还是出现,只能使用强制等待(time.sleep(5)),才能跳过中间页面,等登录成功页面刷新出来之后再进行定位即可。解释这个现象
这个现象是因为隐式等待和显示等待都是针对页面加载的,而不是针对页面的内容变化。当你执行完登录操作后,跳转页面可能需要一定的时间来加载新的页面内容,包括 DOM 元素、JavaScript 脚本等。在这段时间内,WebDriver 可能会尝试查找登录成功页面上的元素,但由于页面尚未完全加载
,所以找不到这些元素,导致定位失败。
在这种情况下,强制等待(如 time.sleep(5))是一种简单粗暴的解决方法。它会暂停代码执行一段固定的时间,以确保页面有足够的时间来加载新的内容。等待期间,WebDriver 不会执行任何查找元素的操作,直到等待时间结束,然后继续执行后续的测试步骤。
多窗口定位异常
使用跳转打开新句柄时,多窗口定位异常的处理方法与前述类似,主要步骤包括:
1.获取所有窗口句柄,并切换到新窗口。
2.使用显示等待等待新窗口中的元素加载完成。
3.在新窗口中进行操作。
多frame嵌套导致无法定位
切换到目标 frame:使用
switch_to.frame()
方法切换到目标 frame。如果 frame 是嵌套在另一个 frame 中,需要逐层切换到目标 frame
python
# 切换到第一层嵌套的 frame
driver.switch_to.frame("frame1")
# 切换到第二层嵌套的 frame
driver.switch_to.frame("frame2")
# 在目标 frame 中定位元素并进行操作
element = driver.find_element_by_id("element_id")
窗口缩小导致元素隐藏
使用滚动条滚动到元素可见位置:如果元素由于页面大小变化而隐藏,可以使用 JavaScript 将页面滚动到元素可见位置。
python
# 滚动到元素可见位置
element = driver.find_element_by_id("element_id")
driver.execute_script("arguments[0].scrollIntoView();", element)
动态ID导致元素无法定位
使用相对定位:如果元素相对于其他元素是唯一的,可以使用相对定位的方式来定位元素,例如 XPath 或 CSS 选择器。
python
# 使用 XPath 定位
element = driver.find_element_by_xpath("//div[@class='parent_class']//input")
# 使用 CSS 选择器定位
element = driver.find_element_by_css_selector("div.parent_class input")
元素没有显示在窗口内导致定位异常
滚动到元素可见位置:使用 JavaScript 将页面滚动到元素可见的位置。
python
element = driver.find_element_by_id("element_id")
driver.execute_script("arguments[0].scrollIntoView();", element)
xpath描述错误(开发修改页面布局之后容易失效)
FirePath 是一个 Firefox 插件,可以帮助开发人员和测试人员快速生成和调试 XPath 和 CSS 选择器。通过使用 FirePath,可以轻松地验证和优化 XPath 表达式,从而解决定位元素时遇到的问题。
不可见元素
使用 ActionChains:如果需要对不可见元素执行鼠标操作(例如鼠标悬停),可以使用 ActionChains 类。
python
from selenium.webdriver.common.action_chains import ActionChains
# 定位不可见元素
element = driver.find_element_by_id("element_id")
# 创建 ActionChains 对象
actions = ActionChains(driver)
# 对元素执行操作
actions.move_to_element(element).perform()