Python自動化測試系列[v1.0.0][元素定位]

用通俗的方式描述自動化測試那就是用代碼控制頁面上的控件來完成測試任務,要控制它就要知道它在哪,於是必須要定位它,定位到它之後把它封裝成對象,成爲對象後它就可以執行任務,實際上所謂自動化測試就是這個過程,那麼定位元素就是自動化的測試一個很重要的開端,也是重中之重

  • Webdriver爲我們提供了8種定位頁面元素的方法,分別是id、name、class name、tag name、link text、partial link text、xpath、css selector。一般情況下id和name最爲常用也最簡單,link text和partial link text也用於定位文字鏈接最爲好用,xpath和css selector最靈活最萬能也最複雜,理論上講8種定位方法完全可以滿足自動化測試工作。
  • 然而在實際工作中,往往要取決於前端代碼的規範程度,並不是所有前端工程師在寫頁面代碼時都會給元素加上id或者name,很多情況下讓自動化測試工程師不得不經常性的使用xpath進行元素定位工作。
  • 也因此對於初學者而言,想要勝任自動化測試工程師的崗位,在訓練自己基本功的時候就更加要下功夫,多多的進行命令行編寫定位的訓練,多多的遇見異常情況,快快的積累經驗方位上策

元素定位工具

隨着瀏覽器的更新迭代,其本身自帶的工具就可以完全滿足我們對前端代碼的定位工作,以Chrome瀏覽器爲例如圖所示,能夠通過鼠標找到並打開開發者工具,也可以通過快捷鍵Ctrl+Shift+I打開它亦或者直接F12打開它。

圖4.1  開發者工具
如果讀者使用的是Firefox瀏覽器,則如圖所示通過鼠標找到並打開查看器,也可以使用快捷鍵Ctrl+Shift+C打開它亦或是直接F12打開它。
圖4.2  查看器
如果讀者使用的是IE瀏覽器,則如圖所示通過鼠標找到並打開F12開發人員工具,或是直接F12打開它。
在這裏插入圖片描述

元素HTML定位

元素定位,實際上就是要定位到要我們要控制的頁面元素的HTML代碼,其HTML代碼中包含了該元素的種種屬性,通過獲得其屬性值而定位到元素的位置。上一小節中介紹了3個瀏覽器獲取頁面元素定位的基礎工具,本小節來看看如何使用它獲取頁面元素的實際HTML屬性。
如果讀者使用的是Chrome,首先使用瀏覽器打開百度主頁及http://www.baidu.com,然後根據上一小節的介紹打開了開發者工具後,使用鼠標左鍵點擊開發者工具工具欄中的第一個按鈕,也可以是用快捷鍵Ctrl+Shift+C觸發該按鈕,然後將鼠標移動到頁面上想要獲取的元素上並單機鼠標左鍵,這個時候開發者工具會自動跳轉到該元素的HTML代碼行,例如我們要獲取的頁面元素是百度主頁的“百度一下”按鈕
在這裏插入圖片描述
開發這工具自動定位到“百度一下”按鈕的HTML代碼行,能夠看到其HTML屬性
<input type="submit" id="su" value="百度一下" class="bg s_btn">
如果讀者使用的是Firefox,首先使用瀏覽器打開百度主頁及http://www.baidu.com,然後根據上一小節的介紹打開了查看器後,使用鼠標左鍵點擊查看器工具欄中的第一個按鈕,也可以是用快捷鍵Ctrl+Shift+C觸發該按鈕,然後將鼠標移動到頁面上想要獲取的元素上並單機鼠標左鍵,這個時候查看器會自動跳轉到該元素的HTML代碼行,例如我們要獲取的頁面元素是百度主頁的“百度一下”按鈕
在這裏插入圖片描述
查看器自動定位到“百度一下”按鈕的HTML代碼行,能夠看到其HTML屬性
<input type="submit" id="su" value="百度一下" class="bg s_btn">
如果讀者使用的是IE,首先使用瀏覽器打開百度主頁及http://www.baidu.com,然後根據上一小節的介紹打開了F12開發人員工具後,使用鼠標左鍵點擊查看器工具欄中的第一個按鈕,也可以是用快捷鍵Ctrl+B觸發該按鈕,然後將鼠標移動到頁面上想要獲取的元素上並單機鼠標左鍵,這個時候開發人員工具會自動跳轉到該元素的HTML代碼行,例如要獲取的頁面元素是百度主頁的“百度一下”按鈕
在這裏插入圖片描述
開發人員工具自動定位到“百度一下”按鈕的HTML代碼行,能夠看到其HTML屬性
<input type="submit" id="su" value="百度一下" class="bg s_btn">

元素ID定位

本節將詳細介紹使用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定位頁面元素,並定製一個簡單的場景結合實例代碼講解如何通過元素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定位頁面元素,並定製一個簡單的場景結合實例代碼講解如何通過元素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定位頁面元素,並定製一個簡單的場景結合實例代碼講解如何通過元素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定位頁面元素,並定製一個簡單的場景結合實例代碼講解如何通過元素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定位頁面元素,並定製一個簡單的場景結合實例代碼講解如何通過元素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來定位頁面元素,並在定位到頁面元素後使用定位到的元素完成工作。

Xpath含義

首先Xpath是一門語言,用於在XML結構的文檔中通過路徑來查找文檔中的節點,而HTML也具備XML的結構,因此可以使用Xpath進行HTML結構中進行節點的定位。
既然是一種通過路徑定位內容的語言,就要區分絕對路徑和相對路徑,而絕對路徑的概念就像找一個門牌號碼,從最高層節點開始找起XX城市XX區XX街XX院XX號樓XX單元XX號,這樣找起來一定是唯一的;而相對路徑的概念則是A相對B的位置,以B爲起點找A的位置,而不是從根節點開始找起。

Xpath基本語法

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(., '百度')]/..")

獲取元素Xpath

如果使用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定位

本節將詳細介紹使用CSS(Cascading Style Sheets)定位頁面元素,並定製一個簡單的場景結合實例代碼講解如何通過元素CSS來定位頁面元素,並在定位到頁面元素後使用定位到的元素完成工作。

CSS定位語法

Selenium的Webdriver在使用css定位時所用的語法如下,看到語法後,繼續往後看我們是怎麼實際使用該語法的

#  webdriver類中find_element_by_css_selector(self, css_selector)函數
driver.find_element_by_css_selector(self,css_selector)

獲取元素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() 

By方法定位

在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”)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章