Selenium基礎

Selenium(1)環境搭建

1、selenium介紹css

selenium主要用於web應用程序的自動化測試,還支持全部基於web的管理任務自動化。html

selenium經歷了2個版本,selenium1.0和selenium2.0;selenium不是一個單獨的工具,而是由一些插件、類庫構成,每一個組成部分都有其特色和應用場景。前端

selenium2.0由如下組件構成:python

selenium2.0 = selenium1.0 + Webdriverweb

Webdirver:經過原生瀏覽器支持或擴展來直接控制瀏覽器,針對各個瀏覽器開發,與瀏覽器緊密集成,支持建立更高級的測試,其還能夠利用操做系統級的調用,模擬用戶輸入;chrome

selenium IDE:嵌入到Firefox瀏覽器中的一個插件,實現簡單的瀏覽器操做錄製與回放功能,主要用於快速建立BUG及重現腳本,可轉化爲多種語言;編程

selenium Gird:測試輔助工具,利用現有的計算機基礎設施,實現多臺計算上和異構環境中運行測試用例;設計模式

selenium RC:selenium的核心組件,支持多種不一樣語言編寫自動化測試腳本,經過其服務器做爲代理服務器去訪問應用,達到測試的目的;瀏覽器

             Client Libraries:Client Libraries庫主要用於編寫測試腳本,用來控制Selenium Server的庫;安全

             Selenium Server:負責控制瀏覽器行爲;

                              Selenium Core(一個JavaScript函數集合):被嵌入到瀏覽器中,經過它實現用程序對瀏覽器進行操做;

                              Launcher:用於啓動瀏覽器,把Core加載到瀏覽器頁面當中,並把瀏覽器代理設置爲Selenium Server的HTTP Proxy

 

2、環境搭建

一、安裝python

登陸Python官網,找到download,選擇與自身平臺(Windows/Linux)相符的版本下載(建議3.5+),而後安裝便可;

注意:安裝時選擇安裝界面的「Add Python 3.x to PATH」進行勾選,避免再次配置環境變量;

安裝完成後經過Windows命令提示符CMD輸入「python」,查看是否安裝成功,以下圖所示:

如上圖所示,則證實安裝成功;

 

二、安裝setuptools與pip

setuptools是PEAK(Python enterprise Application Kit)的一個副項目,是python的distutilsde的加強工具,能夠更方便建立和發佈python包,特別是對其餘包有依賴的狀況;

pip是一個安裝和管理python包的工具,經過pip來安裝python包將變得很簡單,省去了繁瑣的過程,pip的安裝依賴於setuptools,安裝pip以前須要先安裝setuptools;

注意:python目前不支持setuptools,所以須要使用distribute;

setuptools與pip的下載地址以下:

setuptools:https://pypi.python.org/pypi/setuptools

pip:https://pypi.org/project/pip/

注意: 最新版的python安裝包中已經集成了pip,能夠在安裝目錄下的script路徑下查看是否有pip.exe或pip3.exe文件,若是有,則cmd命令行中輸入pip進行驗證;

如上圖所示,則證實已經安裝pip;

 

三、安裝selenium

完成上面2個步驟以後,能夠經過cmd命令直接安裝selenium包,以下圖所示:

注意:安裝時若是隻輸入包名,則默認安裝當前庫中的最新版本,若是想安裝本身須要的版本,則須要在包名後面加上版本號,好比:

pip install selenium==2.48.0

 

四、下載瀏覽器驅動

前面說過,selenium支持多種瀏覽器,因此只須要下載對應的瀏覽器驅動,將解壓獲得的exe文件放到python的安裝目錄下便可;

各個瀏覽器驅動下載地址:https://www.seleniumhq.org/download/

 

五、調試

打開一款python編譯器,輸入下面的代碼,運行,查看是否成功調用瀏覽器運行,若是運行成功,則說明已成功搭建好自動化開發環境;

 

Selenium(2)WebDriver簡介及元素定位

1、WebDriver原理

一、關於WebDriver

設計模式:按照Server-Client的經典設計模式設計;

Server端:即Remote Server(遠程服務器),能夠是任意的瀏覽器,當腳本啓動瀏覽器時,該瀏覽器就是Remote Server,它的職責是等待Client發送請求並作出響應;

Client端:簡單來講就是咱們的測試代碼,測試代碼中的一些行爲是以HTTP請求的方式發送給被測試瀏覽器——Remote Server,Remote Server接受請求,執行相應操做,

         並在Response中返回執行狀態、返回值等信息;

 

二、WebDriver工做流程

①WebDriver啓動目標瀏覽器,並綁定至指定端口,啓動的瀏覽器實例將做爲WebDriver的Remote Server;

②Client端經過CommandExcuter發送HTTPRequest給Remote Server的偵聽端口(通訊協議:the webdriver wire protocol);

③Remote Server須要依賴原生的瀏覽器組件(好比:chromedriver.exe)來轉化瀏覽器的native調用;

 

三、WebDriver.log

python提供了logging模塊給運行中的應用,提供了一個標準的信息輸出接口。它提供了basicConfig方法用於基本信息的定義,開啓debug模塊,

就能夠捕捉到Client端向Server端發送的請求,例子以下:

1 # coding=utf-8
 2 # 導入logging模塊,捕捉Client發送的請求
 3 from selenium import webdriver
 4 import logging
 5 from selenium import webdriver
 6 from selenium.webdriver.support.select import Select # select類
 7 from selenium.webdriver.common.by import By #By類:定位元素
 8 
 9 logging.basicConfig(level=logging.DEBUG)
10 driver = webdriver.Chrome("F:\安裝工具\python\chromedriver.exe")
11 driver.get("www.baidu.com")
12 
13 driver.find_element_by_id("kw").send_keys("selenium")
14 driver.find_element_by_id("su").click()
15 driver.quit() 

2、WebDriver定位方法

WebDriver是基於selenium設計的操做瀏覽器的一套API,針對多種編程語言都實現了這套API,站在python角度來講,WebDriver是python的一個用於實現Web自動化的第三方庫。

一、WebDriver定位方法

WebDriver定位方法提供了八種元素定位方法,所對應的方法、特性分別是:

 

二、XPath和CSS的相似功能對比

 

三、用By定位元素

針對前面介紹的8種定位方法,WebDriver還提供另外一種方法,即:統一調用find_element()方法,經過By來聲明定位方法,而且傳入對應定位方法的定位參數,例子以下:

find.element()方法只用於定位元素,它須要兩個參數,第一個參數是定位的類型,由By提供,第二個參數是定位的具體方式,在使用By以前須要將By類導入;

# 導入By類的包
from selenium.webdriver.common.by import By
find.element(by.id,"kw")
find.element(by.name,"wd")
find.element(by.class_name,"s_ipt")
find.element(by.tag_name,"input")
find.element(by.link_text,"新聞")
find.element(by.partial_link_text,"")
find.element(by.xpath,"//*[@class='bg s_btn'")
find.element(by.css_selector,"span.bg s_btn_wr>input#su")

四、定位一組元素

上面提到的8種定位方法,都是針對單個元素定位的,webdriver還提供了與之對應的8種用於定位一組元素的方法。其通常應用於如下場景:

①批量操做元素,例如勾選頁面上全部的複選框;

②先獲取一組元素,再從這組元素中過濾出須要操做的元素;

定位一組元素的方法與定位單個元素的用法類似,惟一的區別是在element後面多一個s表示複數,具體以下:

# webdriver提供的定位一組元素方法
id                    find_elements_by_id()
Name                  find_elements_by_name()
class_name            find_elements_by_class_name()
tag Name              find_elements_by_tag_name()          
link text             find_elements_by_link_text()
partial link text     find_elements_by_partial_link_text()
xpath                 find_elements_by_xpath()
css selector          find_elements_by_css_selector()

獲取一組元素中某個元素的幾個方法:

len():用來計算元素的個數,經過print()打印出計算的結果;

pos()或pop(-1):默認獲取一組元素的最後一個元素,並返回該元素的值;

pop(0):默認獲取一組元素的第一個元素,並返回該元素的值;

pop(1):默認獲取一組元素的第二個元素,並返回該元素的值;

......

 

3、WebElement接口經常使用方法

一般須要與頁面交互的方法都由WebElement接口提供,包括上面提到的8種定位方法,下面介紹經常使用的幾種方法:

submit():用於提交表單,例如搜索框輸入關鍵字以後的「回車」操做,例如:

# 提交表單
from select import webdriver
driver = webdriver.Chrome("安裝工具\python\chromedriver.exe")
driver.get("http://www.baidu.com")
driver.find_element_by_id("kw").send_keys("imyalost")
# 提交輸入框中的內容
driver.find_element_by_id("imyalost").submit()
driver.quit()

注意:有時候submit()方法和click()方法能夠互用,但submit()的應用範圍不及click()普遍;

clear():清除文本;

send_keys(*value):模擬按鍵輸入;

click():單擊元素;

size:返回元素的尺寸;

text:獲取元素的文本;

get.attribute(name):得到屬性值;

is_displayed():設置該元素是否用戶可見;

# webelement接口經常使用方法
from selenium import webdriver
driver = webdriver.Chrome("安裝工具\python\chromedriver.exe")
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或Flase
result = driver.find_element_by_id("kw").is_displayed()
print("result")

 

Selenium(3)瀏覽器及鼠標,鍵盤事件

1、控制瀏覽器

webdriver主要提供操做頁面上各類元素的方法,但它也提供操做瀏覽器的一些方法,例如控制瀏覽器大小、前進和後退等。

一、控制瀏覽器窗口大小

# 控制瀏覽器大小
from selenium import webdriver
driver = webdriver.Chrome("安裝工具\python\chromedriver.exe")
driver.get("http://www.baidu.com")
# 參數數字爲像素點
print("設置瀏覽器寬480、高800顯示")
driver.set_window_size(480,800)

二、全屏顯示

webdriver提供了maximize_window()方法使打開的瀏覽器全屏顯示,其用法與set_window_size()相同。

三、控制瀏覽器前進、後退

如今的瀏覽器在瀏覽網頁時都提供了前進和後退功能,webdriver也提供了對應的forward()和back()方法,來模擬前進和後退按鈕:

# 控制瀏覽器前進、後退
from selenium import webdriver
driver = webdriver.Chrome("安裝工具\python\chromedriver.exe")
# 訪問百度首頁
first_url='http://www.baidu.com''
print("now access %s "%(first_url))
driver.get(first_url)
# 訪問新聞頁面
second_url='http://www.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()

爲了看清腳本執行過程,每一步的操做都經過print()打印當前的URL地址,執行結果以下:

now access http://www.baidu.com

now access http://news.baidu.com

back to http://www.baidu.com

froward to http://news.baidu.com

四、模擬瀏覽器前刷新

通常咱們刷新頁面都是經過F5或者頁面上的刷新按鈕,webdriver也提供了刷新方法refresh(),用來模擬頁面刷新:

......

# 刷新當前頁面

driver.refresh()

......

 

2、鼠標事件

在webelement接口提供的方法中,能夠經過click()來模擬鼠標單擊操做,但實際上鼠標交互方式不少,例如:右擊、懸停、鼠標拖動等功能;

webdriver提供了ActionChains類,封裝了鼠標操做的經常使用方法:

perform():執行全部的ActionChains中存儲的行爲

context_click():鼠標右擊

double_click():鼠標雙擊

drag_and_drop():鼠標拖動

move_to_element():鼠標懸停

一、鼠標右擊操做

# 鼠標右擊操做
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome("安裝工具\python\chromedriver.exe")
driver.get("http://www.baidu.com")
# 定位到要右擊的元素
right_click = driver.find_element_by_id("KW")
# 對定位到的元素執行鼠標右擊操做
ActionChains(driver).context_click(right_click).perform()
...

二、鼠標懸停

鼠標懸停彈出下拉菜單也是一個十分常見的功能設計,move_to_element()方法能夠模擬鼠標懸停動做,其用法與context_click()相同;

1 # 鼠標懸停
2 ...
3 above = driver.find_element_by_id("id")
4 ActionChains(driver).move_to_element(above).perform()
5 ... 

三、鼠標雙擊操做

double_click()方法用於模擬鼠標雙擊操做;

1 # 鼠標雙擊操做
2 ...
3 double_click = driver.find_element_by_id("id")
4 ActionChains(driver).double_click(double_click).perform()
5 ...

四、鼠標拖放操做

drag_and_drop(source,target)在源元素上按住鼠標左鍵,而後移動到目標元素上釋放;

source:鼠標拖動的源元素

target:鼠標釋放的目標元素

# 定位元素的位置
...
element = driver.find_element_by_id("id")
# 定位元素要移動到的目標位置
target = driver.find_element_by_id("xx")
# 執行元素的拖放操做
ActionChains(driver).drag_and_drop(element,target).perform()
...

3、鍵盤事件

Keys()類提供了鍵盤上幾乎全部的按鍵方法,send_keys()不見能夠模擬鍵盤輸入,還能夠用來輸入鍵盤上的按鍵,甚至是組合鍵,例子以下:

# 模擬鍵盤事件
from selenium import webdriver
# 引入keys模塊
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome("安裝工具\python\chromedriver.exe")
driver.get("http://www.baidu.com")
# 輸入框輸入內容
driver.find_element_by_id("kw").send_keys("selenium")
# 輸入「教程」
driver.find_element_by_id("kw").send_keys("教程")
# 刪除「教程」
driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)
...

如下爲經常使用的鍵盤操做:

# 經常使用的鍵盤操做
send_keys(Keys.BACK_SPACE)
send_keys(Keys.SPACE)
send_keys(Keys.TAB)
send_keys(Keys.ESCAPE)
send_keys(Keys.ENTER)
send_keys(Keys.CONTROL,'a')
send_keys(Keys.CONTROL,'c')
send_keys(Keys.CONTROL,'v')
send_keys(Keys.CONTROL,'x')
send_keys(Keys.F1)
...
send_keys(Keys.F12)

以上爲webdriver的控制瀏覽器操做以及模擬鍵盤、鼠標操做的經常使用方法,固然具體在實際使用過程當中,還須要結合實際的業務場景,靈活運用

 

Selenium(4)斷言

在編寫自動化測試腳本時,爲了使「機器」去自動辨識test case的執行結果是True仍是False,通常都須要在用例執行過程當中獲取一些信息,來判斷用例的執行時成功仍是失敗。

判斷成功失敗與否,就涉及到斷言。webdriver的斷言使用有三種模式:操做(action)、輔助(accessors)、斷言(assertion)。

 

一、操做(action)

模擬用戶與Web應用程序的交互,通常用於操做應用程序的狀態;

如點擊連接,選擇選項的方式進行工做;若是一個動做執行失敗,或是有錯誤,當前的測試將會中止執行。

常見命令以下:

open(打開頁面)

click(點擊)

clickAndWait(點擊並等待)

type(文本類型)

select(選擇下拉菜單)

selectWindow(選擇彈出窗口)

pause(等待指定時間,以毫秒爲單位,即要睡眠的時間)

setSpeed(設定執行速度。以毫秒延遲間隔長度。默認沒有延遲,即爲0)

setTimeout(指定等待動做完成的等待時間。默認爲30秒,須要等待的動做包括了OPEN 和WAITFOR)

goBack(模擬用戶點擊其瀏覽器上的「back」按鈕)

close(模擬用戶點擊彈出窗體或表單標題欄上的」關閉」按鈕)

 

二、輔助(accessors)

輔助工具,用於檢查應用程序的狀態並將結果存儲到變量中;

如:storeElementPresent(locator,variableName)

其中參數locator表示元素定位器,variableName用於存儲結果的變量名;

即將locator定位到的狀態存儲到variableName變量中,若是該元素出現返回true,不然返回false,可同斷言一同使用。

 

三、斷言(assertion)

驗證應用程序的狀態是否同所指望的一致。

常見的斷言包括:驗證頁面內容,如標題是否爲X或當前位置是否正確,或是驗證該複選框是否被勾選。

經常使用斷言以下:

assertLocation(判斷當前是在正確的頁面)

assertTitle(檢查當前頁面的title是否正確)

assertValue(檢查input的值, checkbox或radio,有值爲」on」無爲」off」)

assertSelected(檢查select的下拉菜單中選中是否正確)

assertSelectedOptions(檢查下拉菜單中的選項的是否正確)

assertText(檢查指定元素的文本)

assertTextPresent(檢查在當前給用戶顯示的頁面上是否有出現指定的文本)

assertTextNotPresent(檢查在當前給用戶顯示的頁面上是否沒有出現指定的文本)

assertAttribute(檢查當前指定元素的屬性的值)

assertTable(檢查table裏的某個cell中的值)

assertEditable(檢查指定的input是否能夠編輯)

assertNotEditable(檢查指定的input是否不能夠編輯)

assertAlert(檢查是否有產生帶指定message的alert對話框)

waitForElementPresent (等待檢驗某元素的存在,爲真時,則執行)

使用斷言的注意點:

①不要使用斷言做爲公共方法的參數檢查,公共方法的參數永遠都要執行;

②斷言語句不能夠有任何邊界效應,不要使用斷言語句去修改變量和改變方法的返回值;

 

Selenium(5)解決頁面元素display:none的方法

在UI自動化測試中,有時候會遇到頁面元素沒法定位的問題,包括xpath等方法都沒法定位,是由於前端元素被設置爲不可見致使。

 

一、具體問題

常見的頁面元素不可見致使的不可定位,都是因爲下面的問題:

經過查看相關文檔,能夠看出display:none方法是設置元素不可見,這就是致使爲何經過定位頁面元素沒法定位的緣由。

 

二、解決方案

對於這種問題,能夠經過JavaScript修改頁面元素屬性來將元素置位可見,而後經過id、classname等方法去定位,示例代碼以下(針對上圖所示):

js = "document.getElementById(\"txtPassword\").style.display='block';"
# 調用js腳本
driver.execute_script(js)
sleep(3)
driver.find_element_by_id("txtPassword").send_keys("123456")

代碼解析:

首先經過selenium封裝好的方法document去找到display元素,document提供如下方法來定位display元素:

getElementById():返回對指定ID第一個對象的引用

getElementsByName() :返回帶有指定名稱的對象集合

getElementsByTagName():返回帶有指定標籤名的對象集合

上面我定義了一個js變量,而後經過getElementById()方法去引用display元素,修改none屬性爲block屬性(做爲塊級元素顯示),而後經過selenium自帶的execute_script方法執行腳本。

最後,當元素屬性置爲可見時,能夠經過ID去定位元素。

 

其實還有一個解決方案:讓前端修改display:none爲block就行了,但這樣的話,帶來的變化和安全風險又是須要考慮的問題。一個問題的解決老是伴隨着新的問題,核裂變了解一下?

想起今天和同行聊天時提及的分裂BUG的話題,對話以下:

大佬N:核裂變的原理是經過中子撞擊原子核產生多個新的原子核,原子核是已有的BUG,中子是修改BUG加上的代碼,分裂以後這個bug消失了,取而代之的是更多的原子核(BUG)。。。

我:引發一個BUG的緣由多是多個,修改一段代碼可能形成多個BUG,就像用新技術解決舊問題而帶來的新問題一個意思。。。

 

自動化自己最大的挑戰仍是變化,所以從分層測試角度結合公司項目具體狀況,考慮解決問題的方法,纔是最好的選擇。

 

Selenium(6)利用Select模塊處理下拉框

在利用selenium進行UI自動化測試過程當中,常常會遇到下拉框選項,這篇博客,就介紹下如何利用selenium的Select模塊來對標準select下拉框進行操做。。。

 

首先導入Select模塊:

1 # coding=utf-8
2 from selenium import webdriver
3 from selenium.webdriver.support.select import Select

感興趣的能夠將鼠標指向Select,而後按住Ctrl鼠標單擊,查看Select模塊的源碼,是如何定義封裝Select的各個方法的。

一、Select提供了三種選擇某一項的方法

1 select_by_index          # 經過索引定位
2 select_by_value          # 經過value值定位
3 select_by_visible_text   # 經過文本值定位

注意事項:

index索引是從「0」開始;

value是option標籤的一個屬性值,並非顯示在下拉框中的值;

visible_text是在option標籤中間的值,是顯示在下拉框的值;

 

二、Select提供了三種返回options信息的方法

1 options                  # 返回select元素全部的options
2 all_selected_options     # 返回select元素中全部已選中的選項
3 first_selected_options   # 返回select元素中選中的第一個選項

注意事項:

這三種方法的做用是查看已選中的元素是不是本身但願選擇的:

options:提供全部選項的元素列表;

all_selected_options:提供全部被選中選項的元素列表;

first_selected_option:提供第一個被選中的選項元素;

 

三、Select提供了四種取消選中項的方法

1 deselect_all             # 取消所有的已選擇項
2 deselect_by_index        # 取消已選中的索引項
3 deselect_by_value        # 取消已選中的value值
4 deselect_by_visible_text # 取消已選中的文本值

注意事項:

在平常的web測試中,會常常遇到某些下拉框選項已經被默認選中,這種時候就須要用到這裏所說的四種方法;

 

下面以實際的代碼來作個示例,被測試網頁與源碼截圖以下:

好比要選擇3線,那麼三種選擇方法示例代碼以下:

# coding=utf-8
from selenium import webdriver
from selenium.webdriver.support.select import Select
from time import sleep

# 登陸
driver = webdriver.Chrome()
......

# 根據索引選擇
Select(driver.find_element_by_name("storeDeclare.cityLine")).select_by_index("3")
# 根據value值選擇
Select(driver.find_element_by_name("storeDeclare.cityLine")).select_by_value("3線")
# 根據文本值選擇
Select(driver.find_element_by_name("storeDeclare.cityLine")).select_by_visible_text("3線")
sleep(5)
driver.quit()

以上就是關於selenium的Select模塊提供的幾種方法的用法,示例代碼只是示例,具體實踐還須要結合實際的工做須要來進行

 

Selenium(7)三種等待方式

UI自動化測試,大多都是經過定位頁面元素來模擬實際的生產場景操做。但在編寫自動化測試腳本中,常常出現元素定位不到的狀況,究其緣由,無非兩種狀況:一、有frame;二、沒有設置等待。

由於代碼運行速度和瀏覽器加載渲染速度,不是一個量級,因此致使了這種狀況發生。webdriver提供了3種類型的等待:顯式等待、隱式等待、強制等待。

 

一、顯示等待

定義:等待某個條件成立時繼續執行,不然在達到最大時長時拋出異常(TimeoutException);

WebDriverWait類是由webdriver提供的等待方法,配合該類提供的until()和until_not()方法一塊兒使用,就能夠根據判斷條件而靈活進行等待,格式以下:
WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
driver:瀏覽器驅動
timeout:最長超時時間
poll_frequency:檢測間隔時間,默認0.5s
ignored_exceptions:超時後的異常信息,默認狀況拋出NoSuchElementException異常
WebDriverWait()通常由until()或until_not方法配合使用,下面是這兩種方法的說明:
until(method,message=''):調用該方法提供的驅動程序做爲一個參數,直到返回值爲True;
until_not(method,message=''):調用該方法提供的驅動程序做爲一個參數,直到返回值爲Flase;

示例代碼以下:

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
 
driver = webdriver.Chrome("F:\安裝工具\python\chromedriver.exe")
driver.implicitly_wait(10)
driver.get('http://www.cnblogs.com/imyalost/')
locator = (By.LINK_TEXT, '老_張')
 
try:
    WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(locator))
    print(driver.find_element_by_link_text('老_張').get_attribute('href'))
finally:
    driver.close()

代碼解析:

本例中,經過as關鍵字將expected_conditions重命名爲EC,並調用presence_of_element_located()方法判斷元素是否存在;

上面的例子中,同時使用了隱性等待和顯性等待,可是須要注意的是:等待的最長時間取二者之中的最大值;

expected_conditions類提供的預期條件判斷方法以下:
title_is: 判斷當前頁面的title是否徹底等於(==)預期字符串,返回布爾值
title_contains : 判斷當前頁面的title是否包含預期字符串,返回布爾值
presence_of_element_located : 判斷某個元素是否被加到了dom樹裏,並不表明該元素必定可見
visibility_of_element_located : 判斷某個元素是否可見. 可見表明元素非隱藏,而且元素的寬和高都不等於0
visibility_of : 跟上面的方法作同樣的事情,只是上面的方法要傳入locator,這個方法直接傳定位到的element就行了
presence_of_all_elements_located : 判斷是否至少有1個元素存在於dom樹中。舉個例子,若是頁面上有n個元素的class都是‘column-md-3‘,那麼只要有1個元素存在,這個方法就返回True
text_to_be_present_in_element : 判斷某個元素中的text是否 包含 了預期的字符串
text_to_be_present_in_element_value : 判斷某個元素中的value屬性是否 包含 了預期的字符串
frame_to_be_available_and_switch_to_it : 判斷該frame是否能夠switch進去,若是能夠的話,返回True而且switch進去,不然返回False
invisibility_of_element_located : 判斷某個元素中是否不存在於dom樹或不可見
element_to_be_clickable : 判斷某個元素中是否可見而且是enable的,這樣的話才叫clickable
staleness_of : 等某個元素從dom樹中移除,注意,這個方法也是返回True或False
element_to_be_selected : 判斷某個元素是否被選中了,通常用在下拉列表
element_selection_state_to_be : 判斷某個元素的選中狀態是否符合預期
element_located_selection_state_to_be : 跟上面的方法做用同樣,只是上面的方法傳入定位到的element,而這個方法傳入locator
alert_is_present : 判斷頁面上是否存在alert

二、隱式等待

定義:經過設定的時長等待頁面元素加載完成,再執行下面的代碼,若是超過設定時間還未加載完成,則繼續執行下面的代碼(注意:在設定時間內加載完成則當即執行下面的代碼);

隱式等待的方法爲:implicitly_wait,示例代碼以下:

# coding = utf-8
from selenium import webdriver
 
driver = webdriver.Chrome("F:\安裝工具\python\chromedriver.exe")
driver.implicitly_wait(10) # 隱性等待,最長等10秒
driver.get('http://www.cnblogs.com/imyalost/')
 
print(driver.current_url)
driver.quit()

代碼解析:

本例中,設置的等待時長爲10秒,但這10秒並不是一個固定時間,並不影響腳本執行速度;其次,隱式等待對整個driver的週期都起做用,所以只須要設置一次便可。

 

三、強制等待

即sleep()方法,由python中的time模塊提供,強制讓代碼等待xxx時間,不管前面的代碼是否執行完成或者還未完成,都必須等待設定的時間。

示例代碼以下:

# coding = utf-8
from selenium import webdriver
from time import sleep
 
driver = webdriver.Chrome("F:\安裝工具\python\chromedriver.exe")
driver.get('http://www.cnblogs.com/imyalost/')

sleep(5)
 
print(driver.current_url)
driver.quit()

代碼解析:

本例中,設置強制等待時間爲5秒,5秒以後,打印獲取到的當前頁面的url,而後關閉窗口。

這種強制等待的方法,在debug時候頗有用,不過建議慎用這種方法,由於太死板,嚴重影響程序執行速度!

 

以上三種等待方法,在具體的場景中須要根據狀況選擇合適的方法,靈活運用。。。

 

Selenium(8)Html測試報告

自動化測試過程當中,得到用例的執行結果後,須要有具象化、簡潔明瞭的測試結果,好比:用例執行時間、失敗用例數、失敗的緣由等,這時候,就須要用到測試報告。

HTML測試報告是python語言自帶的單元測試框架,其擴展的HTMLTestRunner模塊可用於生成易於使用的HTML測試報告。

 

一、HTMLTestRunner下載

下載地址:http://tungwaiyip.info/software/HTMLTestRunner.html

下載完成後,將下載的文件保存到C盤的\Python35\Lib目錄下(能夠經過以下命令獲取python安裝目錄):

①進入cmd命令行

②輸入python

③輸入import sys

④輸入print(sys.path)

C:\Users\dell>python
Python 3.5.1 (v3.5.1:37a07cee5969, Dec  6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> print(sys.path)
['', 'C:\\Users\\dell\\AppData\\Local\\Programs\\Python\\Python35\\python35.zip', 'C:\\Users\\dell\\AppData\\Local\\Programs\\Python\\Python35\\DLLs',
  'C:\\Users\\dell\\AppData\\Local\\Programs\\Python\\Python35\\lib', 'C:\\Users\\dell\\AppData\\Local\\Programs\\Python\\Python35', 'C:\\Users\\dell\\
  AppData\\Local\\Programs\\Python\\Python35\\lib\\site-packages']

 

二、修改HTMLTestRunner文件

由於HTMLTestRunner是基於python2開發的,爲了使其支持python3的環境,須要對其中的部份內容進行修改,修改後的內容以下:

# HTMLTestRunner修改內容
# 第94行
import io
# 第539行
self.outputBuffer = io.StringIO()
# 第631行
print(sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime))
# 第642行
if not cls in rmap:
# 第766行
uo = o
# 第772行
ue = e

三、python文件執行與調用

①python文件的後綴爲.py

②py文件既能夠用來執行,就像一小段程序,也能夠用來做爲模塊被導入

③在python中導入模塊通常用import

代碼以下:

from selenium import webdriver
import unittest
import time

class MyTest(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver,Chrome("F:\安裝工具\python\chromedriver.exe")
        self.driver.maximize_window()
        self.driver.implicitly.wait(10)
        self.base_url = "http://www.baidu.com"

    def test_baidu(self):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_id("kw").clear()
        driver.find_element_by_id("kw").send_key("unittest")
        driver.find_element_by_id("su").click()
        time.sleep(2)
        title = assertEqual(title,"unittest_百度搜索")

    def tearDown(self):
        self.driver.quit()

if __name__ == "__main__":
    unittest.main()

 

四、HTMLTestRunner測試報告

以上面的test_baidu.py文件爲例子,生成HTMLTestRunner測試報告,代碼以下:

from selenium import webdriver
import unittest
from HTMLTestRunner import HTMLTestRunner

class Baidu(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome("F:\安裝工具\python\chromedriver.exe")
        self.driver.implicitly_wait(10)
        self.base_url = "http://www.baidu.com/"

    def test_baidu_search(self):
        driver = self.driver
        driver.get(self.base_url)
        driver.find_element_by_id("kw").send_key("HTMLTestRunner")
        driver.find_element_by_id("su").click()

    def tearDown(self):
        self.driver.quit()


if __name__ == "__main__":
    baidu = Baidu("test_baidu_search")
    testunit = unittest.TestSuite()
    testunit.addTest(baidu)

    # 定義報告存放路徑
    fp = open('./result.html', 'wb')
    # 定義測試報告
    runner = HTMLTestRunner(stream=fp,
                        title='百度搜索測試報告',
                        description= '用例執行狀況:')
    runner.run(testunit) #運行測試用例
    fp.close() #關閉報告文件

代碼簡析:

①將HTMLTestRunner模塊用import導入

②經過open()方法以二進制寫模式打開當前目錄下的result.html,若是沒有則自動建立該文件

③調用HTMLTestRunner模塊下的HTMLTestRunner類,stream指定測試報告文件,title用於定義測試報告的標題,description用於定義測試報告的副標題

④經過HTMLTestRunner的run方法運行測試套件中所組裝的測試用例,最後經過close()關閉測試報告文件

 

Selenium(8)集成測試報告

隨着軟件不斷迭代功能愈來愈多,對應的測試用例也會呈指數增加。一個實現幾十個功能的項目,對應的用例可能有上百個甚至更多,若是所有集成在一個文件中,那麼這個文件就很臃腫且維護麻煩。

一個很好的方法就是將這些用例按照功能類型進行拆分,分散到不一樣測試文件中,即一個項目,對應多個分支。

 

1、分拆後的實現代碼

一、testbaidu.py

from selenium import webdriver
import unittest
import time

class MyTest(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome("F:\安裝工具\python\chromedriver.exe")
        self.driver.maximize_window()
        self.driver.implicitly.wait(10)
        self.base_url = "http://www.baidu.com"

    def test_baidu(self):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_id("kw").clear()
        driver.find_element_by_id("kw").send_key("unittest")
        driver.find_element_by_id("su").click()
        time.sleep(2)
        title = assertEqual(title,"unittest_百度搜索")

    def tearDown(self):
        self.driver.quit()

 

二、testyoudao.py

from selenium import webdriver
import unittest
import time

class Mytest(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome("F:\安裝工具\python\chromedriver.exe")
        self.driver.maximize_window()
        self.driver.implicitly_wait(10)
        self.base_url = "http://www.youdao.com"
    
    def test_youdao(self):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_id("query").clear()
        driver.find_element_by_id("query").send.keys("webdriver")
        driver.find_element_by_id("qb").click()
        time.sleep(2)
        title = driver.title
        self.assertEqual(title, "webdriver - 有道搜索")

    def tearDown(self):
        self.driver.close()

 

2、建立用於執行全部用例的ALL_HTMLtest.py文件

一、ALL_HTMLtest.py

# coding=utf-8
import unittest
import time
from HTMLTestRunner import HTMLTestRunner

# 加載用例testbaidu,testyoudao
import testbaidu
import testyoudao

# 將測試用例添加到測試集中
suite = unittest.TestSuite()

suite.addTest(testbaidu.MyTest("test_baidu"))
suite.addTest(testyoudao.Mytest("test_youdao"))

if __name__ == '__main__':
    # 執行測試
    runner = unittest.TextTestRunner()
    runner.run(suite)

 

拆分帶來的好處顯而易見,能夠根據不一樣功能建立不一樣的測試文件,甚至不一樣的目錄,還能夠將不一樣的小功能劃分爲不一樣的測試類,在類下編寫測試用例,總體結構更加清晰。

但依然存在缺陷(當用例達到成百上千條時,在ALL_HTMLtest.py中addTest()添加測試用例就變得很麻煩)。。。

 

二、TestLoader類

unittest單元測試框架提供了TestLoader類,該類負責根據各類標準加載測試用例,並將它們返回給測試套件。

unittest提供了能夠共享的defaultTestLoader類,可使用其子類和方法建立實例,discover()方法就是其中之一。

discover(start_dir, pattern='test*.py', top_level_dir=None)

找到指定目錄下的全部測試模塊,並遞歸查找子目錄下的測試模塊,只有匹配到文件名才能被加載,若是啓動的不是頂層目錄,則頂層目錄必須單獨指定。

start_dir:要測試的模塊名或測試用例目錄;

pattern='test*.py':表示用例文件名的匹配原則,下面的例子中匹配文件名爲以「test」開頭的「.py」文件,星號「*」表示任意多個字符;

top_level_dir=None:測試模塊的頂層目錄,若是沒有頂層目錄,默認爲None;

# coding=utf_8
import unittest
from unittest import defaultTestLoader
# 定義測試用例的目錄爲當前目錄
test_dir = './'
discover = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py') 

if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(discover)

 

3、集成測試報告

HTMLTestRunner目前只針對單個測試文件生成測試報告,所以須要對上面的代碼進行修改,修改後內容以下:
# coding=utf_8
import unittest
import time
from unittest import defaultTestLoader
from HTMLTestRunner import HTMLTestRunner

# 定義測試用例的目錄爲當前目錄
test_dir = './report'
discover = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py') 

if __name__ == '__main__':
    now = time.strftime("%Y-%m-%d %H_%M_%S")
    filename = test_dir + '/' + now + 'result.html'
    fp = open(filename, 'wb')
    runner = HTMLTestRunner(stream=fp,title='集成測試報告demo',description= '用例執行狀況:')
    runner.run(discover)
    fp.close()

 

執行後,結果以下:

 

 

轉載: https://www.cnblogs.com/imyalost

相關文章
相關標籤/搜索