Selenium UI自动化测试中元素定位不到的原因和解决方法汇总

1、总览

原因解决方法
没有打开正确的网址填写正确的网址
定位器选择错误选择合适的定位器
定位表达式错误简单粗暴:F12 copy或手写定位调试
元素嵌套在iframe中1,切换到iframe中:driver.switch_to.frame(’ iframe的id或name值 ');2,再进行元素定位
元素在新窗口中1,获取打开的多个窗口句柄:handles = driver.window_handles;2,切换到新窗口中: driver.switch_to.window(handles[-1])
页面元素没有及时加载1,加等待,不要加的太少,加10s,如果10秒还找不到说明不是因为页面加载导致的元素找不到;2,确定是页面元素没有及时加载原因后,可以使用以下三种等待方式,详见1.2
页面元素不可见或不可点击1,使用JavaScript实现元素定位和动作执行;2,使用鼠标事件ActionChains来操作;3,如果是被伪元素遮挡了原本的元素,可以直接定位到伪元素上进行点击操作 。详见1.3
页面元素是动态的1.根据其他静态属性定位;2.根据元素属性值模糊匹配定位。 详见1.4
脚本流程与实际不符调整脚本以符合实际业务流程

2、元素定位不到的原因之【页面元素没有及时加载】

问题定位思路:

  1. 加等待,不要加的太少,加10s,如果10秒还找不到说明不是因为页面加载导致的元素找不到
  2. 确定是页面元素没有及时加载原因后,可以使用以下三种等待方式
    (1)调试代码使用强制等待:sleep(10) ;
    (2)作用于全局使用隐式等待:driver.implicitly_wait(10)
    隐式等待一般在实例化dirver之后就设置,在服务端等待,作用于全局,也就是在driver的整个生命周期中生效。隐式等待是动态的查找所有元素,默认每隔0.5s轮询一次(也可以手动设置间隔时间),要查找的元素未加载完就继续等待,如果要查找的元素在规定的timeout时间内提前加载完,则结束等待,执行下一步操作;如果要查找的元素在规定的timeout时间内没有加载完,则会抛出异常。
    (3)提升用例执行效率使用显式等待
    显式等待在客户端等待,作用于指定元素,也就是只有在写了显式等待的语句中生效。显式等待也是动态的查找元素,要查找的元素未加载完就继续等待,如果要查找的元素在规定的timeout时间内提前加载完,则结束等待,执行下一步操作;如果要查找的元素在规定的timeout时间内没有加载完,则会抛出异常。需要用到两个类:WebDriverWait 和 expected_conditions

为什么要使用显式等待?

先来了解一下一般html页面上元素的呈现:

  • title出现 首先出现title
  • dom树出现 存在presence,但还不完整
  • css出现 可见visibility
  • js出现,js特效执行 可点击clickable

html文档是自上而下进行加载的,有些js通过异步加载的方式来完成js的加载
样式表下载完成之后会跟之前的样式表一起进行解析,会对之前的元素重新渲染

基于以上原理,我们知道,我们看到元素已经显示出来了,但是元素的某些属性可能还没有加载完全,比如元素是否是可见visibility、元素是否是可点击clickable,如果用隐式等待只能判断元素是否在dom树中出现,它无法判断元素是否可见,元素是否可点击,因此我们需要使用显式等待

显式等待可以处理隐式等待无法解决的一些问题,比如:上传文件(可以设置长一点),文件上传需要设置20s以上,但是如果设置隐式等待,它会在每个find方法都等这么长时间,一旦发现没有找到元素,就会等20s以后才抛出异常,影响case的执行效率,这时候就需要用显式等待,显式等待可以设置的长一点

设置显式等待的两种方法:

方法1:使用selenium自带的WebDriverWait 和 expected_conditions类,expected_conditions里面有很多定义好的判断条件供until使用
示例:

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

locator = (By.XPATH, '//*[@id=”current_price“]')
WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(locator))

方法2:使用lambda表达式
示例:

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By

locator = (By.XPATH, '//*[@id=”current_price“]')
ele = WebDriverWait(self.driver, 20).until(lambda x: x.find_element(*locator))

3、元素定位不到的原因之【页面元素不可见或不可点击】

此处所说的【页面元素不可见或不可点击】的前提条件是:元素已经加载完全了!
如果页面元素还没加载完全,导致的不可见或不可点击,我们可以通过上面1.2的显式等待方法来处理

有一种情况是:页面元素明明已经加载完全了,也定位到了,但是就是执行无效,比如点击无效等,我们又该如何处理呢?

接下来我们就以testerhome.com (https://testerhome.com/account/sign_in)的登录页面的记住密码勾选框为例
问题:直接定位元素后用.click()方法会报错:

self.driver.find_element_by_xpath('//*[@id="user_remember_me"]').click()

报错信息如下:
在这里插入图片描述
分析报错信息:
定位表达式id="user_remember_me"确实是定位到了目标元素,但是报错提示:该元素:id="user_remember_me"不可点击,而其他元素:class="custom-control-label"却被接受点击了
在这里插入图片描述
再来看看页面源码:
在这里插入图片描述
既然是因为元素不可点击导致的问题,那自然也有对应的解决办法,以下列出了可行方案,可供参考
在这里插入图片描述

4、元素定位不到的原因之【页面元素是动态的】

怎么判断元素是否是动态?

  1. 首先应先确定时间等待没问题、且没有打开新页面、没有alert、没有frame,元素可见或可点击

  2. 此时最有可能的原因就是元素是动态的,元素动态有分两种:
    a.元素的属性是动态的
    可以尝试刷新一下网页查看该元素前后有没有变化,如果属性值改变了,即是动态属性了,较为常见的是元素的id属性,或class属性里有拼接一串数字的,就很有可能是动态元素了,如下图:
    在这里插入图片描述
    b.元素的位置是动态的
    有些元素是因为某些框架技术自动生成的动态元素

    比如下图中【添加收货地址】按钮,
    在这里插入图片描述
    未添加任何地址前,该元素是在最右侧://*[@id=“address-box”]/div[1]
    添加第一个地址后,该元素位置往右偏移了://*[@id=“address-box”]/div[2]
    添加第二个地址后,该元素位置再往右偏移://*[@id=“address-box”]/div[3]
    以此类推…

    又比如很多web网站的轮播图也是属于动态元素…

动态元素怎么定位?
针对 a.元素的属性是动态的的解决方法:

  1. 根据其他静态属性定位
    比如如果id属性是动态的,而class属性是静态的,则用class属性来定位
  2. 根据元素属性值模糊匹配定位
    如果有固定前缀、后缀值,可以通过 xpath 的模糊匹配方法
    driver.find_element_by_xpath(“//标签名[contains (@属性,‘属性值’)]”)
    driver.find_element_by_xpath(“//标签名[starts-with (@属性,‘属性值’)]”)
    driver.find_element_by_xpath(“//标签名[end-with (@属性,‘属性值’)]”)
  3. 根据父级、子级或同级元素定位
    属性值完全随机的话,可以通过 xpath、css 选择器找到它的父级、子级、同级 元素,再进行定位
    ps:css 不能找到父级元素
    元素xpathcss
    父级//div/…/span
    子级//div/spandiv > span
    同级//div/following-siblingdiv + span

针对b.元素的位置是动态的的解决方法:
可以通过遍历获取对应的下标,然后取最大下标进行定位

  • 22
    点赞
  • 232
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Selenium是一个用于自动化浏览器操作的工具,用于进行UI自动化测试。它可以模拟用户的操作,比如输入文本、点击按钮等,来测试Web应用程序的功能和可靠性。Selenium WebDriver是Selenium的一个模块,它是基于Python实现的,可以使用Python编写脚本来实现自动化测试。 安装Selenium环境后,可以使用WebDriver来实现自动化输入用户的Email。代码示例如下: driver.findElement(By.name("email")).sendKeys("xiaoming@qatools.cn"); Selenium RC是Selenium的一个模块,由Selenium Server和Client Libraries组成。Selenium Server负责控制浏览器的行为,Client Libraries则是用来编写测试案例并控制Selenium Server的库。Selenium RC也被称为Selenium 1,在Selenium 2与WebDriver合并为Selenium 2。在Selenium 3.0版本Selenium RC已经不存在。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [基于selenium实现UI自动化](https://blog.csdn.net/weixin_60448629/article/details/123006781)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [技术篇——使用 Selenium 实现 UI 自动化测试](https://blog.csdn.net/winteroak/article/details/101048081)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值