UI自动化中元素的定位是最最基本,但也是最让人头痛的地方。控件的动态加载,属性的动态生成抑或因为开发的懒而造成控件的识别问题总是自动化测试的噩梦。WebDriver作为主流的网页测试工具提供了非常丰富的识别控件的方法。这次在写自动化库的时候也遇到各种定位问题,着实抓狂了一阵,但最终都解决了。 虽然我们的产品网页结构并不复杂,但因为xpath, css selector 本身的强大,虽然有时候要绕个弯但webdriver提供的这些方法能应该能解决绝大部分的定位问题。
1. id 定位
显而易见,通过元素的id属性来定位元素。id属性是定位元素最容易最准确的方法,因为Id在网页中一定是唯一的。以下是百度首页百度一下button的html。
<span class="bg s_ipt_wr quickdelete-wrap">
<span class="bg s_btn_wr">
<input id="su" class="bg s_btn" value="百度一下" type="submit">
</span>
Selenium提供了find_element_by_id函数,接受id的值为参数,返回一个webElement的对象
button = driver.find_element_by_id('su')
2. name 定位
通过元素的name属性来定位。以下是百度搜索输入框的html。
<span class="bg s_ipt_wr quickdelete-wrap">
<span class="soutu-btn"></span>
<input id="kw" class="s_ipt" name="wd" value="" maxlength="255" autocomplete="off">
<a id="quickdelete" class="quickdelete" href="javascript:;" title="清空" style="top: 0px; right: 0px; display: none;"></a>
</span>
Selenium提供find_element_by_name函数,接受name的值为参数,返回一个webElement对象。
textbox = driver.find_element_by_name('wd')
3. class 定位
同上面,这通过class属性的值定位,还是以百度搜索输入框为例。Selenium提供find_element_by_class_name,接受class的值为参数,返回一个webElement对象。实际运用中用find_elements_by_class_name比较多,可以看到多了个s,即返回所有符合特定属性webElement列表。而没有s的方法只会返回符合第一个符合条件的webElement对象。这在后面会详细说。
textbox = driver.find_element_by_class_name('s_ipt')
4. tag 定位
以百度的输入框为例,Selenium提供find_element_by_tag_name,接受一个htm标签,返回一个webElement对象。
textbox = driver.find_element_by_tag_name('input')
5. link/partial link 定位
通过链接的文本来定位,返回一个链接的webElement对象。方法为find_element_by_link_text 和 find_element_by_partial_link_text。 区别是前者必须的参数必须是完整的链接文本,不然找不到。后者则只需要链接文本的一部分。
<p id="lh">
<a id="setf" href="//www.baidu.com/cache/sethelp/help.html" οnmοusedοwn="return ns_c({'fm':'behs','tab':'favorites','pos':0})" target="_blank">把百度设为主页</a>
<a οnmοusedοwn="return ns_c({'fm':'behs','tab':'tj_about'})" href="http://home.baidu.com">关于百度</a>
<a οnmοusedοwn="return ns_c({'fm':'behs','tab':'tj_about_en'})" href="http://ir.baidu.com">About Baidu</a>
<a οnmοusedοwn="return ns_c({'fm':'behs','tab':'tj_tuiguang'})" href="http://e.baidu.com/?refer=888">百度推广</a>
</p>
举个例子,我们要获取中文的关于百度这个链接的对象。一下的两个方法都会返回关于百度这个链接的对象。
link = driver.find_element_by_link_text('关于百度')
link = driver.find_element_by_partial_link_text('关于')
6. xpath 定位 XPath是XML路径语言,它是一种用来确定XML文档中某部分位置的语言。Selenium提供find_element_by_xpath方法,接受xpath路径为参数。Xpath定位是一个蛮大的话题,功能非常强大,可以写得非常复杂支持逻辑预算符,能解决大部分的定位问题。 打算另写一篇专门讲讲xpath的定位。这里用百度输入框来做例子
textbox = driver.find_element_by_xpath('//input[@id="kw"]')
7. css 定位
另一种非常强大的定位策略。CSS是一种语言,用来描述HTML,XML的表现样式。 Selenium提供find_element_by_css_selector, 接受css语言作为参数。相对于xpath的表示,css没有那么易读友好,同样会另写一篇说css的定位。这里用百度输入框来做例子。这两个例子第一个表示选在id为kw的元素,第二个表示input标签class属性为s_ipt的元素。
textbox = driver.find_element_by_css_selector('#kw')
textbox = driver.find_element_by_css_selector('input.s_ipt')
8. by 定位
除了以上几种定位方法,selenium还提供一种泛用的方法find_element,接受两个参数,通过By声明的定位发放,以及定位的参数
button = drvier.find_element(By.ID, 'su')
textbox = driver.find_element(By.CLASS_NAME,'kw')
link = driver.find_element(By.LINK_TEXT, '关于百度')
9. find_elements 方法
这在前面提到过,普通的方法只会返回符合条件的第一个对象,用了find_elements的方法会返回HTML里面所有符合条件的元素。例如:
find_elements_by_id
find_elements_by_css_selector
find_elements(By.ID, 'su')