简单对象定位——css定位
CSS定位:
CSS(Cascading Style Sheets)是一种语言,它被用来描述HTML 和XML 文档的表现。CSS 使用选择器来为页面元素绑定属性。这些选择器可以被selenium 用作另外的定位策略。
CSS 可以比较灵活选择控件的任意属性,一般情况下定位速度要比XPath 快,但对于初学者来说比较难以学习使用,下面我们就详细的介绍CSS 的语法与使用。
CSS 选择器的常见语法:
* :通用元素选择器,匹配任何元素
E :标签选择器,匹配所有使用E 标签的元素
.info :class 选择器,匹配所有class 属性中包含info 的元素
#footer :id 选择器,匹配所有id 属性等于footer 的元素
E,F :多元素选择器,同时匹配所有E 元素或F 元素,E 和F 之间用逗号分隔
E F :后代元素选择器,匹配所有属于E 元素后代的F 元素,E 和F 之间用空格分隔
E > F :子元素选择器,匹配所有E 元素的子元素F
E + F: 毗邻元素选择器,匹配紧随E 元素之后的同级元素F (只匹配第一个)
E ~ F :同级元素选择器,匹配所有在E 元素之后的同级F 元素
E[att='val'] :属性att 的值为val 的E 元素(区分大小写)
E[att^='val']: 属性att 的值以val 开头的E 元素(区分大小写)
E[att$='val']: 属性att 的值以val 结尾的E 元素(区分大小写)
E[att*='val']: 属性att 的值包含val 的E 元素(区分大小写)
E[att1='v1'][att2*='v2'] :属性att1 的值为v1,att2 的值包含v2 (区分大小写)
E:contains('xxxx') :内容中包含xxxx 的E 元素
E:not(s): 匹配不符合当前选择器的任何元素
例如下面一段代码:
<div class="formdiv">
<form name="fnfn">
<input name="username" type="text"></input>
<input name="password" type="text"></input>
<input name="continue" type="button"></input>
<input name="cancel" type="button"></input>
<input value="SYS123456" name="vid" type="text">
<input value="ks10cf6d6" name="cid" type="text">
</form>
<div class="subdiv">
<ul id="recordlist">
<p>Heading</p>
<li>Cat</li>
<li>Dog</li>
<li>Car</li>
<li>Goat</li>
</ul>
</div>
</div>
通过CSS 语法进行匹配的实例:
locator 匹配
css=div
css=div.formdiv <div class="formdiv">
css=#recordlist
css=ul#recordlist <ul id="recordlist">
css=div.subdiv p
css=div.subdiv > ul > p <p>Heading</p>
css=form + div <div class="subdiv">
css=p + li
css=p ~ li 二者定位到的都是<li>Cat</li>但是storeCssCount 的时候,前者得到1,后者得到4
css=form > input[name=username] <input name="username">
css=input[name$=id][value^=SYS] <input value="SYS123456" name="vid" type="hidden">
css=input:not([name$=id][value^=SYS]) <input name="username" type="text"></input>
css=li:contains('Goa') <li>Goat</li>
css=li:not(contains('Goa')) <li>Cat</li>
css 中的结构性定位:
结构性定位就是根据元素的父子、同级中位置来定位,css3标准中有定义一些结构性定位伪类如nth-of-type,nth-child,但是使用起来语法很不好理解,这里就不做介绍了。
Selenium 中则是采用了来自Sizzle 的css3定位扩展,它的语法更加灵活易懂。
Sizzle Css3的结构性定位语法:
E:nth(n)
E:eq(n) 在其父元素中的E 子元素集合中排在第n+1 个的E 元素(第一个n=0)
E:first 在其父元素中的E 子元素集合中排在第1 个的E 元素
E:last 在其父元素中的E 子元素集合中排在最后1 个的E 元素
E:even 在其父元素中的E 子元素集合中排在偶数位的E 元素(0,2,4…)
E:odd 在其父元素中的E 子元素集合中排在奇数的E 元素(1,3,5…)
E:lt(n) 在其父元素中的E 子元素集合中排在n 位之前的E 元素(n=2,则匹配0,1)
E:gt(n) 在其父元素中的E 子元素集合中排在n 位之后的E 元素(n=2,在匹配3,4)
E:only-child 父元素的唯一一个子元素且标签为E
E:empty 不包含任何子元素的E 元素,注意,文本节点也被看作子元素
例如下面一段代码:
<div class="subdiv">
<ul id="recordlist">
<p>Heading</p>
<li>Cat</li>
<li>Dog</li>
<li>Car</li>
<li>Goat</li>
</ul>
</div>
匹配示例:
locator 匹配
css=ul > li:nth(0) <li>Cat</li>
css=ul > *:nth(0)
css=ul > :nth(0) <p>Heading</p>
css=ul > li:first <li>Cat</li>
css=ul > :first <p>Heading</p>
css=ul > *:last
css=ul > li:last <li>Goat</li>
css=ul > li:even Cat, Car
css=ul > li:odd Dog, Goat
css=ul > :even <p>Heading</p>
css=ul > p:odd [error] not found
css=ul > li:lt(2) <li>Cat</li>
css=ul > li:gt(2) <li>Goat</li>
css=ul > li:only-child
css=ul > :only-child
css=ul > *:only-child [error] not found (ul 没有only-child)
css=div.subdiv > :only-child <ul id="recordlist">
.......
</ul>
下面是一些XPATH 和CSS 的类似定位功能比较(缺乏一定的严谨性)。
定位方式 XPath CSS
标签 //div div
By id //div[@id='eleid'] div#eleid
By class //div[@class='eleclass']
//div[contains(@class,'eleclass')] div.eleclass
By 属性 //div[@title='Move mouse here'] div[title=Move mouse here]
div[title^=Move]
div[title$=here]
div[title*=mouse]
定位子元素 //div[@id='eleid']/* div#eleid >*
//div/h1 div#eleid >h1
定位后代元素 //div[@id='eleid']//h1 div h1
By index //li[6] li:nth(5)
By content //a[contains(.,'Issue 1164')] a:contains(Issue 1164)
通过对比,我们可以看到,CSS 定位语法比XPath 更为简洁,定位方式更多灵活多样;不过对CSS 理解起来要比XPath 较难;但不管是从性能还是定位更复杂的元素上,CSS 优于XPath,笔者更推荐使用CSS定位页面元素。
关于自动化的定位问题:
自动化测试的元素定位一直是困扰自动化测试新手的一个障碍,因为我们在自动化实施过程中会碰到各式各样的对象元素。虽然XPath 和CSS 可以定位到复杂且比较难定位的元素,但相比较用id 和name 来说增加了维护成本和学习成本,相比较来说id/name 的定位方式更直观和可维护,有新的成员加入的自动化时也增加了人员的学习成本。所以,测试人员在实施自动化测试时一定要做好沟通,规范前端开发人员对元素添加id/name 属性,或者自己有修改HTML 代码的权限。
posted on 2016-12-22 15:20 chenzx0918 阅读(308) 评论(0) 编辑 收藏 举报