求助webdriver层级定位定位问题

科技需要真相和数据,立志成为最有范儿的测试人社区.
那么,本例中就是com.xxx.xxx.SplashActivity
3.关于如何定位元素的问题
如果作为Appium的玩家,你问出这样的问题,我认为你是Selenium的基础不牢靠。
id,classname,name,xpath,tagname……,其实很多元素定位的方法都跟DOM有关,如果对Web前端开发熟悉的童鞋上手这个不会有难度,当然了,对于APP来讲,你可以借助一些现成的工具进行嗅探
比如 uiautomatorviewer 不用单独下载,因为你在折腾Appium的时候你肯定会下载SDK,很幸运,这玩意就是在SDK中自带的,所以如果你已经设置了环境变量的话,直接敲命令就可以启动他了。
4.关于如何等待一个元素的出现而不用一些笨拙粗暴的time.sleep()方法
我相信这是一个非常大众化的需求,我们需要等待某一个元素的出现以此来让我们的脚本进入到下一个Step,这个等待方法最好能够设置超时时间,然后找到后迅速callback。我们也很幸运!如果你仔细看Selenium的API你会发现这么一个东西:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0
ff = webdriver.Firefox()
ff.get(&http://somedomain/url_that_delays_loading&)
element = WebDriverWait(ff, 10).until(EC.presence_of_element_located((By.ID, &myDynamicElement&)))
ff.quit()
原来,我们的webdriver.support.ui中有一个强大的WebDriverWait可以帮助我们完成这个事情。
他提供了一个极其实用的until方法,until方法可以传入一个条件型的参数,这个条件型参数来自selenium.webdriver.support中的expected_conditions,里面定义了一些”call“可调用的类,比如我们这里常用的
presence_of_element_located,意思就是等待某一元素出现(被定位到)
更多关于API上的惊喜可以猛戳这里:
5.关于Appium For Windows
不喜欢折腾的童鞋可以选择在Windows端快速入门Appium,Appium For Windows使用起来极其简单,下载完成后直接双击Appium.exe,然后点击LAUNCHER即可。
6.想到了再写吧……
可能对你有帮助的一些在线API手册
这里我更多的是提供了Python的例子,其他同理。
Python相关的一些知识
Python API / Nose / Unittest 官方例子中所用到的东西,很多新人看不懂Setup和TearDown是有原因的,(>_&)
+ 猜你喜欢...
===== 关于 DiggerPlus =====
DiggerPlus是国内新锐测试人垂直内容博客,专注于挖掘测试工具,普及测试技术,专注于测试人能力提升,博客上线后就受到广大测试人的热烈追捧;此外,DiggerPlus深度整合评测资源,揭秘科技数据和真相,让读者更懂科技,更好地把玩科技。
我们始终保持"独立,客观,严谨,优秀"的优良作风,努力为读者带来源源不断的优质内容。想访问更多酷毙的测试人网站?赶紧来看看吧!
===== DiggerPlus Team =====
DiggerPlus Team是DiggerPlus官方发起的团队,这是一群热爱科技,热爱测试,喜欢深度挖掘的热血测试人,他们是评测师,测试专家。
我们欢迎优秀的测试人。
加入DiggerPlus,可以成为我们的,认证Dper拥有DiggerPlus独一无二的专栏并得到个人展示。
===== DiggerPlus 官方读者群 =====
+ 关于本文作者
Python/C/C++/Javascript程序员,持续学习者,目前专注于前端开发。
| 访问的主页
基于开源中国开发
最新文章热门文章随机文章
"Save Binary World"
使用合作网站账号快速登录,更多精彩等着您:&&&&Selenium WebDriver中使用By.Xpath快速定位页面元素
Selenium WebDriver中使用By.Xpath快速定位页面元素
在Selenium WebDriver中使用By.Xpath快速定位页面元素,实现多属性定位一个元素。
嵌到我的页面
<input type="text" readonly="true" value="">
若举报审核通过,可奖励20下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
免积分&&极速下载60元/年(1200次)
您可能还需要
开发技术下载排行Selenium Webdriver元素定位的八种常用方式 - 测试控 - 博客园
我的测试人生
posts - 2, comments - 2, trackbacks - 0, articles - 0
楼主原创,欢迎学习和交流,码字不容易,转载请注明出处,谢谢。
在使用selenium webdriver进行元素定位时,通常使用findElement或findElements方法结合By类返回的元素句柄来定位元素。其中By类的常用定位方式共八种,现分别介绍如下。
1. By.name()
假设我们要测试的页面源码如下:
&button id="gbqfba" aria-label="Google Search" name="btnK" class="gbqfba"&&span id="gbqfsa"&Google Search&/span&&/button&
当我们要用name属性来引用这个button并点击它时,代码如下:
1 public class SearchButtonByName {
public static void main(String[] args){
WebDriver driver = new FirefoxDriver();
driver.get("");
WebElement searchBox = driver.findElement(By.name("btnK"));
searchBox.click();
2. By.id()
页面源码如下:
1 &button id="gbqfba" aria-label="Google Search" name="btnK" class="gbqfba"&&span id="gbqfsa"&Google Search&/span&&/button&
要引用该button并点击它时,代码如下:
1 public class SearchButtonById {
public static void main(String[] args){
WebDriver driver = new FirefoxDriver();
driver.get("");
WebElement searchBox = driver.findElement(By.id("gbqfba"));
searchBox.click();
3. By.tagName()
该方法可以通过元素的标签名称来查找元素。该方法跟之前两个方法的区别是,这个方法搜索到的元素通常不止一个,所以一般建议结合使用findElements方法来使用。比如我们现在要查找页面上有多少个button,就可以用button这个tagName来进行查找,代码如下:
public class SearchPageByTagName{
public static void main(String[] args){
WebDriver driver = new FirefoxDriver();
driver.get("");
List&WebElement& buttons = driver.findElements(By.tagName("button"));
System.out.println(buttons.size());
//打印出button的个数
另外,在使用tagName方法进行定位时,还有一个地方需要注意的是,通常有些HTML元素的tagName是相同的,如下图(1)所示。
从图中我们可以看到,单选框、复选框、文本框和密码框的元素标签都是input,此时单靠tagName无法准确地得到我们想要的元素,需要结合type属性才能过滤出我们要的元素。示例代码如下:
1 public class SearchElementsByTagName{
public static void main(String[] args){
WebDriver driver = new FirefoxDriver();
driver.get("");
List&WebElement& allInputs = driver.findElements(By.tagName("input"));
//只打印所有文本框的值
for(WebElement e: allInputs){
if (e.getAttribute(&type&).equals(&text&)){
System.out.println(e.getText().toString());
//打印出每个文本框里的值
4. By.className()
className属性是利用元素的css样式表所引用的伪类名称来进行元素查找的方法。对于任何HTML页面的元素来说,一般程序员或页面设计师会给元素直接赋予一个样式属性或者利用css文件里的伪类来定义元素样式,使元素在页面上显示时能够更加美观。一般css样式表可能会长成下面这个样子:
1 .buttonStyle{
width: 50px;
height: 50px;
border-radius: 50%;
margin: 0% 2%;
定义好后,就可以在页面元素中引用上述定义好的样式,如下:
1 &button name="sampleBtnName" id="sampleBtnId" class="buttonStyle"&I'm Button&/button&
如果此时我们要通过className属性来查找该button并操作它的话,就可以使用className属性了,代码如下:
1 public class SearchElementsByClassName{
public static void main(String[] args){
WebDriver driver = new FirefoxDriver();
driver.get("");
WebElement searchBox =
driver.findElement(By.className("buttonStyle"));
searchBox.sendKeys("Hello, world");
注意:使用className来进行元素定位时,有时会碰到一个元素指定了若干个class属性值的&复合样式&的情况,如下面这个button:&button id="J_sidebar_login" class="btn btn_big btn_submit" type="submit"&登录&/button&。这个button元素指定了三个不同的css伪类名作为它的样式属性值,此时就必须结合后面要介绍的cssSelector方法来定位了,稍后会有详细例子。
5. By.linkText()
这个方法比较直接,即通过超文本链接上的文字信息来定位元素,这种方式一般专门用于定位页面上的超文本链接。通常一个超文本链接会长成这个样子:
1 &a href="/intl/en/about.html"&About Google&/a&
我们定位这个元素时,可以使用下面的代码进行操作:
1 public class SearchElementsByLinkText{
public static void main(String[] args){
WebDriver driver = new FirefoxDriver();
driver.get("");
WebElement aboutLink = driver.findElement(By.linkText("About Google"));
aboutLink.click();
6. By.partialLinkText()
这个方法是上一个方法的扩展。当你不能准确知道超链接上的文本信息或者只想通过一些关键字进行匹配时,可以使用这个方法来通过部分链接文字进行匹配。代码如下:
1 public class SearchElementsByPartialLinkText{
public static void main(String[] args){
WebDriver driver = new FirefoxDriver();
driver.get("");
WebElement aboutLink = driver.findElement(By.partialLinkText("About"));
aboutLink.click();
注意:使用这种方法进行定位时,可能会引起的问题是,当你的页面中不止一个超链接包含About时,findElement方法只会返回第一个查找到的元素,而不会返回所有符合条件的元素。如果你要想获得所有符合条件的元素,还是只能使用findElements方法。
7. By.xpath()
这个方法是非常强大的元素查找方式,使用这种方法几乎可以定位到页面上的任意元素。在正式开始使用XPath进行定位前,我们先了解下什么是XPath。XPath是XML Path的简称,由于HTML文档本身就是一个标准的XML页面,所以我们可以使用XPath的语法来定位页面元素。
假设我们现在以图(2)所示HTML代码为例,要引用对应的对象,XPath语法如下:
绝对路径写法(只有一种),写法如下:
引用页面上的form元素(即源码中的第3行):/html/body/form[1]
注意:1. 元素的xpath绝对路径可通过firebug直接查询。2. 一般不推荐使用绝对路径的写法,因为一旦页面结构发生变化,该路径也随之失效,必须重新写。3. 绝对路径以单/号表示,而下面要讲的相对路径则以//表示,这个区别非常重要。另外需要多说一句的是,当xpath的路径以/开头时,表示让Xpath解析引擎从文档的根节点开始解析。当xpath路径以//开头时,则表示让xpath引擎从文档的任意符合的元素节点开始进行解析。而当/出现在xpath路径中时,则表示寻找父节点的直接子节点,当//出现在xpath路径中时,表示寻找父节点下任意符合条件的子节点,不管嵌套了多少层级(这些下面都有例子,大家可以参照来试验)。弄清这个原则,就可以理解其实xpath的路径可以绝对路径和相对路径混合在一起来进行表示,想怎么玩就怎么玩。
下面是相对路径的引用写法:
查找页面根元素://
查找页面上所有的input元素://input
查找页面上第一个form元素内的直接子input元素(即只包括form元素的下一级input元素,使用绝对路径表示,单/号)://form[1]/input
查找页面上第一个form元素内的所有子input元素(只要在form元素内的input都算,不管还嵌套了多少个其他标签,使用相对路径表示,双//号)://form[1]//input
查找页面上第一个form元素://form[1]
查找页面上id为loginForm的form元素://form[@id='loginForm']
查找页面上具有name属性为username的input元素://input[@name='username']
查找页面上id为loginForm的form元素下的第一个input元素://form[@id='loginForm']/input[1]
查找页面具有name属性为contiune并且type属性为button的input元素://input[@name='continue'][@type='button']
查找页面上id为loginForm的form元素下第4个input元素://form[@id='loginForm']/input[4]
Xpath功能很强大,所以也可以写得更加复杂一些,如下面图(3)的HTML源码。
如果我们现在要引用id为&J_password&的input元素,该怎么写呢?我们可以像下面这样写:
WebElement password = driver.findElement(By.xpath("//*[@id='J_login_form']/dl/dt/input[@id='J_password']"));
也可以写成:
WebElement password = driver.findElement(By.xpath("//*[@id='J_login_form']/*/*/input[@id='J_password']"));
这里解释一下,其中//*[@id=& J_login_form&]这一段是指在根元素下查找任意id为J_login_form的元素,此时相当于引用到了form元素。后面的路径必须按照源码的层级依次往下写。按照图(3)所示代码中,我们要找的input元素包含在一个dt标签内,而dt又包含在dl标签内,所以中间必须写上dl和dt两层,才到input这层。当然我们也可以用*号省略具体的标签名称,但元素的层级关系必须体现出来,比如我们不能写成//*[@id='J_login_form']/input[@id='J_password'],这样肯定会报错的。
前面讲的都是xpath中基于准确元素属性的定位,其实xpath作为定位神器也可以用于模糊匹配。比如下面图(4)所示代码:
这段代码中的&退出&这个超链接,没有标准id元素,只有一个rel和href,不是很好定位。不妨我们就用xpath的几种模糊匹配模式来定位它吧,主要有三种方式,举例如下。
a. 用contains关键字,定位代码如下:
1 driver.findElement(By.xpath(&//a[contains(@href, &logout&)]&));
这句话的意思是寻找页面中href属性值包含有logout这个单词的所有a元素,由于这个退出按钮的href属性里肯定会包含logout,所以这种方式是可行的,也会经常用到。其中@后面可以跟该元素任意的属性名。
b. 用start-with,定位代码如下:
1 driver.findElement(By.xpath(&//a[starts-with(@rel, &nofo&)]));
这句的意思是寻找rel属性以nofo开头的a元素。其中@后面的rel可以替换成元素的任意其他属性。
c. 用Text关键字,定位代码如下:
1 driver.findElement(By.xpath(&//*[text()=&退出&]));
这个方法可谓相当霸气啊。直接查找页面当中所有的退出二字,根本就不用知道它是个a元素了。这种方法也经常用于纯文字的查找。
另外,如果知道超链接元素的文本内容,也可以用
1 driver.findElement(By.xpath(&//a[contains(text(), &退出&)]));
这种方式一般用于知道超链接上显示的部分或全部文本信息时,可以使用。
最后,关于xpath这种定位方式,webdriver会将整个页面的所有元素进行扫描以定位我们所需要的元素,所以这是一个非常费时的操作,如果你的脚本中大量使用xpath做元素定位的话,将导致你的脚本执行速度大大降低,所以请慎用。
8. By.cssSelector()
cssSelector这种元素定位方式跟xpath比较类似,但执行速度较快,而且各种浏览器对它的支持都相当到位,所以功能也是蛮强大的。
下面是一些常见的cssSelector的定位方式:
定位id为flrs的div元素,可以写成:#flrs&&&& 注:相当于xpath语法的//div[@id=&flrs&]
定位id为flrs下的a元素,可以写成 #flrs & a& 注:相当于xpath语法的//div[@id=&flrs&]/a
定位id为flrs下的href属性值为/forexample/about.html的元素,可以写成: #flrs & a[href=&/forexample/about.html&]
如果需要指定多个属性值时,可以逐一加在后面,如#flrs & input[name=&username&][type=&text&]。
明白基本语法后,我们来尝试用cssSelector方式来引用图(3)中选中的那个input对象,代码如下:
WebElement password = driver.findElement(By.cssSelector("#J_login_form&dl&dt&input[id=& J_password&]"));
同样必须注意层级关系,这个不能省略。
cssSelector还有一个用处是定位使用了复合样式表的元素,之前在第4种方式className里面提到过。现在我们就来看看如何通过cssSelector来引用到第4种方式中提到的那个button。button代码如下:
&button id="J_sidebar_login" class="btn btn_big btn_submit" type="submit"&登录&/button&
cssSelector引用元素代码如下:
driver.findElement(By.cssSelector("button.btn.btn_big.btn_submit"))
。这样就可以顺利引用到使用了复合样式的元素了。
此外,cssSelector还有一些高级用法,如果熟练后可以更加方便地帮助我们定位元素,如我们可以利用^用于匹配一个前缀,$用于匹配一个后缀,*用于匹配任意字符。例如:
匹配一个有id属性,并且id属性是以&id_prefix_&开头的超链接元素:a[id^='id_prefix_']
匹配一个有id属性,并且id属性是以&_id_sufix&结尾的超链接元素:a[id$='_id_sufix']
匹配一个有id属性,并且id属性中包含&id_pattern&字符的超链接元素:a[id*='id_pattern']
最后再总结一下,各种方式在选择的时候应该怎么选择:
1. 当页面元素有id属性时,最好尽量用id来定位。但由于现实项目中很多程序员其实写的代码并不规范,会缺少很多标准属性,这时就只有选择其他定位方法。
2. xpath很强悍,但定位性能不是很好,所以还是尽量少用。如果确实少数元素不好定位,可以选择xpath或cssSelector。
3. 当要定位一组元素相同元素时,可以考虑用tagName或name。
4. 当有链接需要定位时,可以考虑linkText或partialLinkText方式。
参考资料:
《Selenium Webdriver Practical Guide》
/resources/selenium/css-selectors说说watir-webdriver那些事(三)如何定位页面元素 - dtrex - ITeye技术网站
博客分类:
功能自动化测试做的就是,找到页面的控件元素,然后操作这些控件,完成模拟人工的测试操作。所以开头肯定是要定位到页面上的元素。watir-webdriver提供了多方方法,帮助我们定位Web页面上的元素。
常用的定位方法如下:
=& 'name',
=& 'class name',
:class_name
=& 'class name',
=& 'link text',
:link_text
=& 'link text',
:partial_link_text =& 'partial link text',
=& 'xpath',
目前webdriver还不支持:css的方法,不过说实话这个不经常用
使用id进行定位
比方说针对下面的控件
&input type="text" class="s_ipt" maxlength="100" id="kw" name="wd" autocomplete="off"&
进行ID定位,可以这样写
b.text_field(:id=&"kw").set "rex"
id一般是惟一的标示,不会有重复,所以尽量使用id来定位
使用name进行定位
还是使用这个例子
&input type="text" class="s_ipt" maxlength="100" id="kw" name="wd" autocomplete="off"&
使用name定位,是这样写的
b.text_field(:name=&"wd").set "rex"
name可能会有重复,有的时候要加入:index=&1来唯一性定位
使用class或者class_name的定位
同样的例子
&input type="text" class="s_ipt" maxlength="100" id="kw" name="wd" autocomplete="off"&
使用class或者class_name定位,是这样写的
b.text_field(:class=&"s_ipt").html
使用XPath定位
同样的例子
&input type="text" class="s_ipt" maxlength="100" id="kw" name="wd" autocomplete="off"&
使用XPath定位,是这样写的
b.text_field(:xpath=&'//*[@id="kw"]').html
不过像我在第一篇文章中介绍的,xpath虽然可以用,不过代码会显得非常丑陋,在实际使用过程中,尽量避免使用用xpath来定位元素比较好。
使用其他方法定位
在定位link对象的时候,可以使用link和link_text属性;
另外还可以使用tag_name属性定位任意元素;
多种定位方式同时使用
在很多时候一种定位方式不能完全定位唯一元素,需要多个定位方式综合使用
比方说有两个name一模一样的控件,只能通过index来识别,如下
b.button(:name=&"a",:index=&0).click
这种写法,将定位name为a的第一个元素(这里注意:incex在watir-webdriver里是从0开始的,而在Watir里是从1开始的。)。可以说这种写法是与的关系,即name符合也要index符合。有的时候我们需要或的关系,就是如果名称或者ID只要一个相等就可以,当然你可以写XPath搞定,同时也可以利用 exists?来进行判断,不过代码看似很丑,必要的时候使用吧。
使用层级关系定位
&span id="news"&
&input type="text" /&
这种情况,可能在很多使用前台组件的页面中,经常碰到,如果使用上面的方法定位,你会发现没有id,没有name,整体上会有很多input,单纯用index很痛苦,这个时候用层级管理会好很多,如下
b.span(:id=&"news").text_field(:index=&0).set "rex"
使用这种方式,寻找页面控件更加稳定,效率更高,也算是一种技巧。
浏览: 85637 次
来自: 北京
showModalDialog,我不能定位到ie页面,为啥
use的方法,是window的类方法,api里有的,除非是你的 ...
我运行的时候,为什么说我没有use这个方法?
selenium_java_code_.rar 无法下载啊
我想请问下,这种写法在火狐中能用吗?我在ie和chrome中可 ...

我要回帖

更多关于 webdriver层级定位 的文章

 

随机推荐