1. 程式人生 > >50.[Python]使用Selenium包做Web頁面自動化測試詳解

50.[Python]使用Selenium包做Web頁面自動化測試詳解

簡介

Selenium是ThoughtWorks公司為Web自動化測試開發的工具,除支援多種作業系統如Linux、Mac OS X、Windows外,還支援Chrome、Firefox、Safari、Opera、IE等多種瀏覽器,適合做Web應用的相容性測試及自動化測試。在Web開發的持續整合中,如果每次迭代都採用手工方式對已有的功能進行迴歸測試,需要的人力、時間成本將是非常巨大的,採用Selenium進行自動化地迴歸測試,可以讓團隊的精力集中在新功能的測試上,提升工作效率。

本文主要介紹在Python中使用Selenium包進行自動化測試的方法,您需要具備一些HTML的知識及搭建Web伺服器的方法,這樣才能在學習的過程中親手做實驗,另外完整的示例程式碼放在我的

github專案上,歡迎大家訪問。首先使用pip install selenium命令安裝Python的Selenium包。針對不同的瀏覽器及其版本使用Selenium的方法會有所不同,如下是我的版本資訊:

  • 作業系統:Mac OS Sierra
  • Python: 2.7.10
  • Selenium: 2.53.6
  • Firefox: 47.0.1
  • Safari: 10.0
  • Opera: 39.0
  • Chrome: 53

使用方法

訪問頁面

Selenium執行自動化測試的方法是開啟瀏覽器,按照指令碼規定的步驟模擬人的操作,如點選按鈕、在文字框輸入文字等,然後檢查期望結果。第一步就是要知道訪問什麼頁面,比如測試使用Firefox訪問百度:

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

# 目前支援的driver有Firefox, Chrome, IE和Remote等
driver = webdriver.Firefox(executable_path="./geckodriver")
# 直到頁面被載入完(onload事件被觸發)才將控制權返回指令碼
driver.get('https://www.baidu.com')
assert u'百度一下,你就知道' in
driver.title print u"當前URL:", driver.current_url

對於使用了大量AJAX的頁面,webdriver並不知道頁面何時真正載入完成,這時需要使用waits告訴Selenium等待時間。

Webdriver是Selenium能夠實現跨瀏覽器自動化測試的關鍵,通常簡稱wd。不同瀏覽器有不同的wd,但對外提供了統一的介面呼叫各個瀏覽器自身的自動化測試介面。上面Firefox的webdriver請在此下載

定位元素

開啟頁面後,第二件事情就是定位到我們要操作的頁面元素,定位單個頁面元素有如下方法(下面的方法,如果沒有定位到相應的元素,丟擲NoSuchElementException異常):

  • find_element_by_id:通過id屬性定位元素(返回第一個匹配的)。
  • find_element_by_name:通過name屬性定位元素(返回第一個匹配的)。
  • find_element_by_xpath:通過xpath定位元素(返回第一個匹配的)。
  • find_element_by_link_text:通過超連結文字定位超連結元素,必須是完全匹配(返回第一個匹配的)。
  • find_element_by_partial_link_text:通過超連結文字定位超連結元素,可以是部分匹配(返回第一個匹配的)。
  • find_element_by_tag_name:通過標籤名字定位元素(返回第一個匹配的)。
  • find_element_by_class_name:通過class屬性定位元素(返回第一個匹配的)。
  • find_element_by_css_selector:使用CSS選擇器語法定位元素(返回第一個匹配的)。

上面的方法,對應的批量定位方法如下(返回對應網頁元素的列表):

  • find_elements_by_name
  • find_elements_by_xpath
  • find_elements_by_link_text
  • find_elements_by_partial_link_text
  • find_elements_by_tag_name
  • find_elements_by_class_name
  • find_elements_by_css_selector

此外,webdriver還有find_elementfind_elements方法定位元素:

from selenium.webdriver.common.by import By

driver.find_element(By.XPATH, '//button[text()="Some text"]')
driver.find_elements(By.XPATH, '//button')

By物件含有如下屬性:

  • ID :元素id屬性。
  • XPATH:xpath。
  • LINK_TEXT :超連結文字。
  • PARTIAL_LINK_TEXT :部分超連結文字。
  • NAME :元素name屬性。
  • TAG_NAME :元素標籤名字。
  • CLASS_NAME :元素class屬性。
  • CSS_SELECTOR :使用CSS元素選擇器語法。

操作文字框元素

比如在百度的輸入框查詢資訊:

elem = driver.find_element_by_name('wd')

# 清空預填充內容
elem.clear()
# Keys物件表示鍵盤按鍵,如F1、ALT、ARROW_DOWN等
elem.send_keys(u'48.HTTP基本認證與摘要認證', Keys.RETURN)

assert u'Mars Loo的部落格' in driver.page_source

# quit方法關閉整個瀏覽器
driver.quit()

上傳檔案也可以採用send_keys方法,此時引數提供為檔案的路徑即可。

操作表單元素

定位到一個表單元素後,可以呼叫其submit方法提交表單:

form = ff.find_element_by_name('survey')
form.submit()

如果呼叫submit方法的元素不是表單,丟擲異常NoSuchElementException。提交表單也可以定位到提交按鈕元素後,呼叫其click方法:

submit = ff.find_element_by_id('submit')
submit.click()

操作select元素

# 採用xpath獲取第一個select元素(即使有多個也返回第一個)
element = ff.find_element_by_xpath("//select[@name='car']")
# 獲取所有選項,列印選項值並點選
all_options = element.find_elements_by_tag_name("option")
for option in all_options:
    print "Value is: %s" % option.get_attribute("value")
    option.click()

Selenium還提供了對<select>元素的抽象——Select物件:

from selenium.webdriver.support.ui import Select

select = Select(ff.find_element_by_xpath("//select[@name='car']"))
select.select_by_visible_text("infinity")
select.select_by_value("bmw")
# 按照option的索引選擇,第一個option的index為0
select.select_by_index("0")

對於允許多選以及有預選值的場景,可以做如下處理:

select = Select(ff.find_element_by_xpath("//select[@name='car']"))
# 獲取所有已選項
print select.all_selected_options
# 去選所有選項
select.deselect_all()
# 獲取所有可選項
print select.options

拖放元素

selenium包目前還不支援HTML 5的拖放,一種解決方案是通過Javascript指令碼及jQuery解決:

jquery_url = "http://upcdn.b0.upaiyun.com/libs/jquery/jquery-2.0.2.min.js"

ff = webdriver.Firefox(executable_path="./geckodriver")
ff.get('http://html5demos.com/drag')

ff.set_script_timeout(30)
with open("load_jquery.js") as f:
    load_jquery_js = f.read()
with open("drag_and_drop.js") as f:
    drag_and_drop_js = f.read()
ff.execute_async_script(load_jquery_js, jquery_url)

ff.execute_script(drag_and_drop_js +
                  "$('#one').simulateDragDrop({dropTarget:'#bin'});")

load_jquery.jsdrag_and_drop.js請在我的github專案獲取。

在視窗和frame間切換

在瀏覽器不同視窗之間切換的方法如下:

a = ff.find_element_by_tag_name("a")

# 儲存原始視窗,window_handlers是目前wd開啟的所有視窗的控制代碼列表
prev = ff.window_handles[-1]

# 點選超連結(targe="_blank")後,瀏覽器新視窗被啟用
a.click()

# 儲存新視窗
new = ff.window_handles[-1]

# 切換到原始視窗
ff.switch_to_window(prev)
print "Switch to prev success"

# 切換到新視窗
ff.switch_to_window(new)
print "Switch to new success"

因為HTML 5中不再建議使用<frameset>標籤,所以以<iframe>為例說明如何在框架間切換:

ff.switch_to_frame('frame1')
element = ff.find_element_by_name('wd')
element.clear()
element.send_keys("This is a test")

# 切換到頂級frame,然後才可以切換到其他iframe
ff.switch_to_default_content()
ff.switch_to_frame('frame2')
element = ff.find_element_by_name('email')
element.clear()
element.send_keys("Input to Sohu")

處理彈窗

Javascript的角度,彈窗分為三種:alert、confirm和prompt。使用webdriver的switch_to_alert方法可以將焦點切換到當前的彈窗上,並返回一個Alert物件。
如果是alert型別的視窗,點選取消或者確定都可以關閉該視窗:

# 切換到當前彈出框並返回Alert物件
alert = ff.switch_to_alert()
# 獲取彈出框的文字內容
print "Alert text:", alert.text
# 點選彈出框的確定按鈕
alert.accept()
# 點選彈出框的取消按鈕
# alert.dismiss()

如果是confirm型別的視窗,點選確定會給Javascript返回true,點選取消會給javascript返回false。如果是prompt型別的視窗,可以輸入一段文字後再點選取消還是確定,如果點選取消會給Javascript返回null,如果點選確定會給Javascript返回輸入的文字,因為彈出的prompt框預設會將其中可編輯的文字內容覆蓋選中(見下圖),所以Alert物件沒有clear方法:

這裡寫圖片描述

alert = ff.switch_to_alert()

# 如果是prompt型別的彈出框,直接向其中輸入內容
alert.send_keys("This is my choice")
# 然後點選prompt框的確定按鈕
alert.accept()

處理HTTP基本認證及摘要認證

HTTP基本認證和摘要認證的基本原理可以參考我的博文,這種認證彈窗不需要按照上面的方法處理,如果是Firefox瀏覽器,可以在瀏覽器中訪問about:config進入配置介面將browser.safebrowsing.malware.enabled設定為true,此時Firefox就允許我們以scheme://username:[email protected]/path?query#segment的形式訪問網頁了。設定好了以後,Selenium的指令碼可以這樣寫:

ff = webdriver.Firefox(executable_path="./geckodriver")
ff.get('http://mars:[email protected]:5000/')

歷史記錄前進及後退

通過webdriver的backforward方法,可以很方便地在歷史記錄中前進及後退:

a = ff.find_element_by_tag_name('a')
a.click()
print "Go back"
ff.back()
print "Go forward"
ff.forward()

處理cookie時,需要webdriver先訪問到合法的cookie域,新增cookie然後重新訪問即可,比如(namevalue欄位分別表示cookie的鍵和值):

 ff.get('http://localhost:5000/')
 ff.add_cookie({'name': 'username', 'value': 'marsloo'})
 ff.get('http://localhost:5000/')
 # 獲取當前域的cookies
 print ff.get_cookies()

上述程式碼的輸出可能為:

[{u'domain': u'localhost', u'name': u'username', u'value': u'marsloo', u'expiry': None, u'path': u'', u'httpOnly': False, u'secure': False}]

等待元素載入

如果請求的頁面使用了大量的AJAX,Selenium不會等待其請求完成後再將控制權交給指令碼。為了正確定位到所需的元素,需要使用Selenium的等待功能,最簡單的是這樣:

# 對於所有元素獲取,會等待3秒
ff.implicitly_wait(3)
try:
    a = ff.find_element_by_partial_link_text('g')
    a.click()
except NoSuchElementException:
    print "Page load fail or no such element"

在每一個瀏覽器會話中只需要呼叫一次implicitly_wait方法。如果相對每個元素獲取設定不同的超時時間,可以這樣做(其他更詳細的程式碼可以在我的github專案獲取):

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException


@auto_close
def func():
    try:
        a = WebDriverWait(ff, 3).until(
            EC.presence_of_element_located((By.TAG_NAME, "p")))
        a.click()
    except TimeoutException:
        print "No such element"

上述程式碼中的(By.TAG_NAME, "p")元組,在下面的解釋中以locator引數代替。expected_conditions物件還有很多方法可以使用:

  • title_is(title):標題是title(完全匹配)。
  • title_contains(title):標題包含title(部分匹配)。
  • presence_of_element_located(locator):元素在DOM樹上存在(但是不一定可見)。
  • visibility_of_element_located(locator):元素在DOM樹上存在並且肉眼可見。
  • visibility_of(element):檢查元素的肉眼可見性。
  • presence_of_all_elements_located(locator):元素們在DOM樹上存在(但是不一定可見),locator返回的是元素的列表。
  • text_to_be_present_in_element(locator, text):某個元素的文字中是否包含text
  • text_to_be_present_in_element_value(locator, text):某個元素的value屬性中是否包含text
  • frame_to_be_available_and_switch_to_it(locator):判斷某個frame是否可操作,如果可以的話切換到該frame並返回True,否則返回False
  • invisibility_of_element_located(locator):元素不存在於DOM樹或者不可見。
  • element_to_be_clickable(locator) :元素可見且是可點選狀態。
  • staleness_of(element):元素從DOM樹上移除。
  • element_to_be_selected(element):元素被選中。
  • element_located_to_be_selected(locator):元素被選中。
  • element_selection_state_to_be(element, bool):判斷元素被選中的狀體,bool引數中True表示選中,False表示未選中。
  • element_located_selection_state_to_be(locator, bool):判斷元素被選中的狀體,bool引數中True表示選中,False表示未選中。
  • alert_is_present:彈出了一個視窗。

使用其他瀏覽器

Chrome

使用Chrome進行測試,需要先下載Chrome Driver (可能需要翻牆),解壓縮後代碼如下:

driver = webdriver.Chrome(executable_path="./chromedriver")

Opera

webdriver_service = service.Service('./operadriver')
webdriver_service.start()
driver = webdriver.Remote(webdriver_service.service_url,
                          webdriver.DesiredCapabilities.OPERA)

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

Safari

Safari 10已經開始內建自動化測試的支援,Safari偏好設定->高階->在選單欄中顯示“開發”選單,然後開發->允許遠端自動化,最後下載Selenium Server的jar包,測試指令碼如下:

# -*- coding: utf-8 -*-

from selenium import webdriver
import time
import os

os.environ["SELENIUM_SERVER_JAR"] = "selenium-server-standalone-2.53.1.jar"

# 設定quiet模式,否則會列印很多log
driver = webdriver.Safari(quiet=True)
driver.get('https://www.baidu.com')
assert u'百度一下,你就知道' in driver.title
print u"當前URL:", driver.current_url
time.sleep(4)
driver.quit()

儲存螢幕截圖

使用driver.save_screenshot(filename)可以儲存瀏覽器的執行截圖(預設是覆蓋寫入)。

滾動至螢幕底部

使用ff.execute_script("window.scrollTo(0, document.body.scrollHeight);")可以滾動至螢幕底部。

如果覺得我的文章對您有幫助,歡迎關注我(CSDN:Mars Loo的部落格)或者為這篇文章點贊,謝謝!

相關推薦

50.[Python]使用SeleniumWeb頁面自動化測試

簡介 Selenium是ThoughtWorks公司為Web自動化測試開發的工具,除支援多種作業系統如Linux、Mac OS X、Windows外,還支援Chrome、Firefox、Safari、Opera、IE等多種瀏覽器,適合做Web應用

python+selenium之定位web頁面元素三:By 定位元素

用 By 定位元素 有時需要使用定位方法,在具體通過哪種定位方式(id 或 name)根據實際場景而定位,By 就可以設 置定位策略。 find_element(By.ID,"kw") find_element(By.NAME,"wd") find_element(By.CLASS_

python+selenium之定位web頁面元素二:css定位

CSS(Cascading Style Sheets)是一種語言,它被用來描述 HTML 和 XML 文件的表現。CSS 使用選擇器來為頁面元素繫結屬性。這些選擇器可以被 selenium 用作另外的定位策略。 CSS 可以比較靈活選擇控制元件的任意屬性,一般情況下定位速度要比 XPath 快,

python+selenium之定位web頁面元素:輸入、點選事件觸發

通過前端工具,我們看可以看到頁面上的元素都是由一行一行的程式碼組成。它們之間有層級的組織起 來,每個元素有不同的標籤名和屬性值。那麼在 Selenium 當中就是通過這資訊來找到不同的元素的。 webdriver 提供了八種元素定位方法: id name class n

python+request+Excel接口自動化測試(二)

h+ put res setup 時間 except name 做了 resp 今天整了下python用request寫接口測試用例,做了個粗糙的大概的執行,具體還需找時間優化。這個采用對象化,配置以及常用函數為一個類,執行測試用例為另外的一個類。測試用例的撰寫大概如下(還

【 專欄 】- Python Selenium自動化測試

Python Selenium自動化測試詳解 使用Python語言操作Selenium(webdriver)進行UI自動化測試的一些技能、API詳解、問題解決辦法以及程式碼示例、以及自動化測試框架的搭建

使用Selenium實現基於Web自動化測試

Selenium 及其實現原理 Selenium 的主要功能包括: 1)測試與瀏覽器的相容性:測試應用程式能否相容工作在不同瀏覽器和作業系統之上。 2)測試系統功能:錄製用例自動生成測試指令碼,用於迴歸功能測試或者系統用例說明。 簡而言之,Selenium 就是一款可以錄製使用者操作,幫助 Web

基於 Selenium WebDriver 的 Web 應用自動化測試(JS版)

https://www.ibm.com/developerworks/cn/web/1306_chenlei_webdriver/index.html 為什麼要使用Javascript語言進行自動化測試 相比Java或者Python學習門檻較低,環境安裝簡單,容易上手。 建立測試專案 初始化

Web自動化測試Python + Pytest+Selenium+ Saucelabs

背景介紹: 關於Web Ui 全自動化測試,我們用簡單易學的python語言來編寫測試用例;採用Python的單元測試框架Pytest去控制和執行測試用例;採用開源的Web Ui 測試框架Seleniumt提供的API操作介面元素;使用Saucelabs平臺提

在Linux下實現Python+selenium+chrome的web自動化測試

宣告:ubuntu版本是在16.04下進行的 1、首先需要先安裝Chrome sudo apt-get install libxss1 libappindicator1 libindicator7 wget https://dl.google.com/linux/direc

一隻自動化測試小白的學習記錄——Python+Selenium基於Web自動化測試(例項練習)

也有兩天沒更新了 哎~這學期的課還挺多的 都是利用課餘的一些時間來學習自動化測試(抱怨臉(╯▔皿▔)╯)這兩天我在練習的是一個相對完整的Web自動化測試,也是對前些日子學習內容的整合,具體來說如下:1.開啟瀏覽器2.輸入網址開啟網頁(我是以鏈家網為練習的,因為想到明年畢業後要

使用postman+newman+python接口自動化測試

控制 oba ret 分享圖片 調試接口 lob sta package cli postman是一款API調試工具,可用於測試接口,相類似的工具還有jmeter、soupUI。通過postman+newman+python可以批量運行調試接口,達到自動化測試的效果。 1、

Java+Selenium Web UI自動化測試的一些小總結

The 隱藏 ase 默認 get over rip cli 不可 - Chrome 關於Chrome的配置網上信息很多,直說一點,當選擇在linux環境跑用例的時候,我們會優先選擇headless run,默認情況下headless run的瀏覽器大小好像只有900*76

Python接口自動化測試框架

success pre gin HERE settings 不同 請求頭 toc encode 框架結構如下: Test_Api_Project||---base.py|---base_api|   |---register_api.py |   |---send_sms_

Python selenium根據class定位頁面元素

帶來 調整 空格 classname 百度 即使 不可 body ()   在日常的網頁源碼中,我們基於元素的id去定位是最萬無一失的,id在單個頁面中是不會重復的。但是實際工作中,很多前端開發人員並未給每個元素都編寫id屬性。通常一段html代碼如下: 1 <di

Python&Selenium&Unittest&BeautifuReport 自動化測試並生成HTML自動化測試報告

一、摘要 本篇博文將介紹如何藉助BeautifulReport和HTML模版,生成HTML測試報告的BeautifulReport 原始碼Clone地址為 https://github.com/TesterlifeRaymond/BeautifulReport,其中 BeautifulReport.py和

3.7RF匯入seleniumUI的自動化

安裝Selenium2Library庫 win+R鍵-->cmd-->pip install robotframework-Selenium2Library Selenium2Library配置瀏覽器的過程 : 1、拿到chromedriver.exe驅

selenium高效應對Web頁面元素重新整理

當我們在頁面上進行selenium.type()或者selenium.click()操作的時候,往往需要需要等待一個元素的出現,對於一般的網頁,當我們進入一個新頁面的時候,往往會使用selenium.waitForPageToLoad(WAITTIME);對彈出

web自動化測試外掛Selenium-IDE外掛的安裝使用

 Selenium是ThroughtWorks公司一個強大的開源Web功能測試工具系列,本系列現在主要包括以下4款: q1.SeleniumCore:支援DHTML的測試案例(效果類似資料驅

Web UI自動化測試中處理頁面元素過期問題

Stale Element Reference Exception You have probably been directed to this page because you've seen a StaleElementReferenceException in your tests. Comm