一個selenium+python的自動化測試demo
阿新 • • 發佈:2018-12-15
主要是基礎函式的使用,帶個人註釋,進行了歸納,直接執行會報錯的那種Demo。
目前並不齊全,後期繼續更新。
有什麼問題歡迎提出來交流~
# coding:UTF-8 from selenium import webdriver import unittest import sys from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait #通過關鍵字as把excepted_conditiont預期條件判斷類重新命名為EC,則可以在之後使用EC代替excepted_condition from selenium.webdriver.support import excepted_condition as EC from time import sleep, ctime import os if sys.getdefaultencoding()!='utf-8': reload(sys) sys.setdefaultencoding('utf-8') #選擇元素 class DemoAboutSelect(unittest.testcase): def setUp(self): self.driver = webdriver.Firefox() self.base_url = 'http://baidu.com' def test(self): driver = self.driver driver.get(self.base_url) #可以通過元素的id來定位,id是HTML頁面中元素的唯一的屬性,適合用來定位 driver.find_element_by_id('') #可以通過元素的name來定位,name在HTML中不唯一 driver.find_element_by_name('') #可以通過元素的class來定位,class在HTML中不唯一 driver.find_element_by_class_name('') #可以通過元素的標籤名來定位,tag_name在HTML中不唯一 driver.find_element_by_tag_name('') #可以通過元素標籤對之間的文字資訊來定位,文字資訊在HTML中有可能是唯一的 driver.find_element_by_link_text('') #可以通過元素標籤對之間的一部分文字資訊來定位,在HTML中有可能並不唯一 driver.find_element_by_partial_link_text('') #可以通過XPATH方式來定位(可以通過FF、Chrome、Edge除錯工具快速生成xpath) #可以傳入在HTML中的絕對定位、元素屬性、運算子driver.find_element_by_xpath('') #XPATH可以通過絕對路徑方式來定位 driver.find_element_by_xpath('/html/body/div/div[3]/div/imput') #xpath可以利用元素屬性方式來定位 #元素屬性方式:'//' + '標籤名或*萬用字元' + '[@' + '要使用的元素屬性' + '=' + '要定位元素屬性的值' driver.find_element_by_xpath("//input[@id='su']") #xpath可以同時使用元素屬性方式+絕對路徑方式來定位,通過屬性較多的父級找到子級 driver.find_element_by_xpath("//input[@id='su']/input") #xpath可以使用邏輯運算子+元素屬性+路徑方式來定位,適合一個屬性不能唯一定位元素的情況下 driver.find_element_by_xpath("//input[@name='su' and @class='btclass']/div/input") #可以通過CSS方式來定位元素[.class, #id, *, tag_name, 層級, [屬性='值']] 等組合定位 driver.find_element_by_css_selector('') #可以通過By方式來定位元素,find_element(By.定位方式, 定位相關引數) #使用前要匯入By類:from selenium.webdriver.common.by import By #定位方式:ID,NAME,CLASS_NAME,TAG_NAME,LINK_TEXT,PARTIAL_LINK_TEXT,XPATH,CSS_SELECTOR driver.find_element(By.ID,'kw') #定位一組元素,通常用於以下場景:1.批量操作元素;2.先獲取一組元素,再從這組物件中過濾出需要操作的元素 #在這裡其實是有點問題的,比如id,這個東西在一個HTML裡面是唯一的不能有id重複的元素,定位出來永遠只有一個,用find_elements_by_id()其實有點違背了HTML的規則了,除非有些特殊情況下是想以一個數組形式來獲取一個元素,但這是很浪費資源的一件事,目前想不出來什麼情況下可以用到 driver.find_elements_by_id('kw') driver.find_elements_by_name('su') driver.find_elements_by_class_name('su') driver.find_elements_by_tag_name('kw') driver.find_elements_by_link_text('kw') driver.find_elements_by_partial_link_text('su') driver.find_elements_by_xpath('su') driver.find_elements_by_css_selector('su') #可從裡面使用pop()指定某一個元素來操作 driver.find_elements_by_class_name('class').pop(-1).click() def teatDown(self): self.driver.quit() #操作類 class DemoAboutOperate(unittest.testcase): def setUp(self): self.driver = webdriver.Firefox() self.base_url = 'http://baidu.com' #操作視窗、瀏覽器(改變視窗大小,瀏覽器前進、後退、重新整理) def testOperateWithWindow(self): driver = self.driver driver.get(self.base_url) #控制瀏覽器window #控制瀏覽器大小set_window_size(width, height),用於自適應移動端時可以設定 driver.set_window_size(480, 720) #用於PC端一般希望全屏顯示可以使用maximize_window(),不需要引數 driver.maximize_window() #控制瀏覽器後退,back() driver.back() #控制瀏覽器前進 driver.forward() #控制瀏覽器重新整理 driver.refresh() #獲取當前所有開啟的視窗的控制代碼,返回陣列形式,window_handle handle2 = driver.window_handles #獲取當前/焦點視窗的控制代碼,current_window_handle handle1 = driver.current_window_handle #切換到指定視窗控制代碼的視窗,switch_to.window(handle) driver.switch_to.window(handle1) #操作元素 def testOperateWithElement(self): driver = self.driver driver.get(self.base_url) #簡單元素操作(清除內容、傳送寫入內容、點選、提交) #清空內容,用於避免文字輸入框中輸入造成與預設提示語拼接 driver.find_element(By.ID, 'kw').clear() #模擬按鍵輸入,模擬鍵盤向輸入框輸入內容,傳送鍵盤按鍵,模擬檔案上傳 driver.find_element(By.ID, 'kw').send_keys('value') #模擬單擊,用於可以被單擊的物件,可以包括按鈕,文字/圖片連結,複選框,單選框,下拉框等 driver.find_element(By.ID, 'su').click() #模擬提交操作,可以用於搜尋框模擬搜尋按鈕效果,提交一個按鈕,有時可以和click方法互動使用 driver.find_element(By.ID, 'kw').submit() #WebElement介面其他常用方法(獲得元素尺寸、元素文字內容、屬性的值、返回是否可見) #可返回元素的尺寸{'width':value1, 'height':value2} size沒有() driver.find_element(By.ID, 'kw').size #可返回元素的文字內容,text沒有() driver.find_element(By.ID, 'kw').text #可返回元素的屬性 driver.find_element(By.ID, 'kw').get_attribute('type') #可返回該元素是否使用者可見 true/false driver.find_element(By.ID, 'kw').is_displayed() #滑鼠事件(模擬單擊、懸停、雙擊、拖放、提交) #使用前要匯入 ActionChains 類:from selenium.webdriver.common.action_chains import ActionChains #呼叫 ActionChains 需要把瀏覽器驅動作為引數傳入 #格式:ActionChains (瀏覽器驅動).操作(元素) #變數化元素(個人新增步驟,避免以下例子程式碼過長,才變數化,非必要) element1 = driver.find_element(By.ID, 'kw') element2 = driver.find_element(By.ID, 'su') #模擬滑鼠右鍵操作,context_click()需要傳入點選的元素 ActionChains(driver).context_click(element1) #模擬滑鼠懸停,move_to_element() ActionChains(driver).move_to_element(element1) #模擬滑鼠雙擊操作 ActionChains(driver).double_click(element1) #模擬滑鼠拖放操作 drag_and_drop(source, target) 拖動的源元素,釋放到目標元素上 ActionChains(driver).drag_and_drop(element1, element2) #perform() 執行 ActionChains 中儲存的行為,可以理解為對整個操作的提交動作 ActionChains(driver).context_click(element1).perform() #鍵盤事件(鍵盤按下操作,可單鍵可組合鍵) #使用鍵盤上按鍵前要匯入 Keys 類:from selenium.webdriver.common.keys import Keys #send_keys(Keys.yourself_keyboard [,'組合鍵']) #BACK_SPACE刪除\SPACE空格\TAB製表\ESCAPE回退鍵\ENTER回車鍵\CONTROL控制鍵\F1\F2...\組合鍵 #輸入刪除鍵 element1.send_keys(Keys.BACK_SPACE) #輸入空格鍵 element1.send_keys(Keys.SPACE) #輸入Tab鍵(製表) element1.send_keys(Keys.TAB) #輸入回退鍵 element1.send_keys(Keys.ESCAPE) #輸入回車鍵 element1.send_keys(Keys.ENTER) #輸入組合鍵Ctrl+a element1.send_keys(Keys.CONTROL, 'a') #輸入F1鍵 element1.send_keys(Keys.F1) #獲得驗證資訊 #來驗證是否符合預期結果,可以從title、URL、text來驗證執行結果的對錯 #獲取當前頁面的標題,title title1 = driver.title #獲取當前頁面的URL,current_url now_url1 = driver.current_url #獲取元素的文字,text now_text = driver.text #設定元素等待 #顯示等待: WebDriverWait().until() 某個條件成立時繼續,否則在達到最大時長時丟擲超時異常TimeoutException #使用前需要匯入WebDriverWait:from selenium.webdriver.support.ui import WebDriverWait #WebDriverWait(driver, timeout, check_per_secondtime, ignored_exceptions=None) #ignored_exceptions超時後丟擲的異常,預設丟擲NoSuchElementException異常 #WebDriverWait通常會搭配until(method, value) /until_not(method, value)使用 element3 = WebDriverWait(driver, 5, 0.5).until(EC.presence_of_element_located((By.ID, 'kw'))) # EC excepted_condition類提供的預期條件判斷方法 #{title_is:判斷當前頁面的標題是否等於預期, title_contains:判斷當前頁面的標題是否包含預期字串, presence_of_element_located:判斷元素是否被加在DOM樹裡,包含不可見元素, visibility_of_element_located:判斷元素的定位是否非隱藏且寬高不為0(引數是定位), visibility_of:判斷元素是否非隱藏且寬高不為0(引數是定位好的元素), presence_of_all_element_located:判斷至少有一個元素存在於DOM樹中, text_to_be_present_in_element:判斷元素中的text是否包含預期字串, text_to_be_present_in_element_value:判斷元素的value屬性是否包含預期字串, frame_to_be_available_and_switch_to_it:判斷該表單是否可以切換進去,可以則切換並返回True, invisibility_of_element_located:判斷元素是否不存在於DOM樹或不可見, element_to_be_clickable:判斷元素是否可見且可點選, staleness_of:等到一個元素從DOM樹中移除, element_to_be_selected:判斷元素是否被選中(下拉列表), element_selection_state_to_be:判斷元素的選中狀態是否符合預期, element_located_selection_state_to_be:判斷元素的定位的選中狀態是否符合預期, alert_is_present:判斷頁面上是否存在alert} is_displayed()元素是否可見 #隱式等待:implicitly_wait()設定全域性固定等待時長s,找不到時才等待,超出時長報異常 driver.implicitly_wait(10) #sleep休眠方法:設定某一次等待的固定時長,然後繼續,單位為秒 #使用前需要匯入sleep: from time import sleep sleep(8) #表單操作(切換表單、跳出表單、切回主文件) #frame/iframe表單巢狀頁面時使用,需要切換iframe和frame兩個頁面 #switch_to.frame() 可以傳入id\name,也可以傳入定位物件,或者傳入frame的下標index從0開始 #傳入id\name此處有問題,和HTML有關,同一個HTML文件中id和name可以相同,這樣傳參會出現問題,建議還是傳入定位物件 #傳入定位物件 element4 = driver.fine_element_by_xpath('/html/body/div/li/frame') driver.switch_to.frame(element4) #傳入id/name driver.switch_to.frame('if') #傳入下標index driver.switch_to.frame(2) #switch_to.parent_content() 跳出當前一級的表單,預設是匹配最近的 switch_to.frame()方法,該方法有可能不可用 driver.switch_to.parent_content() #切到父frame,有多層frame時有用,但一般這種巢狀多層的frame是有影響到效能的問題的,可以讓開發改進 driver.switch_to.parent_frame() #切換到主文件,或者理解為最外層的頁面 driver.switch_to.default_content() #switch_to家族的其他(切到當前焦點元素、切到當前alert、confirm、prompt框、切到某個瀏覽器視窗) #driver.switch_to.active_element.send_keys('selenium') 返回當前取得焦點的webdriver物件,然後操作 #driver.switch_to.alert.send_keys() 返回瀏覽器的alert物件,可對瀏覽器alert、confirm、prompt框操作 #driver.switch_to.window(window_name) 切到某個瀏覽器視窗 #警告框的處理 先使用switch_to.alert()定位到警告框 包括 alert\confirm\prompt #accept() 接受現有警告框 driver.switch_to.alert().accept() #dismiss() 解散現有警告框 driver.switch_to.alert().dismiss() #也可以定位到警告框之後,返回警告框的文字資訊 text , 或者傳送文字資訊 send_keys(message) #如果要使用本地的HTML文件進行測試,get的時候傳入檔案地址 def testWithLocalhostHTMLFile(self): driver = self.driver #使用本地檔案進行測試 #在當前py同個路徑時使用'file:///' + os.path.abspath('xxx.html') #使用非當前路徑的檔案時'file:///' + 檔案的絕對路徑如'F:\doc\find.html' #os.path.abspath('file.html')用於獲取當前路徑下的檔案,需要提前匯入os類 #import os file_path = 'file:///' + os.path.abspath('result.html') driver.get(file_path) #上傳檔案 def testWithUploadFile(self): driver = self.driver driver.get(self.base_url) #send_keys方法完成,傳入檔案的絕對路徑,適用input標籤,可以避免操作windows控制元件 driver.find_element_by_id('su').send_keys('E:\\disk\file.txt') #Autolt方法實現 #執行autoit的指令碼來實現 def tearDown(self): self.driver.quit() class if __name__ == '__main__': testunit = unittest.TestSuite() testunit.addTest(DemoAboutSelect('test'))