用通俗的方式描述自动化测试那就是用代码控制页面上的控件来完成测试任务,要控制它就要知道它在哪,于是必须要定位它,定位到它之后把它封装成对象,成为对象后它就可以执行任务,实际上所谓自动化测试就是这个过程,那么定位元素就是自动化的测试一个很重要的开端,也是重中之重
随着浏览器的更新迭代,其本身自带的工具就可以完全满足我们对前端代码的定位工作,以Chrome浏览器为例如图所示,能够通过鼠标找到并打开开发者工具,也可以通过快捷键Ctrl+Shift+I打开它亦或者直接F12打开它。
如果读者使用的是Firefox浏览器,则如图所示通过鼠标找到并打开查看器,也可以使用快捷键Ctrl+Shift+C打开它亦或是直接F12打开它。
如果读者使用的是IE浏览器,则如图所示通过鼠标找到并打开F12开发人员工具,或是直接F12打开它。
元素定位,实际上就是要定位到要我们要控制的页面元素的HTML代码,其HTML代码中包含了该元素的种种属性,通过获得其属性值而定位到元素的位置。上一小节中介绍了3个浏览器获取页面元素定位的基础工具,本小节来看看如何使用它获取页面元素的实际HTML属性。
如果读者使用的是Chrome,首先使用浏览器打开百度主页及http://www.baidu.com,然后根据上一小节的介绍打开了开发者工具后,使用鼠标左键点击开发者工具工具栏中的第一个按钮,也可以是用快捷键Ctrl+Shift+C触发该按钮,然后将鼠标移动到页面上想要获取的元素上并单机鼠标左键,这个时候开发者工具会自动跳转到该元素的HTML代码行,例如我们要获取的页面元素是百度主页的“百度一下”按钮
开发这工具自动定位到“百度一下”按钮的HTML代码行,能够看到其HTML属性
如果读者使用的是Firefox,首先使用浏览器打开百度主页及http://www.baidu.com,然后根据上一小节的介绍打开了查看器后,使用鼠标左键点击查看器工具栏中的第一个按钮,也可以是用快捷键Ctrl+Shift+C触发该按钮,然后将鼠标移动到页面上想要获取的元素上并单机鼠标左键,这个时候查看器会自动跳转到该元素的HTML代码行,例如我们要获取的页面元素是百度主页的“百度一下”按钮
查看器自动定位到“百度一下”按钮的HTML代码行,能够看到其HTML属性
如果读者使用的是IE,首先使用浏览器打开百度主页及http://www.baidu.com,然后根据上一小节的介绍打开了F12开发人员工具后,使用鼠标左键点击查看器工具栏中的第一个按钮,也可以是用快捷键Ctrl+B触发该按钮,然后将鼠标移动到页面上想要获取的元素上并单机鼠标左键,这个时候开发人员工具会自动跳转到该元素的HTML代码行,例如要获取的页面元素是百度主页的“百度一下”按钮
开发人员工具自动定位到“百度一下”按钮的HTML代码行,能够看到其HTML属性
本节将详细介绍使用ID定位页面元素,并定制一个简单的场景结合实例代码讲解如何通过元素ID来定位页面元素,并在定位到页面元素后使用定位到的元素完成工作。
Selenium的Webdriver在使用ID定位时所用的语法如下,看到语法后,继续往后看我们是怎么实际使用该语法的。
driver.find_element_by_id(self, value) # webdriver类中find_element_by_id(self, value)函数
driver.fine_element(self, by, value) # webdriver类中find_element(self, by, value)函数
首先使用浏览器工具获取页面元素HTML属性,获取页面元素id后,完成场景百度搜索关键字“davieyang”
>>> from selenium import webdriver # 从selenium模块中导入webdriver类
>>> chrome_driver = webdriver.Chrome() # 初始化Chrome浏览器驱动并启动Chrome浏览器
DevToolslisteningon ws://127.0.0.1:38316/devtools/browser/cb85fe38-768d-4d2b-8ac5-0f46409603f5
>>> chrome_driver.get("http://www.baidu.com") # 打开百度首页
# 输入__davieyang__
>>> chrome_driver.find_element_by_id("kw").send_keys("__davieyang__")
>>> chrome_driver.find_element_by_id("su").click() # 点击“百度一下“按钮
也可以使用第二种语法完成该场景。
>>> from selenium import webdriver # 从selenium模块中导入webdriver类
>>> chrome_driver = webdriver.Chrome() # 初始化Chrome浏览器驱动并启动Chrome浏览器
DevToolslisteningon ws://127.0.0.1:38316/devtools/browser/cb85fe38-768d-4d2b-8ac5-0f46409603f5
>>> chrome_driver.get("http://www.baidu.com") # 打开百度首页
>>> chrome_driver.find_element(by="id", value="kw").send_keys("__davieyang__")
>>> chrome_driver.find_element(by="id", value="su").click()
本节将详细介绍使用Name定位页面元素,并定制一个简单的场景结合实例代码讲解如何通过元素Name来定位页面元素,并在定位到页面元素后使用定位到的元素完成工作。
Selenium的Webdriver在使用Name定位时所用的语法如下,看到语法后,继续往后看我们是怎么实际使用该语法的。
driver.find_element_by_name(self,name)# webdriver类中find_element_by_name(self,value)函数
driver.find_element(self,by,value) # webdriver类中find_element (self, by, value)函数
首先使用浏览器工具获取页面元素HTML属性,获取页面元素name后,完成场景通过百度首页进入百度新闻页面。
>>> from selenium import webdriver # 从selenium模块中导入webdriver类
>>> chrome_driver = webdriver.Chrome() # 初始化Chrome浏览器驱动并启动Chrome浏览器
DevToolslisteningon ws://127.0.0.1:38316/devtools/browser/cb85fe38-768d-4d2b-8ac5-0f46409603f5
>>> chrome_driver.get("http://www.baidu.com") # 打开百度首页
>>> chrome_driver.find_element_by_name("tj_trnews").click() # 点击“新闻“链接
也可以使用第二种语法完成该场景。
>>> from selenium import webdriver # 从selenium模块中导入webdriver类
>>> chrome_driver = webdriver.Chrome() # 初始化Chrome浏览器驱动并启动Chrome浏览器
DevToolslisteningon ws://127.0.0.1:38316/devtools/browser/cb85fe38-768d-4d2b-8ac5-0f46409603f5
>>> chrome_driver.get("http://www.baidu.com") # 打开百度首页
>>> chrome_driver.find_element(by="name", value=" tj_trnews”).click() # 点击“新闻“链接
本节将详细介绍使用Class定位页面元素,并定制一个简单的场景结合实例代码讲解如何通过元素Class来定位页面元素,并在定位到页面元素后使用定位到的元素完成工作。
Selenium的Webdriver在使用Class定位时所用的语法如下,看到语法后,继续往后看我们是怎么实际使用该语法的。
# webdriver类中find_element_by_class_name(self,value)函数
driver.find_element_by_class_name(self, value)
首先使用浏览器工具获取页面元素HTML属性,获取页面元素class后,完成场景:百度搜索关键字“davieyang”。
>>> from selenium import webdriver # 从selenium模块中导入webdriver类
>>> chrome_driver = webdriver.Chrome() # 初始化Chrome浏览器驱动并启动Chrome浏览器
DevToolslisteningon ws://127.0.0.1:38316/devtools/browser/cb85fe38-768d-4d2b-8ac5-0f46409603f5
>>> chrome_driver.get("http://www.baidu.com") # 打开百度首页
# 输入__davieyang__
>>> chrome_driver.find_element_by_class_name("s_ipt").send_keys("__davieyang__")
# 点击“百度一下“按钮
>>> chrome_driver.find_element_by_class_name("bg s_btn").send_keys("__davieyang__")
本节将详细介绍使用Tag定位页面元素,并定制一个简单的场景结合实例代码讲解如何通过元素Tag来定位页面元素,并在定位到页面元素后使用定位到的元素完成工作。
Selenium的Webdriver在使用Tag定位时所用的语法如下,看到语法后,继续往后看我们是怎么实际使用该语法的。
# webdriver类中find_element_by_tag_name(self,value)函数
driver.find_element_by_tag_name(self, value)
页面上的标签诸如“
# webdriver类中find_elements_by_class_name(self,value)函数
driver.find_elements_by_tag_name(self, value)
然后将一组标签放到List中,再由索引来定位唯一的元素,并且前提是已知索引是多少或者说工程师知道元素在第几个标签里。
首先使用浏览器工具获取页面元素HTML属性,获取页面元素tag后,完成场景:百度搜索关键字“davieyang”
>>> from selenium import webdriver # 从selenium模块中导入webdriver类
>>> chrome_driver = webdriver.Chrome() # 初始化Chrome浏览器驱动并启动Chrome浏览器
>>> chrome_driver.get("http://www.baidu.com") # 打开百度首页
# 页面中input标签很多,因此全部获取后并将其放在input_list列表中
>>> input_list = chrome_driver.find_element_by_tag_name("input")
# 输入框在第8个input标签,使用list索引7获取并输入__davieyang__
>>> input_list[7].send_keys("__davieyang__")
# “百度一下“按钮在第9个input标签,使用list索引8获取并点击
>>> input_list[8].click()
本节将详细介绍使用Link定位页面元素,并定制一个简单的场景结合实例代码讲解如何通过元素Link来定位页面元素,并在定位到页面元素后使用定位到的元素完成工作。
Selenium的Webdriver在使用link_text定位时所用的语法如下,看到语法后,继续往后看我们是怎么实际使用该语法的
# webdriver类中find_element_by_link_text(self, link_text)函数
driver.find_element_by_link_text(self,link_text)
首先使用浏览器工具获取页面元素HTML属性,获取页面元素link_text后,完成场景:通过百度首页进入百度新闻页面
>>> from selenium import webdriver # 从selenium模块中导入webdriver类
>>> chrome_driver = webdriver.Chrome() # 初始化Chrome浏览器驱动并启动Chrome浏览器
DevToolslisteningon ws://127.0.0.1:38316/devtools/browser/cb85fe38-768d-4d2b-8ac5-0f46409603f5
>>> chrome_driver.get("http://www.baidu.com") # 打开百度首页
>>> chrome_driver.find_element_by_link_text("新闻").click() # 点击“新闻“链接
本节将详细介绍使用Partial Link定位页面元素,并定制一个简单的场景结合实例代码讲解如何通过元素Partial Link来定位页面元素,并在定位到页面元素后使用定位到的元素完成工作。
Selenium的Webdriver在使用partial_link_text定位时所用的语法如下,看到语法后,继续往后看我们是怎么实际使用该语法的。
# webdriver类中find_element_by_partial_link_text(self, partial_link_text)函数
# partial link text定位时,只需要输入文字链接的部分内容即可, 而link_text则要输入全部
driver.find_element_by_partial_link_text(self, partial_link_text)
首先使用浏览器工具获取页面元素HTML属性,获取页面元素link_text后,完成场景:通过百度首页进入百度新闻页面。
>>> from selenium import webdriver # 从selenium模块中导入webdriver类
>>> chrome_driver = webdriver.Chrome() # 初始化Chrome浏览器驱动并启动Chrome浏览器
DevToolslisteningon ws://127.0.0.1:38316/devtools/browser/cb85fe38-768d-4d2b-8ac5-0f46409603f5
>>> chrome_driver.get("http://www.baidu.com") # 打开百度首页
>>> chrome_driver.find_element_by_partial _link_text("新").click() # 点击“新闻“链接
本节将详细介绍使用Xpath定位页面元素,并定制一个简单的场景结合实例代码讲解如何通过元素Xpath来定位页面元素,并在定位到页面元素后使用定位到的元素完成工作。
首先Xpath是一门语言,用于在XML结构的文档中通过路径来查找文档中的节点,而HTML也具备XML的结构,因此可以使用Xpath进行HTML结构中进行节点的定位。
既然是一种通过路径定位内容的语言,就要区分绝对路径和相对路径,而绝对路径的概念就像找一个门牌号码,从最高层节点开始找起XX城市XX区XX街XX院XX号楼XX单元XX号,这样找起来一定是唯一的;而相对路径的概念则是A相对B的位置,以B为起点找A的位置,而不是从根节点开始找起。
Selenium的Webdriver在使用xpath定位时所用的语法如下,看到语法后,继续往后看我们是怎么实际使用该语法的。
# webdriver类中find_element_by_xpath(self, xpath)函数
driver.find_element_by_xpath(self,xpath)
为了更好的掌握Xpath知识,请新建一个文本文件并命名为xpath.html,然后将如下HTML代码复制黏贴到文件中并保存,注意将文件的扩展名修改为html,如此便可以用浏览器打开该html格式的文件,本小节介绍的Xpath基本语法完全基于该文件中的元素而进行Xpath的定位练习。
<html>
<body>
<br>
<div id="div1" style="text-align:center">
<img alt="div1-img1" src="http://www.sogou.com/images/logo/new/sogou.png"
href="http://www.sogou.com">img><br/>
<input name="div1input">
<a href="http://www.sogou.com">搜狗搜索a>
<input type="button" value="查询">
div>
<br>
<div name="div2" style="text-align:center">
<img alt="div2-img2" src="http://www.baidu.com/img/bdlogo.png"
href="http://www.baidu.com">img>br>
<input name="div2input">
<a href="http://www.baidu.com">百度搜索a>
div>
body>
html>
基于以上HTML代码,采用多种Xpath对元素进行定位,读者可根据注释逐一比较不同Xpath之间的区别,实际上感受到了Xpath的灵活之后,也同样体会到Xpath远比想象中要复杂的多,面对自动化测试中的使用,掌握如下方式已经足以满足我们使用Xpath对元素进行定位。
# 通过绝对路径获取元素 定位查询按钮
driver.find_element_by_xpath("/html/body/div/input[@value='查询']")
# 通过相对路径获取元素 定位查询按钮
driver.find_element_by_xpath("//input[@value='查询']")
# 通过索引号定位元素 定位查询按钮
driver.find_element_by_xpath("//input[2]") # 可用于定位多个,无论页面分了多少层,每层的第一个input都会被定位到
# 通过索引高级定位 定位第二个div下的超链接
driver.find_element_by_xpath("//div[last()]/a") # div[last()]表示最后一个div元素,last()函数获取的是指定元素的最后的索引号
# 通过索引高级定位 定位第一个div下的超链接
driver.find_element_by_xpath("//div[last()-1]/a") # 表示倒数第二个div元素
# 通过索引高级定位 定位最前面一个属于div元素的子元素中的input元素
driver.find_element_by_xpath("//div/input[position()<2]") # position()函数获取当前元素input的位置序列号
# 通过元素属性值定位
driver.find_element_by_xpath("//img[@href='http://www.sogou.com']")
driver.find_element_by_xpath("//div[@name='div2']/input[@name='div2input']")
driver.find_element_by_xpath("//div[@id='div1']/a[@href='http://www.sogou.com']")
driver.find_element_by_xpath("//input[@type='button']")
# 高级应用之模糊匹配
"""
在自动化测试的实施过程中,常常会遇到页面元素的属性值是动态生成的,每次访问属性值都不一样,此类页面元素定位难度大
假如存在属性值中有一部分内容保持不变,则可以使用模糊匹配
"""
# starts-with(str1, str2) 查找属性alt的属性值为div1关键字开始的页面元素
driver.find_element_by_xpath("//img[start-with(@alt, 'div1')]")
# contains(str1, str2)查找属性alt的属性值包含img关键字的页面元素,只包含即可无需考虑位置
driver.find_element_by_xpath("//img[contains(@alt, 'img')]")
# Xpath轴(Axes)定位元素
"""
轴可以定义相对于当前节点的节点集,使用Axes定位方式可以根据在文档树中的元素相对位置关系进行页面元素定位
及:先找到一个相对好定位的元素,让它作为轴,根据它和要定位元素的相对位置关系进行定位
"""
# 选择当前节点的上层父节点 parent:先获取alt属性值为div2-img2的img元素,基于该元素的位置找到它上一级的div元素
driver.find_element_by_xpath("//img[@alt='div2-img2']/parent::div")
# 选择当前节点的下层所有子节点 child: 原理同上 先获取id属性值威div1的div元素,基于该元素的位置找到它下层节点中的img元素
driver.find_element_by_xpath("//div[@id='div1']/child::img")
# 选择当前节点所有上层的节点 ancestor: 基于img元素的位置找到它上级的div元素
driver.find_element_by_xpath("//img[@alt='div2-img2']/ancestor::div")
# 选择当前节点所有下层的节点(子,孙等)descendant: 基于div的位置找到它下级所有节点中的img元素
driver.find_element_by_xpath("//div[@name='div2']/descendant::img")
# 选择在当前节点之后显示的所有节点 following: 基于div的位置,获取它后面节点中的img元素
driver.find_element_by_xpath("div[@id='div1']/following::img")
# 选择当前节点后续所有兄弟节点 following-sibling: 基于超链接的位置找到它后续兄弟节点中的input元素
driver.find_element_by_xpath("//a[@href='http://www.sogou.com']/following-sibling::input")
# 选择当前节点前面的所有节点 preceding: 基于img的位置找到它前面节点中的div元素
driver.find_element_by_xpath("//img[@alt='div2-img2']/preceding::div")
# 选择当前节点前面的所有兄弟节点 preceding-sibling: 基于input的位置,找到它前面同级节点中的第一个超链接元素
driver.find_element_by_xpath("//input[@value='查询']/preceding-sibling::a[1]")
# 通过text()函数获取页面元素的文本并定位元素 如下1和2等价 3和4等价 5和6等价
driver.find_element_by_xpath("//a[text()='搜狗搜索']")
driver.find_element_by_xpath("//a[.='搜狗搜索']")
driver.find_element_by_xpath("//a[contains(., '百度')]")
driver.find_element_by_xpath("//a[contains(test(), '百度')]")
driver.find_element_by_xpath("//a[contains(text(), '百度')]/preceding::div")
driver.find_element_by_xpath("//a[contains(., '百度')]/..")
如果使用Chrome浏览器,打开开发者工具后,在元素的HTML代码行点击鼠标右键,找到Copy选项,然后在展开的菜单中选择Copy Xpath即可将该元素的Xpath复制出来使用
如果使用Firefox浏览器,打开查看器后,在元素的HTML代码行点击鼠标右键,找到复制选项,然后在展开的菜单中选择Xpath,即可将该元素的Xpath复制出来使用
借助浏览器工具,获取Xpath并完成场景:百度搜索关键字“davieyang”。
>>> from selenium import webdriver # 从selenium模块中导入webdriver类
>>> chrome_driver = webdriver.Chrome() # 初始化Chrome浏览器驱动并启动Chrome浏览器
>>> chrome_driver.get("http://www.baidu.com") # 打开百度首页
# 输入__davieyang__
>>> chrome_driver.find_element_by_xpath("//*[@id='kw']").send_keys("__davieyang__")
# 点击“百度一下“按钮
>>> chrome_driver.find_element_by_xpath("//*[@id='su']").click()
本节将详细介绍使用CSS(Cascading Style Sheets)定位页面元素,并定制一个简单的场景结合实例代码讲解如何通过元素CSS来定位页面元素,并在定位到页面元素后使用定位到的元素完成工作。
Selenium的Webdriver在使用css定位时所用的语法如下,看到语法后,继续往后看我们是怎么实际使用该语法的
# webdriver类中find_element_by_css_selector(self, css_selector)函数
driver.find_element_by_css_selector(self,css_selector)
如果使用Chrome浏览器,打开开发者工具后,在元素的HTML代码行点击鼠标右键,找到Copy选项,然后在展开的菜单中选择Copy selector即可将该元素的css selector复制出来使用
如果使用Firefox浏览器,打开查看器后,在元素的HTML代码行点击鼠标右键,找到复制选项,然后在展开的菜单中选择CSS 选择器,即可将该元素的css selector复制出来使用
借助浏览器工具,获取css selector并完成场景:百度搜索关键字“davieyang”
>>> from selenium import webdriver # 从selenium模块中导入webdriver类
>>> chrome_driver = webdriver.Chrome() # 初始化Chrome浏览器驱动并启动Chrome浏览器
DevToolslisteningon ws://127.0.0.1:38316/devtools/browser/cb85fe38-768d-4d2b-8ac5-0f46409603f5
>>> chrome_driver.get("http://www.baidu.com") # 打开百度首页
# 输入__davieyang__
>>> chrome_driver.find_element_by_css_selector("#kw").send_keys("__davieyang__")
# 点击“百度一下“按钮
>>> chrome_driver.find_element_by_css_selector("#su").click()
在selenium.webdriver.common.by里还提供了By类用于定位页面元素,而实际上它与前面讲的方法也仅仅是写法上的不同
Find_element(By.ID, “value”)
Find_element(By,NAME, “value”)
Find_element(By.CLASS_NAME, “value”)
Find_element(By.TAG_NAME, “value”)
Find_element(By.LINK_TEXT, “link text”)
Find_element(By.PARTIAL_LINK_TEXT, “partial link text”)
Find_element(By.XPATH, “xpath”)
Find_element(By.CSS_SELECTOR, “css_selector”)