Python 测开28期 - WL - 学习笔记 - 浏览器控制、控件定位、等待方式

浏览器控制

  • 模拟功能测试中对浏览器的操作
关键字 操作 使用场景
get 打开浏览器 web自动化测试第一步
refresh 浏览器刷新 模拟浏览器刷新
back 浏览器回退 模拟回退步骤
maximize_window 最大化浏览器 模拟浏览器最大化
minimize_window 最小化浏览器 模拟浏览器最小化
  • 打开网页
    • get 方法打开浏览器
    • 此方法必须传入参数:目标网站的url
  • 刷新
    • driver.refresh()
  • 回退
    • driver.back()
  • 最大化
    • driver.maximize_window()
  • 最小化
    • driver.minimize_window()
  • 示例代码
import time
from selenium import webdriver
def open_web():
    driver = webdriver.Chrome()
    driver.get("https://www.baidu.com/")
    time.sleep(2)
    driver.refresh()
    time.sleep(2)
    driver.get("https://www.ceshiren.com/")
    time.sleep(2)
    driver.back()
    time.sleep(2)
    driver.maximize_window()
    time.sleep(2)
    driver.minimize_window()
    time.sleep(2)
    driver.close()

if __name__ == '__main__':
    open_web()

常见控件定位方法

HTMl 铺垫

<!DOCTYPE html>
<html lang="en">
<head>    
    <meta charset="UTF-8">    
    <title>测试人论坛</title>
</head>
<body>    
    <a href="https://ceshiren.com/" class="link">链接</a>    
    <span id="spans" style="line-height: 20px;">跳转</span>
</body>
</html>

selenium 八大定位方式

方式 描述
class name class 属性对应的值
css selector(重点) css 表达式
id(重点 id 属性对应的值
name(重点) name 属性对应的值
link text 查找其可见文本与搜索值匹配的锚元素。
partial link text 查找其可见文本包含搜索值的锚元素。如果多个元素匹配,则只会选择第一个元素
tag name 标签名称
xpath(重点) xpath 表达式
方式
  • 格式一
# 格式
driver.find_element_by_定位方式(定位元素)
driver.find_element(By.定位方式, 定位元素)
  • 格式二
# 官方建议使用的方式
driver.find_element_by_id("su")
driver.find_element(By.ID, "su")

常用定位方式练习

  • 通过 id 定位
    • 格式:driver.find_element(By.ID, “ID属性对应的值”)
  • 通过 name 定位
    • 格式:driver.find_element(By.NAME, “name属性对应的值”)
    • 疑问:name的选择值好像不能太深入,否则会报错
driver.get("https://vip.ceshiren.com/#/ui_study/frame")


web_name = driver.find_element(By.NAME, "el-table_1_column_2")

# 错误
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[name="el-table_1_column_2"]"}
  (Session info: chrome=121.0.6129.0)
  • 通过 css 选择器定位
    • 格式:driver.find_element(By.CSS_SELECTOR, “css表达式”)
    • 复制绝对定位
    • 编写 sc selector 表达式
    • 疑问:有个别元素定位会报错:
driver.get("https://vip.ceshiren.com/#/ui_study/frame")


web_css2 = driver.find_element_by_css_selector("head > script:nth-child(42)")
#报错
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"head > script:nth-child(42)"}
  (Session info: chrome=121.0.6129.0)
  • 通过 xpath 定位
    • 格式:driver.find_element(By.XPATH, “xpath表达式”)
    • 复制绝对定位
    • 编写 xpath 表达式
    • **疑问:有个别元素定位会报错 **
driver.get("https://vip.ceshiren.com/#/ui_study/frame")

web_xpath = driver.find_element(By.XPATH, 
'//*[@id="app"]/div/div[1]/div/div[3]/table/tbody/tr[4]/td[2]/div')
#报错
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[@id="app"]/div/div[1]/div/div[3]/table/tbody/tr[4]/td[2]/div"}
  (Session info: chrome=121.0.6129.0)
  • 通过连接文本定位 link
    • 格式:driver.find_element(By.LINK_TEXT, “文本内容”)
    • 注意:
        1. 元素一定是a标签
        1. 输入的元素为标签内的文本

强制等待与隐式等待

  • 为什么要添加等待
    • 避免页面未渲染完成后操作,导致的报错

强制(直接)等待

  • 解决方案:在报错的元素操作之前添加等待
  • 原理:强制等待,线程休眠一定实践
  • 演练环境:https://vip.ceshiren.com/
  • time.sleep(3)
  • 强制等待的问题
      1. 不确定页面的加载时间,可能会因为等待时间过长,而影响用例的执行效率
      1. 不确定页面的加载时间,可能会因为等待时间过短,而导致代码依然会报错

隐式等待

  • 问题:难以确定元素加载的具体等待时间
  • 解决方案:针对于寻找元素的这个动作,使用隐式等待添加配置
  • 演练环境:https://vip.ceshiren.com/
  • 原理:设置一个等待时间,轮询查找(默认0.5s)元素是否出现,如果没有出现就抛出异常
  • driver.implicitly_wait(3)
driver.implicitly_wait(3)
driver.find_element(By.XPATH, "xxxxxx")
  • 注意:
    • 在代码一开始运行的时候就添加隐式等待的配置,
    • 此设置是全局生效的,
    • 在所有的find_element动作之前就执行此代码
  • 隐式等待无法解决的问题
    • 元素可以找到,使用点击等操作,出现报错
    • 原因:
      • 页面元素加载是异步加载过程,通常 html 会先加载完成,js、css其后
      • 元素存在与否是由HTML决定,元素的交互是由css或js决定
      • 隐式等待只关注元素能不能找到,不关注元素能否点击或进行其他交互
    • 解决方案:使用显式等待

显式等待

  • 示例:WebDriverWait(driver实例,最长等待时间,轮询时间).until(结束条件)、
  • 原理:在最长等待时间内,轮询,是否满足条件
  • 演练环境:霍格沃兹测试开发
  • 注意:在初级时期,先关注使用
  • 问题:元素已经找到,但是不能实现点击效果
  • 在操作前增加:WebDriverWait(driver, 10).until(expected_conditions.element_to_be_clickable((By.ID, “id的参数”)))
  • 注意:
    • 第一个参数是driver,第二个参数是最长等待时间,until方法内需要结合调用的方法
    • expected_conditions的参数传入的都是一个元组
WebDriverWait(driver, 10).until(expected_conditions.element_to_be_clickable((By.ID, "success_btn")))

driver.find_element(By.ID, "success_btn")

总结

类型 使用的方式 原理 适用场景
直接等待 time.sleep(等待时长) 强制线程等待 调试代码,临时性添加
隐式等待 driver.implicitly_wait(等待时长) 在时间范围内,轮询查找元素 解决找不到元素问题,无法解决元素交互问题
显式等待 WebDriverWait(driver实例, 最长等待时间, 轮询时间).until(结束条件) 设定特定的等待条件,轮询操作 解决特定条件下的等待问题,比如点击等交互性行为

常见控件交互方法

元素操作

  • 点击(.click())、输入(.send_keys(“xxxx”))、清空(.clear())
    • 点击百度搜索框
    • 输入”霍格沃兹测试开发“
    • 清空搜索框中信息
    • 演练地址:https://www.baidu.com/
# 点击百度搜索框
driver.find_element(By.ID, "kw").click()
# 输入”霍格沃兹测试开发“
driver.find_element(By.ID, "kw").send_keys("霍格沃兹测试开发")
# 清空搜索框中信息
driver.find_element(By.ID, "kw").clear()

获取元素属性信息

  • 原因:定位到元素后,获取元素的文本信息,属性信息等
  • 目的:根据这些信息进行断言或者调试
  • 演练地址:霍格沃兹测试开发
  • 获取元素属性:.get_attribute(“class”)
  • 获取元素文本:.text
web_id = driver.find_element(By.ID, "locate_id")
# 获取此元素的文本信息,不是所有元素都有文本信息的
id_text= web_id.text
# 获取此元素的 class 属性信息
res = web_id.get_attribute("class")