测试开发面试准备之python selenium API
?
一、瀏覽器操作
1、瀏覽器最大化
driver.maximize_window() #將瀏覽器最大化顯示2、設(shè)置瀏覽器寬、高
driver.set_window_size(480, 800)#設(shè)置瀏覽器寬480、高800顯示3、控制瀏覽器前進、后退
driver.back()#瀏覽器后退 driver.forward()#瀏覽器前進二、簡單對象的定位
webdriver 提供了一系列的元素定位方法,常用的有以下幾種:
- ?id
- ?name
- ?class name
- ?tag name
- ?link text
- ?partial link text
- ?xpath
- ?css selector
分別對應(yīng)python webdriver 中的方法為:
- find_element_by_id()
- find_element_by_name()
- find_element_by_class_name()
- find_element_by_tag_name()
- find_element_by_link_text()
- find_element_by_partial_link_text()
- find_element_by_xpath()
- find_element_by_css_selector()
?
1、id 和name 定位
id 和name 是我們最常用的定位方式,因為大多數(shù)元素都有這兩個屬性,而且在對控件的id 和name
命名時一般使其有意義也會取不同的名字。通過這兩個屬性使我們找一個頁面上的屬性變得相當容易。
比如:
#id=”gs_htif0” find_element_by_id("gs_htif0") #name=”btnK” find_element_by_name("btnK")2、tag name 和class name 定位
比如:
#<div id="searchform" class="jhp_big" style="margin-top:-2px"> #<form id="tsf" οnsubmit="return name="f" method="GET" action="/search"> find_element_by_class_name("jhp_big") find_element_by_tag_name("div")tag name 定位應(yīng)該是所有定位方式中最不靠譜的一種了,因為在一個頁面中具有相同tag name 的元
素極其容易出現(xiàn)。
3、link text 與partial link text 定位
有時候需要操作的元素是一個文字鏈接,那么我們可以通過link text 或partial link text 進行元素
定位。比如:
當一個文字連接很長時,我們可以只取其中的一部分,只要取的部分可以唯一標識元素。一般一個頁
面上不會出現(xiàn)相同的文件鏈接,通過文字鏈接來定位元素也是一種簡單有效的定位方式。
4、XPath 定位
XPath 是一種在XML 文檔中定位元素的語言。因為HTML 可以看做XML 的一種實現(xiàn),所以selenium 用
戶可是使用這種強大語言在web 應(yīng)用中定位元素。
以下面一段html代碼為例:
<html class="w3c"> <body><div class="page-wrap"> <div id="hd" name="q"> <form target="_self" action="http://www.so.com/s"> <span id="input-container"> <input id="input" type="text" x-webkit-speech="" autocomplete="off" suggestwidth="501px" >(1)使用絕對路徑定位:
當我們所要定位的元素很難找到合適的方式時,都可以通這種絕對路徑的方式位,缺點是當元素在很
多級目錄下時,我們不得不要寫很長的路徑,而且這種方式難以閱讀和維護。
(2)使用相對路徑定位:
find_element_by_xpath("//input[@id=’input’]") #通過自身的id 屬性定位 find_element_by_xpath("//span[@id=’input-container’]/input") #通過上一級目錄的id 屬性定位 find_element_by_xpath("//div[@id=’hd’]/form/span/input") #通過上三級目錄的id 屬性定位 find_element_by_xpath("//div[@name=’q’]/form/span/input")#通過上三級目錄的name 屬性定位通過上面的例子,我們可以看到XPath 的定位方式非常靈活和強大的,XPath 可以做布爾邏輯運算,例如://div[@id=’hd’ or @name=’q’]。
當然,它的缺陷也非常明顯:
1、性能差,定位元素的性能要比其它大多數(shù)方式差;
2、不夠健壯,XPath會隨著頁面元素布局的改變而改變;
3. 兼容性不好,在不同的瀏覽器下對XPath 的實現(xiàn)是不一樣的。
?
下面插播一下xpath的知識:
(1)路徑表達式:
| nodename | 選取此節(jié)點的所有子節(jié)點。 |
| / | 從根節(jié)點選取。 |
| // | 從匹配選擇的當前節(jié)點選擇文檔中的節(jié)點,而不考慮它們的位置。 |
| . | 選取當前節(jié)點。 |
| .. | 選取當前節(jié)點的父節(jié)點。 |
| @ | 選取屬性。 |
實例
在下面的表格中,我們已列出了一些路徑表達式以及表達式的結(jié)果:
| bookstore | 選取 bookstore 元素的所有子節(jié)點。 |
| /bookstore | 選取根元素 bookstore。 注釋:假如路徑起始于正斜杠( / ),則此路徑始終代表到某元素的絕對路徑! |
| bookstore/book | 選取屬于 bookstore 的子元素的所有 book 元素。 |
| //book | 選取所有 book 子元素,而不管它們在文檔中的位置。 |
| bookstore//book | 選擇屬于 bookstore 元素的后代的所有 book 元素,而不管它們位于 bookstore 之下的什么位置。 |
| //@lang | 選取名為 lang 的所有屬性。 |
實例
在下面的表格中,我們列出了帶有謂語的一些路徑表達式,以及表達式的結(jié)果:
| /bookstore/book[1] | 選取屬于 bookstore 子元素的第一個 book 元素。 |
| /bookstore/book[last()] | 選取屬于 bookstore 子元素的最后一個 book 元素。 |
| /bookstore/book[last()-1] | 選取屬于 bookstore 子元素的倒數(shù)第二個 book 元素。 |
| /bookstore/book[position()<3] | 選取最前面的兩個屬于 bookstore 元素的子元素的 book 元素。 |
| //title[@lang] | 選取所有擁有名為 lang 的屬性的 title 元素。 |
| //title[@lang='eng'] | 選取所有 title 元素,且這些元素擁有值為 eng 的 lang 屬性。 |
| /bookstore/book[price>35.00] | 選取 bookstore 元素的所有 book 元素,且其中的 price 元素的值須大于 35.00。 |
| /bookstore/book[price>35.00]/title | 選取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值須大于 35.00。 |
(2)選取未知節(jié)點
XPath 通配符可用來選取未知的 XML 元素。
| * | 匹配任何元素節(jié)點。 |
| @* | 匹配任何屬性節(jié)點。 |
| node() | 匹配任何類型的節(jié)點。 |
實例
在下面的表格中,我們列出了一些路徑表達式,以及這些表達式的結(jié)果:
| /bookstore/* | 選取 bookstore 元素的所有子元素。 |
| //* | 選取文檔中的所有元素。 |
| //title[@*] | 選取所有帶有屬性的 title 元素。 |
?
5、CSS 定位
CSS(Cascading Style Sheets)是一種語言,它被用來描述HTML 和XML 文檔的表現(xiàn)。CSS 使用選擇器來為頁面元素綁定屬性。這些選擇器可以被selenium 用作另外的定位策略。CSS 可以比較靈活選擇控件的任意屬性,一般情況下定位速度要比XPath 快,但對于初學(xué)者來說比較難以學(xué)習(xí)使用,下面我們就詳細的介紹CSS 的語法與使用:
例如下面一段代碼:
<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 語法進行匹配的實例:
關(guān)于自動化的定位問題:
自動化測試的元素定位一直是困擾自動化測試新手的一個障礙,因為我們在自動化實施過程中會碰到
各式各樣的對象元素。雖然XPath 和CSS 可以定位到復(fù)雜且比較難定位的元素,但相比較用id 和name 來
說增加了維護成本和學(xué)習(xí)成本,相比較來說id/name 的定位方式更直觀和可維護,有新的成員加入的自動
化時也增加了人員的學(xué)習(xí)成本。所以,測試人員在實施自動化測試時一定要做好溝通,規(guī)范前端開發(fā)人員
對元素添加id/name 屬性,或者自己有修改HTML 代碼的權(quán)限。
三、操作測試對象
一般來說,所有有趣的操作與頁面交互都將通過WebElement 接口,包括上一節(jié)中介紹的對象定位,
以及本節(jié)中需要介紹的常對象操作。
webdriver 中比較常用的操作元素的方法有下面幾個:
- clear 清除元素的內(nèi)容,如果可以的話
- send_keys 在元素上模擬按鍵輸入
- click 單擊元素
- submit 提交表單
例如:
driver.find_element_by_id("user_name").clear() driver.find_element_by_id("user_name").send_keys("username") driver.find_element_by_id("user_pwd").clear() driver.find_element_by_id("user_pwd").send_keys("password") driver.find_element_by_id("dl_an_submit").click() #通過submit() 來提交操作 #driver.find_element_by_id("dl_an_submit").submit()- clear() 用于清除輸入框的默認內(nèi)容
- send_keys("xx") 用于在一個輸入框里輸入xx 內(nèi)容
- click() 用于單擊一個按鈕、連接等
- submit() 提交表單
1、WebElement 接口常用方法
WebElement 接口除了我們前面介紹的方法外,它還包含了別一些有用的方法。下面,我們例舉例幾
個比較有用的方法。
- size #返回元素的尺寸
- text #獲取元素的文本
- get_attribute(name) #獲得屬性值
- is_displayed() #檢查該元素是否用戶可見
例如:
size=driver.find_element_by_id("kw").size#返回百度輸入框的寬高 text=driver.find_element_by_id("cp").text #返回百度頁面底部備案信息 #返回元素的屬性值,可以是id、name、type 或元素擁有的其它任意屬性 attribute=driver.find_element_by_id("kw").get_attribute('type') #返回元素的結(jié)果是否可見,返回結(jié)果為True 或False result=driver.find_element_by_id("kw").is_displayed()四、鼠標事件
?
前面例子中我們已經(jīng)學(xué)習(xí)到可以用 click()來模擬鼠標的單擊操作,而我們在實際的 web 產(chǎn)品測試中發(fā)現(xiàn),有關(guān)鼠標的操作,不單單只有單擊,有時候還要和到右擊,雙擊,拖動等操作,這些操作包含在ActionChains 類中。
ActionChains 類鼠標操作的常用方法:
- context_click() 右擊
- double_click() 雙擊
- drag_and_drop() 拖動
- move_to_element() 鼠標懸停在一個元素上
- click_and_hold() 按下鼠標左鍵在一個元素上
1、右擊操作
#引入 ActionChains 類 from selenium.webdriver.common.action_chains import ActionChains ... #定位到要右擊的元素 right =driver.find_element_by_xpath("xx") #對定位到的元素執(zhí)行鼠標右鍵操作 ActionChains(driver).context_click(right).perform()ActionChains 用于生成用戶的行為;所有的行為都存儲在 actionchains 對象中。通過 perform()執(zhí)行存儲的行為。
2、鼠標雙擊操作
#引入 ActionChains 類 from selenium.webdriver.common.action_chains import ActionChains ... #定位到要雙擊的元素 double =driver.find_element_by_xpath("xxx") #對定位到的元素執(zhí)行鼠標雙擊操作 ActionChains(driver).double_click(double).perform()3、鼠標拖放操作
drag_and_drop(source, target)
在源元素上按下鼠標左鍵,然后移動到目標元素上釋放。
source: 鼠標按下的源元素。
target: 鼠標釋放的目標元素。
4、鼠標移動上元素上
#引入 ActionChains 類 from selenium.webdriver.common.action_chains import ActionChains ... #定位到鼠標移動到上面的元素 above = driver.find_element_by_xpath("xxx") #對定位到的元素執(zhí)行鼠標移動到上面的操作 ActionChains(driver).move_to_element(above).perform()5、按下鼠標左鍵
#引入 ActionChains 類 from selenium.webdriver.common.action_chains import ActionChains ... #定位到鼠標按下左鍵的元素 left=driver.find_element_by_xpath("xxx") #對定位到的元素執(zhí)行鼠標左鍵按下的操作 ActionChains(driver).click_and_hold(left).perform()五、鍵盤事件
from selenium.webdriver.common.keys import Keys #在使用鍵盤按鍵方法前需要先導(dǎo)入 keys 類包。
下面經(jīng)常使用到的鍵盤操作:
- send_keys(Keys.BACK_SPACE) 刪除鍵(BackSpace)
- send_keys(Keys.SPACE) 空格鍵(Space)
- send_keys(Keys.TAB) 制表鍵(Tab)
- send_keys(Keys.ESCAPE) 回退鍵(Esc)
- send_keys(Keys.ENTER) 回車鍵(Enter)
- send_keys(Keys.CONTROL,'a') 全選(Ctrl+A)
- send_keys(Keys.CONTROL,'c') 復(fù)制(Ctrl+C)
- send_keys(Keys.CONTROL,'x') 剪切(Ctrl+X)
- send_keys(Keys.CONTROL,'v') 粘貼(Ctrl+V)
六、獲取頁面的title和url
有時間需要通過頁面的title和url去判斷頁面的狀態(tài)。比如測試登錄是否成功和重定向是否成功。
#獲得前面 title,打印 title = driver.title print title#獲得前面 URL,打印 now_url = driver.current_url print now_url?七、設(shè)置等待時間
有時候為了保證腳本運行的穩(wěn)定性,需要腳本中添加等待時間。
設(shè)置等待時間有以下幾種方法:
- sleep(): 設(shè)置固定休眠時間。 python 的 time 包提供了休眠方法 sleep() , 導(dǎo)入 time包后就可以使用 sleep()進行腳本的執(zhí)行過程進行休眠。
- implicitly_wait():是 webdirver 提供的一個超時等待。隱的等待一個元素被發(fā)現(xiàn),或一個命令完成。如果超出了設(shè)置時間的則拋出異常。
- WebDriverWait():同樣也是 webdirver 提供的方法。在設(shè)置時間內(nèi),默認每隔一段時間檢測一次當前頁面元素是否存在,如果超過設(shè)置時間檢測不到則拋出異常。
1、sleep()休眠方法
當執(zhí)行到sleep()方法時會固定休眠一定的時長,然后再往下執(zhí)行。sleep()方法以秒為單位,假如休眠時間小于 1 秒,可以用小數(shù)表示。
import time .... time.sleep(5) time.sleep(0.5)當然,也可以直接導(dǎo)入 sleep()方法,使腳本中的引用更簡單
from time import sleep .... sleep(3) sleep(30)2、implicitly_wait()
隱式等待是通過一定的時長等待頁面上某元素加載完成。如果超出了設(shè)置的時長元素還沒被加載,則拋出NoSuchElementException異常。implicitly_wait()方法比 sleep() 更加智能,后者只能選擇一個固定的時間的等待,前者可以在一個時間范圍內(nèi)智能的等待。以秒為單位。注意:它并不針對頁面上的某一個元素進行等待,而是從你設(shè)定這個隱式等待開始的所有需要定位的元素。當腳本執(zhí)行到某個元素定位時,如果元素可以定位,則繼續(xù)執(zhí)行;如果元素定位不到,則它將以輪詢的方式不斷判斷元素是否定位到。超過設(shè)定時間拋出異常
?
#添加智能等待30秒 driver.implicitly_wait(30)3、WebDriverWait()
詳細格式如下:
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None),參數(shù)解釋如下:
- driver - WebDriver 的驅(qū)動程序(Ie, Firefox, Chrome 或遠程)
- timeout - 最長超時時間,默認以秒為單位
- poll_frequency - 休眠時間的間隔(步長)時間,默認為 0.5 秒
- ignored_exceptions - 超時后的異常信息,默認情況下拋 NoSuchElementException 異常。
WebDriverWai()一般由 unit()或 until_not()方法配合使用,下面是 unit()和 until_not()方法的說明:
until(method, message=’’)
調(diào)用該方法提供的驅(qū)動程序作為一個參數(shù),直到返回值不為False。
until_not(method, message=’’)
調(diào)用該方法提供的驅(qū)動程序作為一個參數(shù),直到返回值為 False。
?八、定位一組對象
需要獲取頁面上的一組元素是的方法:
#find_elements 用于獲取一組元素。 find_elements_by_id(‘xx’) find_elements_by_name(‘xx’) find_elements_by_class_name(‘xx’) find_elements_by_tag_name(‘xx’) find_elements_by_link_text(‘xx’) find_elements_by_partial_link_text(‘xx’) find_elements_by_xpath(‘xx’) find_elements_by_css_selector(‘xx’)?
?可以使用for... in ...對這一組元素進行遍歷
for checkbox in checkboxes: checkbox.click()我們獲取到一組元素之后也可以使用pop()方法獲得這一組元素中的第幾個,然后再對該元素進行操作:
find_elements_by_id(‘xx’).pop().click()- pop()或pop(-1)默認獲取一組元素中的最后一個
- pop(0) ? 默認獲取一組元素的第一個元素
- pop(1) ? 默認獲取一組元素的第二個元素
- ......以此類推
九、層級定位
在實際的項目測試中,經(jīng)常會有這樣的需求:頁面上有很多個屬性基本相同的元素 ,現(xiàn)在需要具體
定位到其中的一個。由于屬性基本相當,所以在定位的時候會有些麻煩,這時候就需要用到層級定位。先
定位父元素,然后再通過父元素定位子孫元素。
比如下拉列表,我們可以先點擊彈出下拉框然后再定位下拉列表中的選項
#點擊 Link1 鏈接(彈出下拉列表) driver.find_element_by_link_text('Link1').click() #在父親元件下找到 link 為 Action 的子元素 menu = driver.find_element_by_id('dropdown1').find_element_by_link_text('Another action')十、多表單切換
在 web 應(yīng)用中經(jīng)常會出現(xiàn) frame/iframe 表單內(nèi)嵌套的應(yīng)用,WebDriver只能在一個頁面上進行元素識別定位,對于frame/iframe表單內(nèi)嵌頁面上的元素?zé)o法直接定位。這是需要通過switch_to.frame()方法將當前定位的主體切換為frame/iframe表單的內(nèi)嵌頁面中。
driver.switch_to_frame("f2")switch_to.frame()默認可以直接去表單的id或name屬性。如果沒有這兩個屬性,可以通過其他方式定位,比如:
#先通過xpath定位到iframe xf=driver.find_element_by_xpath('/*[@class="if"]') #再將定位對象傳給switch_to.frame()方法 driver.switch_to.frame()如果完成了在當前表單上的操作,則可以通過switch_to.parent_content()方法跳出當前一集表單。該方法默認對應(yīng)于離他最近的switch_to.frame()。如果要跳出最外層的頁面使用switch_to.default_conent().
十一、多窗口切換
1、相關(guān)方法
current_window_handle:獲得當前窗口句柄
window_handles:返回所有窗口的句柄到當前對話
switch_to.window(窗口句柄):切換到對應(yīng)的窗口。
nowhandle=driver.current_window_handledriver.find_element_by_link_text(u"發(fā)表話題").click()time.sleep(3) #由于發(fā)表新話題會新窗口打開,所以要指向新窗口,即發(fā)話題窗口 allhandles=driver.window_handles for handle in allhandles: if(handle!=nowhandle): driver.switch_to.window(handle)?十二、警告窗處理
處理javascript所生成的alert、confirm、prompt,可以使用switch_to_alert()方法定位到alert/confirm/prompt,然后使用text/accept/dismiss/send_keys等方法進行操作
- text ? ? 返回 alert/confirm/prompt 中的文字信息。
- accept ? ? ?點擊確認按鈕。
- dismiss ? ? 點擊取消按鈕,如果有的話。
- send_keys ? ? 輸入值,這個 alert\confirm 沒有對話框就不能用了,不然會報錯。
十三、上傳文件
?1、查找到input標簽,通過send_keys添加文件路徑
#通過查找到input標簽,然后send進去 driver.find_element_by_id("coverImgSrc").send_keys(u"%s"%tds["coverImgSrc"])2、使用AutoIt識別flash控件和windows控件實現(xiàn)自動上傳文件
十四、調(diào)用javascript
當 webdriver 遇到?jīng)]法完成的操作時,筆者可以考慮借用 JavaScript 來完成。使用webdriver 提供的execute_script() 接口用來調(diào)用 js 代碼。比如要操作頁面上隱藏的元素,可以用javascript來把它設(shè)置為可見然后進行操作
比如下面這段代碼:
使用javascript:
…… #修改元素的屬性 js = 'document.querySelectorAll("select")[0].style.display="block";' driver.execute_script(js) sel = driver.find_element_by_tag_name('select') Select(sel).select_by_value('opel') ……十五、控制瀏覽器滾動條
一般用到操作滾動條的會兩個場景:
- 注冊時的法律條文的閱讀,判斷用戶是否閱讀完成的標準是:滾動條是否拉到最下方。
- 要操作的頁面元素不在視覺范圍,無法進行操作,需要拖動滾動條
用于標識滾動條位置的代碼:
<body οnlοad= "document.body.scrollTop=0 "> <body οnlοad= "document.body.scrollTop=100000 ">如果滾動條在最上方的話, scrollTop=0 , 那么要想使用滾動條在最可下方, 可以 scrollTop=100000 ,
這樣就可以使?jié)L動條在最下方。
十六、獲取元素對象的屬性值
有時候我們定位頁面上的元素發(fā)現(xiàn)常用的id、name等屬性是相同的。這個時候我們只能通過常規(guī)的定位方法定位出一組元素,然后觀察通過元素的屬性可以定位出單個元素??墒褂?get_attribute()方法。
比如:
# 選擇頁面上所有的 tag name 為 input 的元素 inputs = driver.find_elements_by_tag_name('input') #然后循環(huán)遍歷出 屬性data-node值 為594434493的元素,單擊勾選 for input in inputs: if input.get_attribute('data-node') == '594434493': input.click() ……?十七、獲取驗證碼問題
關(guān)于驗證碼的處理,網(wǎng)上有幾種說法:
1、測試時先去掉驗證碼
2、使用驗證碼識別技術(shù)
3、使用cookies記錄登錄用戶名密碼,下次自動登錄免去驗證碼輸入環(huán)節(jié)
我們自己內(nèi)部的處理方式是內(nèi)部提供一個接口獲得驗證碼,然后通過js代碼把獲取的驗證碼填寫進去:
#自動獲取驗證碼并填寫js="$.getJSON('http://xxx.xxx.com/util/getCode.jsonp?callback=?',function(data){$('.imgcode').val(data.code);})" driver.execute_script(js)文章出處:https://www.cnblogs.com/pachongshangdexuebi/p/5313381.html
轉(zhuǎn)載于:https://www.cnblogs.com/william126/p/10889216.html
總結(jié)
以上是生活随笔為你收集整理的测试开发面试准备之python selenium API的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mysql查漏补缺笔记
- 下一篇: python批量json文件转xml文件