在我們做UI自動化測試的時候,會有一些元素需要特殊操作,比如下拉框操作/鍵鼠操作/文件上傳。
下拉框操作
在我們很多頁面里有下拉框的選擇,這種元素怎么定位呢?下拉框分為兩種類型:我們分別針對這兩種元素進行定位和操作
- select標簽 : 通過select類處理。
- 非select標簽
1、針對下拉框元素,如果是Select標簽類型,可以通過Selenium WebDriver中的Select類來進行處理:
from selenium.webdriver.support.ui import Select
這個Select類提供了如下操作方法:
- select_by_index(index) #通過選項的順序 : 索引選擇,從0開始
- select_by_value(value) #通過value屬性
- select_by_visible_text(text) #通過選項可見文本
- options #提供所有的選項的列表,其中都是選項的WebElement元素
from select import select from time import sleep from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.select import Select 驅動 = webdriver.Chrome() 驅動.get("https://www.hao123.com/?src=from_pc") 驅動.maximize_window() 驅動.implicitly_wait(3) #點擊切換按鈕 驅動.find_element(By.CSS_SELECTOR,".city-change-btn").click() sleep(3) # 獲取省下拉框的元素 select_test01 = 驅動.find_element(By.NAME,"province") sleep(3) #通過編號 Select(select_test01).select_by_value("04") sleep(3) # 獲取城市下拉框的元素 select_test02 = 驅動.find_element(By.NAME,"city") sleep(3) #通過文字 Select(select_test02).select_by_visible_text("B 巴南") sleep(3) #獲取城市下級元素下拉框的元素 select_test03 = 驅動.find_element(By.NAME,"dist") sleep(3) #通過索引 Select(select_test03).select_by_index(0) sleep(3) 驅動.find_element(By.CSS_SELECTOR,".select-confirm-btn").click()
2、如果是非Select類型元素,不能通過Select類來進行處理,此時直接點擊即可。現在很多項目并不是select標 簽。
from selenium.webdriver.support.ui import Select
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleepdriver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://www.baidu.com/')# 點擊設置按鈕
driver.find_element(By.ID,"s-usersetting-top").click()
sleep(2)
# 點擊高級搜索
driver.find_element(By.XPATH,'//span[text()="高級搜索"]').click()
sleep(2)
#點擊時間不限的下拉框元素
driver.find_element(By.XPATH,'//span[text()="時間不限"]').click()
sleep(2)
driver.find_element(By.XPATH,'//p[text()="一周內"]').click()sleep(3)driver.quit()
左右滑動解鎖
(1)driver.find_elements_by_class_name("slide-to-unlock-handle")[0]==先通過class屬性找到所有的里面的第一個
(2)click_and_hold() ? ==對滑塊按下鼠標左鍵
(3)move_by_offset() ==通過for循環動滑塊的位置,move_by_offset()方法第一個參數是X軸,第二個參數是Y軸,單位為像素。因為是平行移動,所以Y設置為0。 X每次移動兩2個像素。每次循環休眠0.1秒,時間間隔越小,移動越順滑.
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
驅動 = webdriver.Chrome()
驅動.get("https://www.helloweba.net/demo/2017/unlock/")
驅動.maximize_window()
# 查找滑動模塊
unlock_element = 驅動.find_element(By.CSS_SELECTOR,".slide-to-unlock-handle")
# 獲取鼠標操作
mouse_oper = ActionChains(驅動)
#對滑塊按下鼠標左鍵并執行
mouse_oper.click_and_hold(unlock_element).perform()
#拖動x軸移動x坐標
mouse_oper.move_by_offset(300,0).perform()
#重置滑動框
mouse_oper.reset_actions()
sleep(5)
#退出
驅動.quit()
鍵鼠操作
UI自動化測試的時候,我們有些時間需要操作鼠標和鍵盤,對元素進行操作。比如鼠標有很多操作 雙擊 單機 右鍵等。所以,我們需 要學習鍵鼠操作。
selenium里有一個專門的類來處理鼠標的操作: ActionChains類, 可以用來模擬鼠標操作
- from selenium.webdriver.common.action_chains import ActionChains 【導包】
第一步:選擇鼠標的行為(參數是元素對象 -element): 通過driver.find_element找到的元素,再選 擇鼠標行為:
- 懸浮-移動鼠標 move_to_element() -- p1
- 點擊 click() --p1 拖拽 drag_and_drop(element1,element2) --P1
- 先找到element1,再找到element2,拖拽執行
- 雙擊 double_click() ---p2
- 在特定元素上單擊鼠標左鍵(不釋放)click_and_hold() ----- p2
- 暫停 pause() 每個動作之間可以暫停一下----- p2
- release() #抬起鼠標 --p2 右鍵 context_click() :
- 右鍵后打開的菜單 無法定位 不屬于html頁面 所以用的少。
這個方法很多,不需要全部記住,如果用到的時候查一下就可以。 知道基本使用的步驟就可以。-- 通過ActionChains(driver).可以查 看所有方法。
第二步:執行鼠標操作行為 - perform(),鼠標操作一定要perform才會執行。
ActionChains鼠標操作的具體的使用步驟:
1、實例化ActionChains對象
2、調用你要使用的鼠標操作行為 : 可以用鏈式調用
- - 因為每個方法返回的都是self ,可以連續調用
3、調用perform()去執行鼠標操作: 一定要perform才會執行。
ActionChains(driver).move_to_element(elem).perform() # 移動到元素
ActionChains(driver).click(elem).perform() # 點擊元素
ActionChains(driver).drag_and_drop(element1,element2).perform() # 拖拽動作
注意問題:普通的點擊操作和鼠標點擊操作的區別?
- 普通的click,在點擊的時候是有條件要求,被點擊的元素需要是能夠被點擊的狀態 -- 有條件約束,有可能會失敗
- 鼠標click,不會管元素是否能夠被點擊,直接去點擊 -- 沒有條件約束,任何元素都可以點擊
- 什么情況下使用鼠標click?== 如果你發現有時候通過普通的click點擊不了,那你可以選擇鼠標click
""" 第一步:選擇鼠標的行為(參數是元素對象 -element): 通過driver.find_element找到的元素,再選擇鼠標行為: * 懸浮-移動鼠標 move_to_element() -- p1 * 點擊 click() --p1 * 拖拽 drag_and_drop(element1,element2) --P1* 先找到element1,再找到element2,拖拽執行 第二步:執行鼠標操作行為 - perform(),鼠標操作一定要perform才會執行。ActionChains鼠標操作的具體的使用步驟: * 1、實例化ActionChains對象 * 2、調用你要使用的鼠標操作行為 :* 可以用鏈式調用 - 因為每個方法返回的都是self ,可以連續調用 * 3、調用perform()去執行鼠標操作: 一定要perform才會執行。 """ from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support.ui import Select from selenium import webdriver from selenium.webdriver.common.by import By from time import sleepdriver = webdriver.Chrome() driver.maximize_window() driver.get('https://www.baidu.com/')# 元素定位表達式-設置按鈕 ele_setting = driver.find_element(By.ID,"s-usersetting-top")# 1、實例化ActionChains對象 + 2、調用你要使用的鼠標操作行為 :-懸浮 移動鼠標到某個元素+3、調用perform()去執行鼠標操作 ActionChains(driver).move_to_element(ele_setting).perform() sleep(2)# 找到高級搜索按鈕 --用鼠標點擊操作 ele_search = driver.find_element(By.XPATH,'//span[text()="高級搜索"]') ActionChains(driver).click(ele_search).perform() sleep(2)
""" 第一步:選擇鼠標的行為(參數是元素對象 -element): 通過driver.find_element找到的元素,再選擇鼠標行為: * 懸浮-移動鼠標 move_to_element() -- p1 * 點擊 click() --p1 * 拖拽 drag_and_drop(element1,element2) --P1* 先找到element1,再找到element2,拖拽執行 第二步:執行鼠標操作行為 - perform(),鼠標操作一定要perform才會執行。ActionChains鼠標操作的具體的使用步驟: * 1、實例化ActionChains對象 * 2、調用你要使用的鼠標操作行為 :* 可以用鏈式調用 - 因為每個方法返回的都是self ,可以連續調用 * 3、調用perform()去執行鼠標操作: 一定要perform才會執行。 """ from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support.ui import Select from selenium import webdriver from selenium.webdriver.common.by import By from time import sleepdriver = webdriver.Chrome() driver.maximize_window() driver.get('https://www.treejs.cn/v3/demo/cn/exedit/drag.html')#元素拖拽操作 ele1 = driver.find_element(By.ID,'treeDemo_2_span') # 初始元素 ele2 = driver.find_element(By.ID,'treeDemo_5_span') # 目標位置 ActionChains(driver).drag_and_drop(ele1,ele2).perform() sleep(2)driver.quit()
""" 有些按鈕用普通點擊無法點擊成功 此時就會需要去嘗試使用鼠標點擊。""" from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support.ui import Select from selenium import webdriver from selenium.webdriver.common.by import By from time import sleepdriver = webdriver.Chrome() driver.maximize_window() driver.get('file:///D:/Pycharm_Project/upload_demo.html')# 普通點擊不能生效的 # driver.find_element(By.ID,'fu').click()# 嘗試用鼠標點擊 ActionChains(driver).click(driver.find_element(By.ID,'fu')).perform()
鍵盤事件 : 用的稍微比較少,了解一下
Selenium中send_keys除了可以模擬鍵盤輸入之外,還有些時候需要操作鍵盤上的按鍵,甚至是組合鍵,比如CTRL+A,CTRL+C等, 所以我們需要代碼操作鍵盤。使用的是send_keys里的Keys的類。
- from selenium.webdriver.common.keys import Keys
Keys()類提供了鍵盤上所有按鍵的方法,常用的鍵盤按鍵操作如下:
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’) #復制(Ctrl+C)
send_keys(Keys.CONTROL,‘x’) #剪切(Ctrl+X)
send_keys(Keys.CONTROL,‘v’) #粘貼(Ctrl+V)
send_keys(Keys.F1) #鍵盤 F1
...
send_keys(Keys.F12) #鍵盤 F12
"""
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’) #復制(Ctrl+C)
send_keys(Keys.CONTROL,‘x’) #剪切(Ctrl+X)
send_keys(Keys.CONTROL,‘v’) #粘貼(Ctrl+V)
send_keys(Keys.F1) #鍵盤 F1
...
send_keys(Keys.F12) #鍵盤 F12"""
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleepdriver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://www.baidu.com/')driver.find_element(By.ID,'kw').send_keys("百度一下")# 回車
# driver.find_element(By.ID,"kw").send_keys(Keys.ENTER)
# 回刪鍵
driver.find_element(By.ID,"kw").send_keys(Keys.BACK_SPACE)
sleep(2)
driver.find_element(By.ID,"kw").send_keys(Keys.BACK_SPACE)
sleep(1)
# 組合鍵 - 全選
driver.find_element(By.ID,"kw").send_keys(Keys.CONTROL,"a")
sleep(2)
# 組合鍵 - 復制
driver.find_element(By.ID,"kw").send_keys(Keys.CONTROL,"c")
driver.find_element(By.ID,"kw").clear() # 文本清空
sleep(2)
# 組合鍵 - 粘貼
driver.find_element(By.ID,"kw").send_keys(Keys.CONTROL,"v")
sleep(2)
driver.find_element(By.ID,"kw").send_keys(Keys.CONTROL,"v")sleep(2)driver.quit()
文件上傳:文件上傳是自動化中比較麻煩棘手的部分。
有些場景我們需要上傳本地文件到項目里。這種比較麻煩,因為需要點開文件上傳的窗口后,打開的是windows的文件選擇窗口,而 selenium是無法操作這個窗口的。 selenium只能操作html網頁。
針對這種上傳文件的場景,我們分兩種情況來處理:
場景1、上傳文件的元素是是input標簽 : 這種比較方便,直接send_keys這個文件的路徑就可以了。
"""
場景1、上傳文件的元素是是input標簽 :<input type="file" id="fu" value="選擇文件">
這種比較方便,直接send_keys這個文件的路徑就可以了。
"""
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleepdriver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://www.baidu.com/')# 點擊相機的按鈕
driver.find_element(By.XPATH,'//span[@class="soutu-btn"]').click()# 找到文件上傳的元素 直接進行send_keys()操作 把上傳的文件的路徑 填進去
driver.find_element(By.XPATH,'//input[@class="upload-pic"]').send_keys(r'C:\Users\95744\Pictures\Camera Roll\123.jpg')sleep(3)
driver.quit()
場景2、 不是input輸入框,點擊彈出系統的選擇文件的窗口這種 需要借助第三方庫實現:- PC 應用程序自動化工 具
通過系統工具實現自動化測試:windows系統自動化測試工具 :pyautogui,AutoIT,Pywinauto。
- 1)在打開對話框中填寫要上傳的文件路徑: pyautogui.write(r'D:\fk88.png') ,選擇要上傳的文件 【write不支持中文】
- 2)點擊打開按鈕-按下回車按鈕:pyautogui.press('enter', presses=2) ,庫可能有bug,所以盡量點擊2次 確保萬無一失 注意:默認文件路徑不能有中文: 有中文 直接使用會報錯。
我們學習pyautogui工具,使用的步驟:
- 1)在打開對話框中填寫要上傳的文件路徑: pyautogui.write(r'D:\fk88.png') ,選擇要上傳的文件 【write不支持中文】
- 2)點擊打開按鈕-按下回車按鈕:pyautogui.press('enter', presses=2) ,庫可能有bug,所以盡量點擊2次 確保萬無一失
- 注意:默認文件路徑不能有中文: 有中文 直接使用會報錯
- 支持中文的做法:先去復制路徑->粘貼;
- 但是pyautogui不支持復制操作,所以需要借助 另外一個庫:pyperclip,內置庫 直接導入即可 :import pyperclip
- 通過熱鍵粘貼路徑
- 然后再點擊回車按鈕確認上傳
- 這個庫只能支持單個文件上傳,要多個 可以使用 pywinauto的庫,不過這個庫不那么穩定+只能支持windows
""" * pyautogui:跨平臺支持:windows、linux、mac,操作也比較簡單。* 第三方庫: pip install pyautogui 我們學習pyautogui工具,使用的步驟: * 1)在打開對話框中填寫要上傳的文件路徑: pyautogui.write(r'D:\fk88.png') ,選擇要上傳的文件 * 2)點擊打開按鈕-按下回車按鈕:pyautogui.press('enter', presses=2) ,庫可能有bug,所以盡量點擊2次 確保萬無一失* 注意:默認文件路徑不能有中文: 有中文 直接使用會報錯。* 支持中文的做法:先去復制路徑->粘貼;* 但是pyautogui不支持復制操作,所以需要借助 另外一個庫:pyperclip,內置庫 直接導入即可 :import pyperclip* 通過熱鍵粘貼路徑* 然后再點擊回車按鈕確認上傳為了萬無一失 可以 統一使用中文的方式進行上傳。或者你可以在上傳之前 確保數據名和路徑都是英文的。""" import pyautogui from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep import pyperclipdriver = webdriver.Chrome() driver.maximize_window() driver.get('https://caesium.app/')# 點擊瀏覽按鈕--點擊 打開上傳的窗口 driver.find_element(By.XPATH,'//span[contains(text(),"瀏覽")]').click() sleep(2) # 加一個強制等待# 借助pyautogui工具 操作 步驟 # 1)在打開對話框中填寫要上傳的文件路徑 # pyautogui.write(r'C:\Users\libin\Desktop\tricy.png') # pyautogui.write(r'C:\Users\libin\Desktop\驗證碼.png') # # # 2)點擊打開按鈕-按下回車按鈕 # pyautogui.press("enter", presses=2)# 路徑有中文的寫法 # 1、先復制路徑 pyperclip.copy(r'C:\Users\95744\Pictures\Camera Roll\幣安app.png') # 2、粘貼 -- hotkey 通過熱鍵粘貼 pyautogui.hotkey("ctrl","v") sleep(2)# 3)點擊打開按鈕-按下回車按鈕 pyautogui.press("enter", presses=2)
通過系統工具實現自動化測試的缺點:
- 1、不太穩定,兼容性比較差
- 2、不能同時以其他的任務在執行 所以盡量優先用send_keys 不能用 再用系統工具。
-
驗證碼處理
很多的網站都在登錄頁面加入了識別文字,識別圖片,拖動拼圖的驗證碼方式來防止爬蟲、惡意注冊等,如果是做自動化,需要繞過 驗證碼才能進入下一步操作。
- 方案一、測試環境去除驗證碼 :最輕松的方法,找開發幫忙解決。
- 方案二、萬能驗證碼 (推薦): lemon, 這個也簡單和常用。推薦使用
- 方案三、通過添加cookie繞過登錄繞過圖片驗證【UI自動化】
cookie是一門客戶端技術,一般是由服務器生成返回給瀏覽器客戶端來保存的,并且cookie是以鍵值對的形式保存在瀏覽器客戶端 的,每一個cookie都會有名稱,值,過期時間...用來保存少量的用戶信息
Cookie有很多使用場景,在項目中比較常見的有:
- 1. 登錄記住用戶名
- 2. 記錄用戶瀏覽記錄
Cookie種類:
1、會話cookie:保存在內存中,瀏覽器關閉就清除== 這種不適用。
2、持久cookie:保存在硬盤中,失效時間到之后就會清除 ,適用于cookies的處理方式登錄。
- 添加cookie解決驗證碼思路:
- 在登錄某個網站,如果勾選【自動登錄】,當下次再訪問該網站時就自動處于登錄狀態。這個功能其實就是將用戶信息保存 在瀏覽器的cookie中,當再次訪問網站時,瀏覽器直接使用本地保存的cookie用戶信息進行登錄。
- 所以我們在代碼中也可以將用戶信息添加到cookie中,再刷新瀏覽器即可;
driver = webdriver.Chrome() driver.get('https://www.baidu.com/') driver.maximize_window() #通過添加百度登錄之后用戶信息-cookie driver.add_cookie({"name":"BDUSS","value":"zlaRUg4VjVPb2xkSG5MSmJOfmpIQnp3WUdDZXNDbWk4V3I5ME9SemtoRHRpWFZsSVFBQUFBJC sleep(2) driver.refresh()
""" 1、先跟開發確認 登錄的cookies保存在哪個cookies鍵值對里 【瀏覽器里會保存很多cookies】 2、確認這個cookies是會話cookies 還是 持久cookie, 持久cookie可以用; 3、先在本地瀏覽器里先登錄項目-- cookies才能保存在瀏覽器,并拿到cookies 給代碼傳過去 百度登錄cookies: BDUSS : 1FdWc1ai1LRmNGRE9jZFlBa0Q5cUkyWFpFUGN0ZHBCeGI4SExqbVlvaE1QeGxtSVFBQUFBJCQAAAAAAAAAAAEAAAAJsDdLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEyy8WVMsvFlei """ from selenium import webdriver from time import sleepdriver = webdriver.Chrome() driver.get("https://www.baidu.com/") driver.maximize_window()# 通過百度登錄之后的cookies拿到 driver.add_cookie({"name":"BDUSS","value":"JxMzJoazl3SzNFa1pWQU5YTzM0UlJlWTBkaS1XMlRQQk8ydEpqNn4za0RBbmhtSUFBQUFBJCQAAAAAAAAAAAEAAACFWXWR1vHSttfTNjYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN1UGYDdVBmNF"}) sleep(2)# 刷新頁面 --使用cookies直接繞過登錄 進入登錄后的狀態 driver.refresh()sleep(2) driver.quit()
cookie失效條件:
-
1、手動退出登錄
-
2、cookie已經超過有效期
注意,如果cookies失效 就需要重新獲取cookies。