Web自動化測試的基本操作實現

摘要:

之前用Selenium做UI自動化測試從初學到熟練碰到過很多問題,這裡就不一一細說了,所以把最基本的操作都寫在了一起,包括:控制瀏覽器,操作元素,鼠標事件,鍵盤事件,設置元素等待,多表單/窗口切換,警告框處理,上傳文件,操作Cookie,調用JavaScript控制瀏覽器滾動條,窗口截圖。

時間緊急,沒有仔細整理,望讀者見諒~~

目錄

1.控制瀏覽器

1.1控制瀏覽器窗口大小

1.2控制瀏覽器後退和前進

1.3模擬刷新瀏覽器

2.元素操作

2.1常用的元素操作

2.2WebElement 接口常用方法

3.鼠標事件

4.鍵盤事件

5.設置元素等待

5.1顯式等待

5.2隱式等待

5.3sleep 休眠方法

6.多表單切換

7.多窗口切換

8.警告框處理

9.上傳文件

9.1send_keys 實現上傳

9.2AutoIt 實現上傳

10.操作cookie

11.調用JavaScript控制瀏覽器滾動條

12.窗口截圖

1 控制瀏覽器

Selenium 主要提供的是操作頁面上各種元素的方法,但它也提供了操作瀏覽器本身的方法,比如瀏覽器的大小以及瀏覽器後退、前進按鈕等。

1.1控制瀏覽器窗口大小

在不同的瀏覽器大小下訪問測試站點,對測試頁面截圖並保存,然後觀察或使用圖像比對工具對被測頁面的前端樣式進行評測。比如可以將瀏覽器設置成移動端大小(480x800),然後訪問移動站點,對其樣式進行評估;WebDriver 提供了set_window_size() 方法來設置瀏覽器的大小。

例子:

#coding=utf-8

from selenium import webdriver

driver = webdriver.Firefox()

driver.get("http://192.168.30.180/Uet-Platform/")

#參數數字為像素點

print "設置瀏覽器寬480、高800 顯示"

driver.set_window_size(480, 800)

driver.quit()

在PC 端運行執行自動化測試腳本大多的情況下是希望瀏覽器在全屏幕模式下執行,那麼可以使用maximize_window()方法,其用法與set_window_size()相同,但它不需要傳參。

1.2控制瀏覽器後退和前進

在使用瀏覽器瀏覽網頁的時候,瀏覽器提供了後退和前進按鈕,可以方便的對瀏覽過的網頁之間切換,那麼WebDriver 也提供了對應的back()和forward()方法來模擬後退和前進按鈕。下面通過例子來演示這兩個方法的使用。

例子:

#coding=utf-8

from selenium import webdriver

driver = webdriver.Firefox()

first_url= 'http://www.baidu.com'

print "now access %s" %(first_url)

driver.get(first_url)

#訪問新聞頁面

second_url='http://news.baidu.com'

print "now access %s" %(second_url)

driver.get(second_url)

print "back to %s "%(first_url)

driver.back()

#前進到新聞頁

print "forward to %s"%(second_url)

driver.forward()

driver.quit()

輸出:

now access http://www.baidu.com

now access http://news.baidu.com

back to http://www.baidu.com

forward to http://news.baidu.com

1.3模擬刷新瀏覽器

有時候需要手動的刷新(F5)的刷新頁面

driver.refresh() #刷新當前頁面

2元素操作

2.1常用的元素操作

1、clear() 清除文本,如果是一個文件輸入框

2、send_keys(*value) 在元素上模擬按鍵輸入

3、click() 單擊元素

例子:

#coding=utf-8

from selenium import webdriver

import unittest, time, re

driver = webdriver.Firefox()

driver.implicitly_wait(30)

base_url ="http://192.168.30.180/Uet-Platform/masterLogin.action" #30測試環境

driver.get(base_url)

driver.find_element_by_id("txtUserName").clear()

driver.find_element_by_id("txtUserName").send_keys("13554797004")

driver.find_element_by_id("txtPassword").clear()

driver.find_element_by_id("txtPassword").send_keys("123123")

driver.find_element_by_link_text(u"登錄").click()

driver.switch_to_frame("lj_left")

driver.find_element_by_xpath("//div[@id='left']/table/tbody/tr[6]/td").click()

driver.find_element_by_link_text(u"用戶單位管理").click()

……

說明:

clear()方法用於清除文本輸入框中的內容,例如登錄框內一般默認會有“賬號”“密碼”等提示信息用於引導用戶輸入正確的數據,如果直接向輸入框中輸入數據,可能會與輸入框中的提示信息拼接,本來用戶輸入為“username”,結果與提示信息拼接為“帳號username”,從而造成輸入信息的錯誤;這個時候

可以先使用clear()方法清除輸入框內的提示信息再進行輸入。

send_keys()方法模擬鍵盤輸入向輸入框裡輸入內容。如上面的例子中通過這個方法向用戶名和密碼框中輸入用戶名和密碼。

click()方法可以用來單擊一個按鈕,前提是它是可以被點擊元素,它與send_keys()方法是web 頁面操作中最常用到的兩個方法。其實click()方法不僅僅用於點擊一個按鈕,還可以單擊任何可以點擊文字/圖片連接、複選框、單選框、甚至是下拉框等。

2.2WebElement 接口常用方法

1、submit()

submit()方法用於提交表單,這裡特別用於沒提交按鈕的情況,例如搜索框輸入關鍵字之後的“回車”操作,那麼就可以通過submit()來提交搜索框的內容。

例子:

#coding=utf-8

from selenium import webdriver

driver = webdriver.Firefox()

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

driver.find_element_by_id('query').send_keys('hello')

#提交輸入框的內容

driver.find_element_by_id('query').submit()

driver.quit()

有些時候submit()可以與click()方法互換來使用,submit()同樣可以提交一個按鈕。

2、 size 返回元素的尺寸。

3、text 獲取元素的文本。

4、get_attribute(name) 獲得屬性值。

5、is_displayed() 設置該元素是否用戶可見。

例子:

#coding=utf-8

from selenium import webdriver

driver = webdriver.Firefox()

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

#獲得輸入框的尺寸

size=driver.find_element_by_id('kw').size

print size

text=driver.find_element_by_id("cp").text

print text

#返回元素的屬性值,可以是id、name、type 或元素擁有的其它任意屬性

attribute=driver.find_element_by_id("kw").get_attribute('type')

print attribute

#返回元素的結果是否可見,返回結果為True 或False

result=driver.find_element_by_id("kw").is_displayed()

print result

driver.quit()

運行結果:

{'width': 526, 'height': 22}

©2014 Baidu 使用百度前必讀京ICP 證030173 號

True

解析:

執行上面的程序並獲得執行結果:size 用於獲取百度輸入框的寬、高。text 用於獲得百度底部的備案信息。get_attribute()用於獲百度輸入的type 屬性的值。is_displayed()用於返回一個元素是否可見,如果可見返回True,否則返回False。

3鼠標事件

在現在的web 產品中,隨著前端技術的發展,頁面越來越華麗,鼠標的操作也不單單隻有單擊,現在頁面中隨處可以看到需要右擊、雙擊、鼠標懸停、甚至是鼠標拖動等操作的功能設計。在WebDriver 中這些關於鼠標操作的方法由ActionChains 類提供。

3.1ActionChains 類提供的鼠標操作的常用方法

1、perform() 執行所有ActionChains 中存儲的行為

2、context_click() 右擊

3、double_click() 雙擊

4、drag_and_drop() 拖動

5、move_to_element() 鼠標懸停

例子1:鼠標右擊操作

對於ActionChains 類下所提供的鼠標方法與前面學過的click()方法有所不同,那麼簡單context_click()右鍵點擊一個元素。

代碼實現:

from selenium import webdriver

#引入ActionChains 類

from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()

driver.get("http://yunpan.360.cn")

....

#定位到要右擊的元素

right_click =driver.find_element_by_id("xx")

#對定位到的元素執行鼠標右鍵操作

ActionChains(driver).context_click(right_click).perform()

....

說明:

from selenium.webdriver import ActionChains

對於ActionChains 類下面的方法,在使用之前需要先將模塊導入。

ActionChains(driver)

調用ActionChains()方法,在使用將瀏覽器驅動driver 作為參數傳入。

context_click(right_click)

context_click()方法用於模擬鼠標右鍵事件,在調用時需要傳入右鍵的元素。

perform()

執行所有ActionChains 中存儲的行為,可以理解成是對整個操作事件的提交動作。

例子2:鼠標懸停

鼠標懸停彈出下拉菜單也是一個非常見的一個功能設計

move_to_element()方法可以模擬鼠標懸停的動作,其用法與context_click()相同。

代碼實現:

……

from selenium import webdriver

#引入ActionChains 類

from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()

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

....

#定位到要懸停的元素

above =driver.find_element_by_id("xx")

#對定位到的元素執行懸停操作

ActionChains(driver).move_to_element(above).perform()

....

例子3:鼠標雙擊操作

double_click(on_element)方法用於模擬鼠標雙擊操作,用法同上。

代碼實現:

……

from selenium import webdriver

#引入ActionChains 類

from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()

....

#定位到要懸停的元素

double_click = driver.find_element_by_id("xx")

#對定位到的元素執行雙擊操作

ActionChains(driver).double_click(double_click).perform()

....

例子4:鼠標推放操作

drag_and_drop(source, target)在源元素上按下鼠標左鍵,然後移動到目標元素上釋放。

source: 鼠標拖動的源元素。

target: 鼠標釋放的目標元素。

代碼實現:

……

from selenium import webdriver

#引入ActionChains 類

from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()

....

#定位元素的源位置

element = driver.find_element_by_name("xxx")

#定位元素要移動到的目標位置

target = driver.find_element_by_name("xxx")

#執行元素的拖放操作

ActionChains(driver).drag_and_drop(element,target).perform()

....

4鍵盤事件

有時候我們在測試時需要使用Tab 鍵將焦點轉移到下一個元素,Keys()類提供鍵盤上幾乎所有按鍵的方法,前面瞭解到send_keys()方法可以模擬鍵盤輸入,除此之外它還可以模擬鍵盤上的一些組合鍵,例:Ctrl+A、Ctrl+C 等。

4.1鍵盤操作

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

例子:

……

#coding=utf-8

from selenium import webdriver

#引入Keys 模塊

from selenium.webdriver.common.keys import Keys

driver = webdriver.Firefox()

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

#輸入框輸入內容

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

#刪除多輸入的一個m

driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)

#輸入空格鍵+“教程”

driver.find_element_by_id("kw").send_keys(Keys.SPACE)

driver.find_element_by_id("kw").send_keys(u"教程")

#ctrl+a 全選輸入框內容

driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')

#ctrl+x 剪切輸入框內容

driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'x')

#ctrl+v 粘貼內容到輸入框

driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'v')

#通過回車鍵盤來代替點擊操作

driver.find_element_by_id("su").send_keys(Keys.ENTER)

driver.quit()

5設置元素等待

如今大多數的web 應用程序使用AJAX 技術。當瀏覽器在加載頁面時,頁面內的元素可能並不是同時被加載完成的, 這給元素的定位添加的困難。如果因為在加載某個元素時延遲而造成ElementNotVisibleException 的情況出現,那麼就會降低的自動化腳本的穩定性。

WebDriver 提供了兩種類型的等待:顯式等待和隱式等待。

5.1顯式等待

顯式等待使WebdDriver 等待某個條件成立時繼續執行,否則在達到最大時長時拋棄超時異常(TimeoutException)。

例子:

#coding=utf-8

from selenium import webdriver

from selenium.webdriver.common.by import By

from selenium.webdriver.support.ui import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Firefox()

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

element = WebDriverWait(driver,5,0.5).until(EC.presence_of_element_located((By.ID,"kw")))

element.send_keys('selenium')

driver.quit()

WebDriverWait()

它是由webdirver 提供的等待方法。在設置時間內,默認每隔一段時間檢測一次當前頁面元素是否存

在,如果超過設置時間檢測不到則拋出異常。具體格式如下:

WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)

driver - WebDriver 的驅動程序(Ie, Firefox,Chrome 等)

timeout - 最長超時時間,默認以秒為單位

poll_frequency - 休眠時間的間隔(步長)時間,默認為0.5 秒

ignored_exceptions - 超時後的異常信息,默認情況下拋NoSuchElementException 異常。

until()

WebDriverWait()一般由until()(或until_not())方法配合使用,下面是until()和until_not()方法的說明。

until(method, message=’ ’)

調用該方法提供的驅動程序作為一個參數,直到返回值為Ture。

until_not(method, message=’ ’)

調用該方法提供的驅動程序作為一個參數,直到返回值為False。

Expected Conditions

在本例中,我們在使用expected_conditions 類時對其時行了重命名,通過as 關鍵字對其重命名為EC,

並調用presence_of_element_located()判斷元素是否存在。

expected_conditions 類提供一些預期條件的實現。

title_is 用於判斷標題是否xx。

title_contains 用於判斷標題是否包含xx 信息。

presence_of_element_located 元素是否存在。

visibility_of_element_located 元素是否可見。

visibility_of 是否可見

presence_of_all_elements_located 判斷一組元素的是否存在

text_to_be_present_in_element 判斷元素是否有xx 文本信息

text_to_be_present_in_element_value 判斷元素值是否有xx 文本信息

frame_to_be_available_and_switch_to_it 表單是否可用,並切換到該表單。

invisibility_of_element_located 判斷元素是否隱藏

element_to_be_clickable 判斷元素是否點擊,它處於可見和啟動狀態

staleness_of 等到一個元素不再是依附於DOM。

element_to_be_selected 被選中的元素。

element_located_to_be_selected 一個期望的元素位於被選中。

element_selection_state_to_be 一個期望檢查如果給定的元素被選中。

element_located_selection_state_to_be 期望找到一個元素並檢查是否選擇狀態

alert_is_present 預期一個警告信息

除了expected_conditions 所提供的預期方法,我們也可以使用前面學過的is_displayed()方法來判斷元素是否可。

例子:

#coding=utf-8

from selenium import webdriver

from selenium.webdriver.support.ui import WebDriverWait

driver = webdriver.Firefox()

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

input_ = driver.find_element_by_id("kw")

element = WebDriverWait(driver,5,0.5).until(

lambda driver : input_.is_displayed()

)

input_.send_keys('selenium')

driver.quit()

5.2隱式等待

隱式等待是通過一定的時長等待頁面所元素加載完成。哪果超出了設置的時長元素還沒有被加載測拋NoSuchElementException 異常。WebDriver 提供了implicitly_wait()方法來實現隱式等待,默認設置為0。它的用法相對來說要簡單的多。

例子:

#coding=utf-8

from selenium import webdriver

from selenium.webdriver.support.ui import WebDriverWait

driver = webdriver.Firefox()

driver.implicitly_wait(10)

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

input_ = driver.find_element_by_id("kw22")

input_.send_keys('selenium')

driver.quit()

implicitly_wait()默認參數的單位為秒,本例中設置等待時長為10 秒,首先這10 秒並非一個固定的等待時間,它並不影響腳本的執行速度。其次,它並不真對頁面上的某一元素進行等待,當腳本執行到某個元素定位時,如果元素可定位那麼繼續執行,如果元素定位不到,那麼它將以輪詢的方式不斷的判斷元素

是否被定位到,假設在第6 秒鐘定位到元素則繼續執行。直接超出設置時長(10 秒)還沒定位到元素則拋出異常。

在上面的例子中,顯然百度輸入框的定位id=kw22 是有誤的,那麼在超出10 秒後將拋出異常。

5.3sleep 休眠方法

有時間我們希望腳本執行到某一位置時做固定時間的休眠,尤其是在腳本調試的過程中。那麼可以使用sleep()方法,需要說明的是sleep()由Python 的time 模塊提供。

例子:

#coding=utf-8

from selenium import webdriver

from time import sleep

driver = webdriver.Firefox()

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

sleep(2)

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

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

sleep(3)

driver.quit()

當執行到sleep()方法時會固定的休眠所設置的時長,然後再繼續執行。sleep()方法默認參數以秒為單位,如果設置時長小於1 秒,可以用小數點表示,如:sleep(0.5)

6多表單切換

在web 應用中經常會遇到frame 嵌套頁面的應用,頁WebDriver 每次只能在一個頁面上識別元素,對於frame 嵌套內的頁面上的元素,直接定位是定位是定位不到的。這個時候就需要通過switch_to_frame()方法將當前定位的主體切換了frame 裡。

例子:

#coding=utf-8

from selenium import webdriver

import time

import os

driver = webdriver.Firefox()

file_path = 'file:///' + os.path.abspath('frame.html')

driver.get(file_path)

#切換到iframe(id = "if")

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.quit()

switch_to_frame() 默認可以直接取表單的id 或name 屬性進行切換。

……

#id = "if"

driver.switch_to_frame("if")

#name = "nf"

driver.switch_to_frame("nf")

……

那麼如果iframe 沒有可用的id 和name 可以通過下面的方式進行定位:

……

#先通過xpth 定位到iframe

xf = driver.find_element_by_xpath('//*[@class="if"]')

#再將定位對象傳給switch_to_frame()方法

driver.switch_to_frame(xf)

……

driver.switch_to_default_content()

如果完成了在當前表單上的操作可以通過switch_to_default_content()方法返回到上一層單。該方法不用指定某個表單的返回,默認對應與它最近的switch_to_frame()方法。

7多窗口切換

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

圖 多窗口

這裡以百度首頁與註冊頁為例,演示在不同窗口切換。

例子:

#coding=utf-8

from selenium import webdriver

driver = webdriver.Firefox()

driver.implicitly_wait(10)

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

sreach_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 register window!'

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 sreach window!'

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.quit()

說明:

整個腳本的處理過程:首先打開百度首頁,通過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() 是類似,前者用於不同窗口的切換,後者用於不同表單之間的切換。

8警告框處理

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

1、text 返回alert/confirm/prompt 中的文字信息。

2、accept 點擊確認按鈕。

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

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

如圖 百度搜索設置的彈出的彈窗是不能通過前端工具對其進行定位的,這個時候就可以通過switch_to_alert()方法接受這個彈窗。

例子:

#coding=utf-8

from selenium import webdriver

from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()

driver.implicitly_wait(10)

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

#鼠標懸停相“設置”鏈接

link = driver.find_element_by_link_text(u'設置')

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

#打開搜索設置

driver.find_element_by_class_name('setpref').cick()

#保存設置

driver.find_element_by_css_selector('#gxszButton > a.prefpanelgo').click()

#接收彈窗

driver.switch_to_alert().accept()

driver.quit()

9上傳文件

文件上傳操作也比較常見功能之一,上傳功能操作webdriver 並沒有提供對應的方法,關鍵上傳文件的思路。

對web 頁面的上功能,點擊“上傳”按鈕需要打開本地的Window 窗口,從窗口選擇本地文件進行上傳,那麼WebDriver 對於Windows 的控件是無能為力的

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

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

插件上傳:一般是指基於Flash 與JavaScript 或Ajax 等技術所實現的上傳功能或插件。

9.1send_keys 實現上傳

對於通過input 標籤實現的通過上傳,可以將其看作一個輸入框,通過send_keys()傳入本地文件路徑從而模擬上傳功能。

例子:

#coding=utf-8

from selenium import webdriver

import os

driver = webdriver.Firefox()

#打開上傳功能頁面

file_path = 'file:///' + os.path.abspath('upfile.html')

driver.get(file_path)

#定位上傳按鈕,添加本地文件

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

driver.quit()

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

9.2AutoIt 實現上傳

AutoIt 目前最新是v3 版本,這是一個使用類似BASIC 腳本語言的免費軟件,它設計用於WindowsGUI(圖形用戶界面)中進行自動化操作。它利用模擬鍵盤按鍵,鼠標移動和窗口/控件的組合來實現自動化任務。

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

從網站上下載AutoIt 並安裝,安裝完成在菜單中會看到圖的目錄:

圖 AutoIt 菜單

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,鼠標將變成一個小風扇形狀的圖標,按住鼠標左鍵拖動到需要識別的控件上。

圖 AutoIt Windows Info 識別“文件名”輸入框控件

圖 AutoIt Windows Info 識別“打開”按鈕控件

如圖,通過AutoIt Windows Info 獲得以下信息。

窗口的title 為“選擇要加載的文件”,標題的Class 為“#32770”。

文件名輸入框的class 為“Edit”,Instance 為“1” ,所以ClassnameNN 為“Edit1”。

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

2、根據AutoIt Windows Info 所識別到的控件信息打開SciTE Script Editor 編輯器,編寫腳本。

;ControlFocus("title","text",controlID) Edit1=Edit instance 1

ControlFocus("選擇要加載的文件", "","Edit1")

; Wait 10 seconds for the Upload window to appear

WinWait("[CLASS:#32770]","",10)

; Set the File name text on the Edit field

ControlSetText("選擇要加載的文件", "", "Edit1", "D:\\\\\\upload_file.txt")

Sleep(2000)

; Click on the Open button

ControlClick("選擇要加載的文件", "","Button1");

說明:

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 可執行文件。如下圖

圖 Compile Script to.exe 生成exe 程序

點擊“Browse”選擇upfile.au3 文件,點擊“Convert”按鈕將其生成為upfile.exe 程序。

4、下面就是通過自動化測試腳本調用upfile.exe 程序實現上傳了。

例子:

#coding=utf-8

from selenium import webdriver

import os

driver = webdriver.Firefox()

#打開上傳功能頁面

file_path = 'file:///' + os.path.abspath('upfile.html')

driver.get(file_path)

#點擊打開上傳窗口

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

#調用upfile.exe 上傳程序

os.system("D:\\\\\\upfile.exe")

driver.quit()

通過Python 的os 模塊的system()方法可以調用exe 程序並執行。

10操作cookie

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

10.1操作cookie方法

webdriver 操作cookie 的方法有:

1、get_cookies() 獲得所有cookie 信息

2、get_cookie(name) 返回有特定name 值有cookie 信息

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

4、delete_cookie(name) 刪除特定(部分)的cookie 信息

5、delete_all_cookies() 刪除所有cookie 信息

下面通過get_cookies()來獲取當前瀏覽器的cookie 信息。

程序實現:

#coding=utf-8

from selenium import webdriver

import time

driver = webdriver.Chrome()

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

# 獲得cookie 信息

cookie= driver.get_cookies()

#將獲得cookie 的信息打印

print cookie

driver.quit()

執行結果:

>>> ============= RESTART ===============

>>>

[{u'domain': u'.youdao.com',

u'secure': False,

u'value': u'aGFzbG9nZ2VkPXRydWU=',

u'expiry': 1408430390.991375,

u'path': u'/',

u'name': u'_PREF_ANONYUSER__MYTH'},

{u'domain': u'.youdao.com',

u'secure': False,

u'value': u'1777851312@218.17.158.115',

u'expiry': 2322974390.991376,

u'path': u'/', u'name':

u'OUTFOX_SEARCH_USER_ID'},

{u'path': u'/',

u'domain': u'www.youdao.com',

u'name': u'JSESSIONID',

u'value': u'abcUX9zdw0minadIhtvcu',

u'secure': False}]

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

例子:

#coding=utf-8

from selenium import webdriver

import time

driver = webdriver.Firefox()

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

#向cookie 的name 和value 添加會話信息。

driver.add_cookie({'name':'key-aaaaaaa', 'value':'value-bbbbbb'})

#遍歷cookies 中的name 和value 信息打印,當然還有上面添加的信息

for cookie in driver.get_cookies():

print "%s -> %s" % (cookie['name'], cookie['value'])

driver.quit()

執行結果:

>>> ======================= RESTART ======================

>>>

YOUDAO_MOBILE_ACCESS_TYPE -> 1

_PREF_ANONYUSER__MYTH -> aGFzbG9nZ2VkPXRydWU=

OUTFOX_SEARCH_USER_ID -> -1046383847@218.17.158.115

JSESSIONID -> abc7qSE_SBGsVgnVLBvcu

key-aaaaaaa -> value-bbbbbb

從打印結果可以看到最後一條cookie 信息是在腳本執行過程中通add_cookie()方法添加的。通過遍歷得到的所cookie 信息從而找到key 為“name”和“value”的特定cookie 的value。

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

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

11調用JavaScript控制瀏覽器滾動條

WebDiver 不能操作本地Windows 控件,但對於瀏覽器上的控件也不是都可以操作的。比哪瀏覽器上的滾動條,雖然WebDriver 提供操作瀏覽器的前進和後退按鈕,但對於滾動條並沒有提供相應用的方法。那麼在這種情況下就可以藉助JavaScript 方法來控制瀏覽器滾動條。WebDriver 提供了execute_script()方法來執行JavaScript 代碼。

一般用到操作滾動條的會兩個場景:

(1)註冊時的法律條文的閱讀,判斷用戶是否閱讀完成的標準是:滾動條是否拉到最下方。

(2)要操作的頁面元素不在視覺範圍,無法進行操作,需要拖動滾動條。

用於標識滾動條位置的代碼

例子:

……


……

document.body.scrollTop

網頁被捲去的高。scrollTop 設置或獲取滾動條與最頂端之間的距離。如果想讓滾動條處於頂部,那麼可以設置scrollTop 的值為0,如果想讓滾動條處於最底端,可以將這個值設置的足夠大,大個窗口的高度即可。scrollTop 的值以像素為單位。

例子:

#coding=utf-8

from selenium import webdriver

import time

driver=webdriver.Firefox()

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="document.documentElement.scrollTop=10000"

driver.execute_script(js)

time.sleep(3)

#將滾動條移動到頁面的頂部

js_="document.documentElement.scrollTop=0"

driver.execute_script(js_)

time.sleep(3)

driver.quit()

通過瀏覽器打開百度進行搜索,搜索的一屏無法完全顯示將會出現滾動條。這個時候就可以通過JavaScript 代碼控制滾動條在任意位置,需要改變的就是scrollTop 的值。通過execute_script()方法來執行這段JavaScript 代碼。

有時候滾動條不僅上下有,如上圖,其它左右也有,那麼可以通過下面JavaScript 代碼來實現上下與左右滾動條的任意推動。

例子:

……

#window.scrollTo(左邊距,上邊距);

window.scrollTo(0,450);

……

js=" window.scrollTo(200,1000);"

driver.execute_script(js)

用法與同上,通過execute_script()調用此代碼,修改scrollTo()的參數即可。

當然,JavaScript 的作用不僅於此,它同樣可操作頁面上的元素或讓,或讓這個元素隱藏。

12窗口截圖

自動化腳本是交給工具去執行,有時候打印的錯誤信息並不十分明確,如果在腳本執行出錯的時候將對當前窗口截圖保存,那麼通過圖片信息會更只觀幫助我們找到腳本出錯的原因。Webdriver 提供了截圖函數get_screenshot_as_file()來截取當前窗口。

例子:

#coding=utf-8

from selenium import webdriver

driver = webdriver.Chrome()

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

try:

driver.find_element_by_id('kw_error').send_key('selenium')

driver.find_element_by_id('su').click()

except :

driver.get_screenshot_as_file("D:\\\\baidu_error.jpg")

driver.quit()

在本例中用到了Python 的異常處理,要本例中百度輸入框的id=kw_error 會定位不到元素,那麼try就會捕捉到這個異常,從而執行except,在except 中執行get_screenshot_as_file()對當前窗口進行截圖,這裡需要指定圖片的保存路徑及文件名,並且關閉當前驅動。

腳本運行完成打開D 盤就可以找到baidu_error.jpg 圖片文件了。