Selenium2 Python 自動化測試實戰學習筆記(三)

來源:互聯網
上載者:User

標籤:

4.9 多表單切換

在web應用中經常會遇到frame嵌套頁面的應用,webdriver每次只能在一個頁面上識別元素,對於frame嵌套的頁面上的元素,直接定位是定位不到的,這時候就需要switch_to_frame()方法將當前定位的主體切換到frame裡。Frame.htm:frame.htm, 直接定位百度的輸入框一定會報找不到元素的錯誤。那麼可以使用switch_to_frame()先找到frame.html 中的<iframe>標籤,然後再定位百度輸入框。switch_to_frame() 預設可以直接取表單的id 或name 屬性進行切換. 如果完成了在當前表單上的操作可以通過switch_to_default_content()方法返回到上一層表單, 不用指定某個表單的返回,預設對應與它最近的switch_to_frame()方法。

Frame.py

#coding=utf-8

from selenium importwebdriver

import time,os

 

driver=webdriver.Chrome()

file_path="file:///"+os.path.abspath("frame.htm")

driver.get(file_path)

 

driver.switch_to_frame("if")

driver.find_element_by_id("kw").send_keys("selenium")

driver.find_element_by_id("su").click()

time.sleep(3)

driver.switch_to_default_content()

time.sleep(3)

driver.close()

 

4.10 多視窗切換

有時候需要在不同的視窗切換,從而操作不同的視窗上的元素。WebDriver 提供了switch_to_window()方法可以切換到任意的視窗。Window.py

#conding=utf-8

from selenium import webdriver

 

driver=webdriver.Chrome()

driver.implicitly_wait(10)

driver.get("http://www.baidu.com")

 

search_windows=driver.current_window_handle

 

driver.find_element_by_link_text(u‘登入‘).click()

driver.find_element_by_link_text(u‘立即註冊‘).click()

 

all_handles=driver.window_handles

 

#進入註冊視窗

for handle in all_handles:

    if handle !=sreach_windows:

       driver.switch_to_window(handle)

        print ‘now registerwindow!‘

       driver.find_element_by_name("account").send_keys(‘username‘)

       driver.find_element_by_name(‘password‘).send_keys(‘password‘)

#進入搜尋視窗

for handle in all_handles:

    if handle ==sreach_windows:

       driver.switch_to_window(handle)

        print ‘now sreachwindow!‘

        driver.find_element_by_id(‘TANGRAM__PSP_2__closeBtn‘).click()

       driver.find_element_by_id("kw").send_keys("selenium")

       driver.find_element_by_id("su").click()

        time.sleep(5)

driver.close()

 

整個指令碼的處理過程:首先開啟百度首頁,通過current_window_handle 獲得當前視窗的控制代碼,並給變數sreach_handle。接著開啟登入彈窗,在登入視窗上點擊“立即註冊”從而開啟新的註冊視窗。通過window_handles 獲得當前開啟的所視窗的控制代碼,賦值給變數all_handles。

第一個迴圈遍曆all_handles,如果handle 不等於sreach_handle,那麼一定是註冊視窗,因為指令碼執行只開啟的兩個視窗。所以,通過switch_to_window()切換到註冊頁進行註冊操作。第二個迴圈類似,不過這一次判斷如果handle 等於sreach_handle,那麼切換到百度搜尋網頁,關閉之前開啟的登入彈窗,然後時行搜尋操作。

在本例中所有用到的新方法:

current_window_handle 獲得當前視窗控制代碼

window_handles 返回的所有視窗的控制代碼到當前會話

switch_to_window()

用於切換到相應的視窗,與上一節的switch_to_frame() 是類似,前者用於不同視窗的切換,後者用於不同表單之間的切換。

4.11 警告框處理

         在WebDriver 中處理JavaScript 所產生的alert、confirm 以及prompt是很簡單的。具體做法是使用switch_to_alert()方法定位到alert/confirm/prompt。然後使用text/accept/dismiss/send_keys按需進行操做。

l  text 返回alert/confirm/prompt中的文字資訊。

l  accept 點擊確認按鈕。

l  dismiss 點擊取消按鈕,如果有的話。

l  send_keys 輸入值,這個alert\confirm沒有對話方塊就不能用了,不然會報錯。

彈出框不能通過前端工具對其進行定位,可以通過switch_to_alert()方法接收這個彈窗。

Alert.py

#coding=utf-8

from selenium import webdriver

from selenium.webdriver.common.action_chains import ActionChains

import time

 

driver=webdriver.Chrome()

driver.implicitly_wait(10)

driver.get("http://www.baidu.com")

 

#mouse stop set link

link=driver.find_element_by_name("tj_settingicon")

ActionChains(driver).move_to_element(link).perform()

#open search setting

driver.find_element_by_link_text(u‘搜尋設定‘).click()

#save set

driver.find_element_by_link_text(u‘儲存設定‘).click()

#recieve pop_window

driver.switch_to_alert().accept()

time.sleep(5)

driver.close()

    ActionChains 類所提供的move_to_element()滑鼠移至上方的使用,將滑鼠移至上方在“搜尋”連結上然後彈出下拉式功能表。在菜單中點擊“搜尋設定”按鈕。設定完成點擊“儲存設定”彈出警告框。通過switch_to_alert()方法擷取當前頁上的警告框,accept()接受警告框。

 

 

4.12 上傳檔案

對於web頁面的上傳功能,點擊上傳按鈕需要開啟本地的window視窗,從視窗選擇本地檔案進行上傳,那麼webdriver對於windows的控制項是無能為力的。

對於web頁面的上傳功能一般會有以下幾種方式。

普通上傳:普通上傳都是將本地檔案的路徑作為一個值放在input標籤中,通過form表單提交的時候將這個值提交給伺服器。

外掛程式上傳:一般是指基於flash與JavaScript或ajax等技術所實現的上傳功能或外掛程式。

4.12.1 Send_keys()實現上傳

通過input標籤實現上傳,通過send_keys()傳入本地檔案路徑從而類比上傳功能。Upfile.htm:upfile.htm

Upfile.py

#coding=utf-8

from seleniumimport webdriver

import os,time

 

driver=webdriver.Chrome()

 

#open upfilefuntion page

file_path="file:///"+os.path.abspath("upfile.htm")

driver.get(file_path)

 

#locate theupload button and add file

driver.find_element_by_name("file").send_keys("D:\\session_help.txt")

time.sleep(10)

 

driver.close()

通過這種方法上傳,就繞開了操作Windows控制項的步驟。如果能找上傳的input 標籤,那麼基本都可以通過send_keys()方法向其輸入一個檔案地址來實現上傳。

4.12.2 AutoIt 實現上傳

Autolt 是一個使用類似basic指令碼語言的免費軟體,它設計用於windows GUI中進行自動化操作。它利用類比鍵盤按鍵,滑鼠移動和視窗/控制項的組合來實現自動化任務。

官方網站:https://www.autoitscript.com/site/

AutoIt Windows Info                 用於協助我們識Windows 控制項資訊。

Compile Script to.exe               用於將AutoIt 產生exe 執行檔案。

Run Script                                用於執行AutoIt 指令碼。

SciTE Script Editor                   用於編寫AutoIt 指令碼。

下面以操作upload.html 上傳彈出的視窗為例講解AutoIt 實現上傳過程。

 

1、 首先開啟AutoIt Windows Info 工具,滑鼠點擊Finder Tool,滑鼠將變成一個小風扇形狀的表徵圖,按住滑鼠左鍵拖動到需要識別的控制項上。

4.14、4.15,通過AutoIt WindowsInfo 獲得以下資訊。

視窗的title 為“選擇要載入的檔案”,標題的Class 為“#32770”。

檔案名稱輸入框的class 為“Edit”,Instance 為“1”,所以ClassnameNN 為“Edit1”。

開啟按鈕的class 為“Button”,Instance 為“1”,所以ClassnameNN 為“Button1”。

 

2、根據AutoItWindows Info 所識別到的控制項資訊開啟SciTEScript Editor 編輯器,編寫指令碼。

ControlFocus()方法用於識別Window 視窗。WinWait()設定10 秒鐘用於等待視窗的顯示,其用法與WebDriver所提供的implicitly_wait()類似。ControlSetText()用於向“檔案名稱”輸入框內輸入本地檔案的路徑。這裡的Sleep()方法與Python 中time 模組提供的Sleep()方法用法一樣,不過它是以毫秒為單位,Sleep(2000)表示固定休眠2000 毫秒。ControlClick()用於點擊上傳視窗中的“開啟”按鈕。

AutoIt 的指令碼已經寫好了,可以通過功能表列“Tools”-->“Go” (或按鍵盤F5)來運行一個指令碼吧!注意在運行時上傳視窗當前處於開啟狀態。

3、 指令碼運行正常,將其儲存為upfile.au3,這裡儲存的指令碼可以通過Run Script 工具將其開啟運行,但我們的目的是希望這個指令碼被Python 程式調用,那麼就需要將其產生exe 程式。開啟Compile Script to.exe工具,將其產生為exe 可執行檔。4.16,

 

點擊“Browse”選擇upfile.au3 檔案,點擊“Convert”按鈕將其產生為upfile.exe 程式。

4、下面就是通過自動化測試指令碼調用upfile.exe 程式實現上傳了。Upfile_by_autoit.py:

#coding=utf-8

from seleniumimport webdriver

import os,time

driver=webdriver.Chrome()

#open theupload funtion page

file_path="file:///"+os.path.abspath("upfile.htm")

driver.get(file_path)

time.sleep(10)

#click theopen upload window

driver.find_element_by_name("file").click()

#callupfile.exe programe

os.system("C:\\Users\\ewang\\Desktop\\Python_Selenium2\\upflie.exe")

driver.close()

4.13 操作Cookie

         有時候我們需要驗證瀏覽器中是否存在某個cookie,因為基於真實的cookie 的測試是無法通過白盒和整合測試完成的。WebDriver 提供了操作Cookie 的相關方法可以讀取、添加和刪除cookie 資訊。

webdriver 操作cookie 的方法有:

 get_cookies() 獲得所有cookie 資訊

 get_cookie(name) 返回有特定name 值有cookie 資訊

 add_cookie(cookie_dict) 添加cookie,必須有name 和value 值

 delete_cookie(name) 刪除特定(部分)的cookie 資訊

 delete_all_cookies() 刪除所有cookie 資訊

下面通過get_cookies()來擷取當前瀏覽器的cookie 資訊。Cookie.py

#coding=utf-8

from seleniumimport webdriver

import time

 

driver=webdriver.Chrome()

driver.get("http://www.youdao.com")

 

cookie=driver.get_cookies()

ck_nu=0

for ck incookie:

    ck_nu=ck_nu+1

    print "the %d cookie: \t %r \n" %(ck_nu,ck)

 

driver.close()

通過列印結果可以看出,cookie是以字典的形式進行存放的,知道了cookie 的存放形式,那麼我們就可以按照這種形式向瀏覽器中寫入cookie 資訊。Add_cookie.py

#coding=utf-8

from selenium import webdriver

import time

driver=webdriver.Chrome()

driver.get("http://www.youdao.com")

driver.add_cookie({‘name‘:‘key-enlong‘,‘value‘:‘value-loveyou‘})

for ck in driver.get_cookies():

    print "%s -> %s" %(ck[‘name‘], ck[‘value‘])

driver.close()

 

那麼在什麼情況下會用到cookie 的操作呢?例如開發人員開發一個功能,當使用者登入後,會將使用者的使用者名稱寫入瀏覽器cookie,指定的key 為“username”,那麼我們就可以通過get_cookies() 找到useranme,列印vlaue,如果找不到username 或對應的value 為空白,那麼說明儲存瀏覽器的cookie 是有問題的。

delete_cookie() 和delete_all_cookies()的使用也很簡單,前者通過name 值到一個特定的cookie 將其刪除,後者直接刪除瀏覽器中的所有cookies()資訊。

4.14 調用JavaScript

         WebDriver不能操作本地windows控制項,但對於瀏覽器的控制項也不是都可以操作的。比如瀏覽器上的捲軸,雖然webdriver提供操作瀏覽器的前進和後退按鈕,但對與捲軸並沒有提供相應用的方法。Webdriver提供了execute_script()方法來執行JavaScript。

         一般操作捲軸的會有兩個情境:

l  註冊時的法律條文的閱讀,判斷使用者是否閱讀完成的標準是:捲軸是否拉倒最下方。

l  操作的頁面不在視覺範圍,無法執行操作,需要拖動捲軸。

用於標識捲軸位置的代碼:

<bodyonload= "document.body.scrollTop=0 ">

<bodyonload= "document.body.scrollTop=100000 ">

        

document.body.scrollTop:scrollTop 設定或擷取捲軸與最頂端之間的距離。如果想讓捲軸處於頂部,那麼可以設定scrollTop 的值為0,如果想讓捲軸處於最底端,可以將這個值設定的足夠大,大個視窗的高度即可。HTML.PY:

#coding=utf-8

from seleniumimport webdriver

import time

driver=webdriver.Chrome()

driver.get("http://www.baidu.com")

driver.find_element_by_id("kw").send_keys("selenium")

driver.find_element_by_id("su").click()

time.sleep(3)

js="varq=document.documentElement.scrollTop=10000"

driver.execute_script(js)

time.sleep(3)

js_="varq=document.documentElement.scrollTop=0"

driver.execute_script(js_)

time.sleep(3)

driver.close()

 

通過JavaScript 代碼控制捲軸在任意位置,需要改變的就是scrollTop 的值。通過execute_script()方法來執行這段JavaScript 代碼。當然,JavaScript 的作用不僅於此,它同樣可操作頁面上的元素或讓,或讓這個元素隱藏。

 

 

4.15 視窗

         自動化指令碼是交給工具去執行,有時候列印的錯誤資訊並十分不明確,如果在執行指令碼出錯的時候將對當前視窗儲存,通過圖片資訊的找到指令碼出錯的原因。Webdriver提供了函數get_screenshot_as_file()來截取當前視窗。Screenshot.py

#coding=utf-8

from selenium import webdriver

 

driver=webdriver.Chrome()

driver.get("http://www.baidu.com")

 

try:

   driver.find_element_by_id("kw_22").send_keys("selenium")

   driver.find_element_by_id("su").click()

 

except :

   driver.get_screenshot_as_file("D:\\BAIDU.JPG")

    driver.quit()

         本例中百度輸入框的id=kw_error 會定位不到元素,那麼try就會捕捉到這個異常,從而執行except,在except 中執行get_screenshot_as_file()對當前視窗進行,這裡需要指定圖片的儲存路徑及檔案名稱,並且關閉當前驅動。指令碼運行完成開啟D 盤就可以找到baidu_error.jpg 圖片檔案了。

4.16 關閉視窗

  Quit()方法:退出相關的驅動程式和關閉所有視窗

  Close()方法:用於關閉當前視窗

  當指令碼在執行時開啟了多個視窗,這個時候只能關閉其中的某一個視窗,這個時候就需要使用close()來關閉。

4.17 驗證碼的處理

   1. 去掉驗證碼

                 這是最簡單的方法,對於開發人員來說,只是把驗證碼的相關代碼注釋掉即可,如果是在測試環境,這樣做可省去了測試人員不少麻煩,如果自動化指令碼是要在正式環境跑,這樣就給系統帶來了一定的風險。

2. 設定萬能碼

去掉驗證碼的主要是安全問題,為了應對線上系統的安全性威脅,可以在修改程式時不取消驗證碼,而是程式中留一個“後門”---設定一個“萬能驗證碼”,只要使用者輸入這個“萬能驗證碼”,程式就認為驗證通過,否則按照原先的驗證方式進行驗證。

  

 

1.       驗證碼識別技術

例如可以通過Python-tesseract 來識別圖片驗證碼,Python-tesseract 是光學字元辨識Tesseract OCR 引擎的Python 封裝類。能夠讀取任何常規的圖片檔案(JPG, GIF ,PNG , TIFF 等)。不過,目前市面上的驗證碼形式繁多,目前任何一種驗證碼識別技術,識別率都不是100%

2.       記錄cookie

通過向瀏覽器中添加cookie 可以繞過登入的驗證碼,這是比較有意思的一種解決方案。比如我們在第一次登入某網站可以勾選“記住密碼”的選項,當下次再訪問該網站時自動就處於登入狀態了。這樣其實也繞過驗證碼問題。那麼這個“記住密碼”的功能其實就記在了瀏覽器的cookie 中。WebDriver 來操作瀏覽器的Cookie,可以通過add_cookie()方法將使用者名稱密碼寫入瀏覽器cookie ,再次訪問網站時伺服器直接讀取瀏覽器Cookie 登入。

這種方式最大的問題是如何從瀏覽器的Cookie 中找到使用者名稱和密碼對應的key 值,並傳傳輸入對應的登入資訊。可以get_cookies()方法來擷取登入的所有的cookie 資訊,從中找到使用者名稱和密碼的key。當然,如果網站登入時根本不將使用者名稱和密碼寫Cookie,這會存在一定的安全風險。那麼這種方式就不起作用了。

4.18 WebDriver 原理

         WebDriver是按照server-client的經典設計傳統模式設計。

         webdriver 的工作流程:

1. WebDriver 啟動目標瀏覽器,並綁定到指定連接埠。該啟動的瀏覽器執行個體,做為WebDriver 的remote server。

2. Client 端通過CommandExcuter 發送HTTPRequest 給remote server 的偵聽連接埠(通訊協定:the webriver wire protocol)   

3. Remote server 需要依賴原生的瀏覽器組件(如:IEDriverServer.exe、chromedriver.exe),來轉化轉化瀏覽器的native 調用。

 

在Python 提供了logging 模組,logging 模組給運行中的應用提供了一個標準的資訊輸出介面。它提供了basicConfig()方法用於基本資料的定義。將debug 模組開啟。就可以捕捉到用戶端與伺服器的互動資訊。basicConfig()開啟的debug 模式只能捕捉到用戶端向伺服器所發送的POST 請求,而無法擷取伺服器所返回應答資訊。Test.py

#coding=utf-8

from selenium import webdriver

import logging

 

logging.basicConfig(level=logging.DEBUG)

diver = webdriver.Chrome()

diver.get("http://www.baidu.com")

diver.find_element_by_id("kw").send_keys("selenium")

diver.find_element_by_id("su").click()

diver.quit()

 

Selenium2 Python 自動化測試實戰學習筆記(三)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.