购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.3 元素定位实战

本节主要结合众多自动化测试案例介绍元素定位实战,如单个元素定位、多个元素定位、By类定位及引用JavaScript、JQuery辅助定位来加强元素定位实战技巧。在笔者看来,元素定位在自动化测试中非常重要。

2.3.1 单个元素定位实战

WebDriver提供了多种内置定位方法,如id、name、class、link_text、partial_link_text、tag、xpath和css定位等。下面介绍一个百度首页案例。按F12键,会出现Chrome调试工具,单击调试工具上方的小箭头,定位到文本框位置上。在HTML页面下方显示的是页面文本框对应的HTML元素。拆分HTML元素,如图2.11所示。

028-01.jpg

图2.11 百度首页HTML元素拆分

在上面的案例中,百度文本框对应的元素是<input id="kw" name="wd" class="s_ipt" value maxlength="255" autocomplete="off" >,其中=(等号)左侧的id、name、class、value maxlength和autocomplete等都是元素的属性,就像人有身份证、姓名和身高等属性一样;等号右侧的kw、wd、s_ipt、255、off等都是属性值,就像人的身份证号、姓名和身高等。Selenium工具就是通过识别这些属性来进行测试的。

1. 通过find_element_by_id()定位

示例如下:

from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
driver.find_element_by_id("kw").send_keys('大道至简')
driver.quit()

2. 通过find_element_by_name()定位

示例如下:

from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
driver.find_element_by_name("wd").send_keys('大道至简')
driver.quit()

3. 通过find_element_by_class_name()定位

示例如下:

from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
driver.find_element_by_class_name("s_ipt").send_keys('大道至简')
driver.quit()

上述3个案例中,分别使用了id、name、class_name来定位百度文本框。send_keys()是一个方法,表示向文本框中输入内容。在元素定位中,如果元素本身有id、name属性,则直接使用id、name定位,一般来说,id、name属性值都是唯一的。相反,在使用class定位时,要检查class_name属性值在页面中是否唯一。如果不唯一,尽量不要用class去定位。举个简单的例子,一个班级里有两个叫张飞的同学,喊张飞时,这两个同学都会一起站起来,这样就会产生冲突。

通过浏览器自带的调试工具来验证属性的唯一性。按F12键,再按Ctrl+F组合键,搜索指定的元素属性值。如图2.12所示,class属性值在整个页面显示数量只有1个,这时就可以使用class来定位了。有些情况下,class属性值即使是唯一的,可能也会定位报错,这时就需要考虑其他定位方法。

030-01.jpg

图2.12 Chrome调试工具界面

4. 通过find_element_by_xpath()定位

示例如下:

from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
driver.find_element_by_xpath("//input[@id='kw']").send_keys('大道至简')
driver.quit()

//表示相对路径,input标签是文本框的所在标签,@id=kw是文本框元素id的属性值。当然,也可以把id换成其他的定位,如name等。

示例如下:

from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
driver.find_element_by_xpath("//form[@id='form']/span/input").send_keys('大道至简')
driver.quit()

//form[@id= 'form']表示父类元素,/表示下一级标签,/span/input表示span标签下的input标签,如图2.13所示。

030-02.jpg

图2.13 父子关系定位界面演示图

示例如下:

from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
driver.find_element_by_xpath("//input[@id='kw' and @class='s_ipt']").send_keys('大道 
至简')
driver.quit()

//input表示HTML页面相对路径下的input标签;@id='kw' and @class='s_ipt'是input标签的两个属性,通过id和class两个属性加强元素的唯一性。

5. 通过find_element_by_css_selector()定位1

示例如下:

from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
driver.find_element_by_css_selector("input#kw").send_keys('大道至简')
driver.quit()

input#kw表示input标签下id属性值是kw的元素。在css定位中,id简写用“#”来表示,class属性简写用“.”来表示。

6. 通过find_element_by_css_selector()定位2

示例如下:

from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
driver.find_element_by_css_selector("form#form>span>input").send_keys('大道至简')
driver.quit()

form#form表示form标签下id属性值是form的元素。在css定位中,层级关系用“>”来表示。span>input表示span标签下的input标签。有时为了简洁,也可以不写“>”,直接写成form#form span input。

2.3.2 多个元素定位实战

有时定位的元素属性值或标签名并不是唯一的,如一个页面有多个相同的type属性值或多个相同的标签名,如图2.14所示。

032-01.jpg

图2.14 多个元素属性界面

示例如下:

from selenium import webdriver
driver = webdriver.Chrome()
driver.get('file:///' + os.path.abspath('checkbox.html'))
driver.find_elements_by_css_selector("input[type='checkbox']")[0].click()
driver.quit()

如图2.14所示,整个页面中有3个相同的input标签,且input标签下的type属性值checkbox都是一样的。这种情况可以使用find_elements_by_css_seletor()方法定位,该方法返回一个列表对象。通过Python索引下标来获取要定位的元素。[0]表示第一个input标签下的checkbox属性值,[1]表示第二个input标签下的checkbox属性值。

再看一个多个标签定位案例,如图2.15所示。

032-02.jpg

图2.15 百度首页调试界面

示例如下:

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
tag = dr.find_elements_by_tag_name('input')
for t in tag:
if t.get_attribute('autocomplete') == 'off':
    t.send_keys('fighter007')
driver.find_element_by_id('su').click()
dr.quit()

如图2.15所示,当页面中有多个input标签时,可以通过标签本身的属性来定位。先获取所有input标签,然后通过for循环遍历每一个对象,最后判断获取的对象中autocomplete属性等于off的元素。

2.3.3 使用By类定位

使用By类定位,需要先导入By类。元素定位中的id、name、xpath、class、link_text和css分别在By类定位的语法是By.ID、By.NAME、By.XPATH、By.CLASS_NAME、By.LINK_TEXT和By.CSS_SELECTOR,示例如下:

from selenium import webdriver
from selenium.webdriver.common.by import By  # 导入By类
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.find_element(By.ID,'kw').send_keys('大道至简')
driver.find_element(By.ID,'kw').click()

By类定位的统一语法是find_element(By.ID,'kw'),即通过id定位百度文本框,kw是文本框的id属性值。By类中的元素定位方法要注意区分大小写。

2.3.4 使用JavaScript定位

JavaScript提供了多种元素定位方式,如getElementsByClassName()、getElementByID()、getElementsByName()、getElementsByTagName()和document.querySelectorAll()等。除getElementByID()定位返回单个elements元素定位外,其他的定位方式都是返回list对象,如图2.16所示。

034-01.jpg

图2.16 简书登录界面

示例如下:

from selenium import webdriver
import time as t
dr = webdriver.Chrome()
dr.get('https://www.jianshu.com/sign_in')
t.sleep(2)
# 单击“注册”按钮
js_register = 'document.getElementById("js-sign-up-btn").click();'
dr.execute_script(js_register)
t.sleep(2)

使用document.getElementById()方法定位“注册”按钮,其中execute_script()方法用于调用js方法来执行JavaScript脚本。

# 单击“登录”按钮
js_class = 'document.getElementsByClassName("active")[0].click();'
dr.execute_script(js_class)
t.sleep(2)

使用getElementsByClassName()方法定位“登录”按钮,该方法返回一个list对象,其中[0]表示获取第一个class属性的元素。

js_input = 'document.getElementsByTagName("input")[2].value="username";'  
dr.execute_script(js_input)
t.sleep(2)

使用getElementsByTagName()方法定位账号文本框,其中[2]表示获取整个页面的第三个input标签,value="username"表示向文本框输入账号为username。

# 使用js 标签名定位输入密码框
js_passwd = 'document.getElementsByTagName("input")[3].value="password";'  # [3]索引值为3 
dr.execute_script(js_passwd)
t.sleep(2)

使用document.getElementsByTagName()方法定位密码文本框,其中[3]表示获取整个页面的第四个input标签,value="password"表示向文本框输入密码为password。

2.3.5 使用JQuery定位

JQuery是JavaScript中的一个库,JQuery中的css选择器经常会用于元素定位中的策略,示例如下:

# 定位登录链接
js_class = 'document.getElementsByClassName("active")[0].click();'
dr.execute_script(js_class)
t.sleep(2)
# 定位账号文本框,输入“username”
js_input = 'document.getElementsByTagName("input")[2].value="username";' dr.execute_
script(js_input)
t.sleep(2)
# 定位密码文本框,输入“password”
# js_passwd = 'document.getElementsByTagName("input")[3].value="password";'
dr.execute_script(js_passwd)
t.sleep(2)
# 使用css选择器定位“登录”按钮
css_btn = 'document.querySelectorAll(".sign-in-button")[0].click();'
dr.execute_script(css_btn)

JQuery定位语法可以统一用document.querySelectorAll()来表示,该方法返回的是一个list对象,其中.sign-in-button表示“登录”按钮本身的class属性,[0]表示返回第一个元素对象。 T5C4aiI0UGUXHVVVXjoifzkYxHK4bi2z/KOtFbZx34efmnqITbtzjYJ6qGKK6Ffv

点击中间区域
呼出菜单
上一章
目录
下一章
×