手把手教你學(xué)會(huì) Selenium 2 自動(dòng)化測(cè)試實(shí)例

Selenium 2 自動(dòng)化測(cè)試實(shí)例 更新中...

目錄:

[TOC]

[1. 自動(dòng)化測(cè)試基礎(chǔ)]
[2. 測(cè)試環(huán)境搭建]
[3. Python基礎(chǔ)]
[4. WebDriver API]
[5. 自動(dòng)化測(cè)試模型]
[6. selenium IDE]
[7. unittest 單元測(cè)試框架]
[8. 自動(dòng)化測(cè)試高級(jí)應(yīng)用]
[9. Selenium Grid2]
[10. Python多線程]
[11. 自動(dòng)化測(cè)試實(shí)戰(zhàn)]
[12. BDD框架指Lettuce入門]
[13. GitHub托管項(xiàng)目]
[14. 持續(xù)繼承Jenkins入門]

1. 自動(dòng)化測(cè)試基礎(chǔ)

1.1 軟件測(cè)試分類

1. 根據(jù)項(xiàng)目流程階段劃分測(cè)試

  1. 單元測(cè)試: 單個(gè)子程序測(cè)試
  2. 集成測(cè)試: 模塊由多個(gè)單元集成成子系統(tǒng)再測(cè)試
  3. 系統(tǒng)測(cè)試: 針對(duì)整個(gè)產(chǎn)品系統(tǒng)的測(cè)試
  4. 驗(yàn)收測(cè)試: 部署軟件之前的最后一個(gè)測(cè)試階段

2. 白盒測(cè)試、黑盒測(cè)試、灰盒測(cè)試

  1. 黑盒:只關(guān)心軟件的輸入數(shù)據(jù)和輸出結(jié)果
  2. 白盒:產(chǎn)品內(nèi)部動(dòng)作和代碼邏輯是否按照設(shè)計(jì)規(guī)格進(jìn)行
  3. 灰盒:介于黑盒和白盒之間,既關(guān)注輸入輸出的正確性,同時(shí)也關(guān)注內(nèi)部的表現(xiàn)

3. 功能測(cè)試和性能測(cè)試

  1. 功能測(cè)試:邏輯功能測(cè)試、界面測(cè)試、易用性測(cè)試、安裝測(cè)試、兼容性測(cè)試等等
  2. 性能測(cè)試:
    • 時(shí)間性能:具體響應(yīng)時(shí)間
    • 空間性能:消耗占用系統(tǒng)資源,例如硬件資源,CPU、內(nèi)存、網(wǎng)絡(luò)帶寬消耗等

4. 手工測(cè)試與自動(dòng)化測(cè)試

  1. 手工測(cè)試:由測(cè)試人員一個(gè)一個(gè)地去執(zhí)行測(cè)試用例
  2. 自動(dòng)化測(cè)試:把人為驅(qū)動(dòng)的測(cè)試行為轉(zhuǎn)化為機(jī)器執(zhí)行的一種過(guò)程
    • 功能自動(dòng)化測(cè)試:測(cè)試工具(或者框架)錄制/編寫測(cè)試腳本,對(duì)軟件的功能進(jìn)行測(cè)試,并驗(yàn)證測(cè)試結(jié)果是否正確,從而替代部分手工測(cè)試工作,達(dá)到節(jié)約時(shí)間成本、人力成本
    • 性能自動(dòng)化測(cè)試:通過(guò)性能工具來(lái)模擬成千上萬(wàn)的虛擬用戶向系統(tǒng)發(fā)送請(qǐng)求,具而驗(yàn)證系統(tǒng)的處理能力

5. 冒煙測(cè)試、回歸測(cè)試、隨機(jī)測(cè)試、探索型測(cè)試和安全測(cè)試

  1. 冒煙測(cè)試:先驗(yàn)證具體的基本功能是否實(shí)現(xiàn),是否具備進(jìn)行大規(guī)模系統(tǒng)測(cè)試
  2. 回歸測(cè)試:修改之后的舊代碼,從新測(cè)試,檢測(cè)有沒(méi)有引進(jìn)新的錯(cuò)誤或者導(dǎo)致其他代碼產(chǎn)生錯(cuò)誤
  3. 隨機(jī)測(cè)試:輸入數(shù)據(jù)是隨機(jī)生成的,其目的是模擬用戶的真實(shí)操作,并發(fā)現(xiàn)一些邊緣型的錯(cuò)誤
  4. 探索性測(cè)試:一種測(cè)試思維方式,強(qiáng)調(diào)在碰到問(wèn)題時(shí)及時(shí)改變測(cè)試策略

1.2 分層的自動(dòng)化測(cè)試

測(cè)試金字塔的概念由敏捷大師 Mike Cohn 在他的 Succeeding with agile 一書中首次提出。
基本觀念是:我們應(yīng)該有更多的低級(jí)別的單元測(cè)試,而不僅僅是通過(guò)用戶界面運(yùn)行的端到端的測(cè)試。

所謂傳統(tǒng)的自動(dòng)化測(cè)試我們可以理解為基于產(chǎn)品的UI層的自動(dòng)化測(cè)試,它是將黑盒功能測(cè)試轉(zhuǎn)化為由程序或者工具執(zhí)行的一種自動(dòng)化測(cè)試。
UI自動(dòng)化測(cè)試成本維護(hù)高昂,UI易變。
分層自動(dòng)化測(cè)試倡導(dǎo)的是由黑盒(UI)單層到黑白盒多層的自動(dòng)化測(cè)試體系,從全面的黑盒自動(dòng)化測(cè)試到對(duì)系統(tǒng)的不同曾次進(jìn)行自動(dòng)化測(cè)試。

  1. 單元自動(dòng)化測(cè)試
    • 是指針對(duì)軟件的最小可測(cè)試單元進(jìn)行檢查和驗(yàn)證。對(duì)于單元測(cè)試中的單元的含義,一般來(lái)說(shuō)c語(yǔ)言是指一個(gè)函數(shù),Java是指一個(gè)類,圖形化軟件是一個(gè)窗口或者菜單,需要用到測(cè)試框架。
      • Java:Junit、TestNG
      • C#:NUnit
      • python:unittest、pytest
    • Code Review 代碼審查
      • Java:Eclipse的ReviewClipse和Jupiter
      • python:Review Board
  2. 接口自動(dòng)化測(cè)試
    • 模塊接口測(cè)試
      • 測(cè)試模塊之間的調(diào)用與返回,強(qiáng)調(diào)一個(gè)類方法或者函數(shù)的調(diào)用,并對(duì)返回結(jié)果的驗(yàn)證,同單元自動(dòng)化測(cè)試
    • Web接口測(cè)試
      • 服務(wù)器接口測(cè)試:是指測(cè)試瀏覽器與服務(wù)器的接口,通過(guò)HTTP協(xié)議實(shí)現(xiàn)前后端的數(shù)據(jù)傳遞測(cè)試
      • 外部接口測(cè)試:指調(diào)用的接口由第三方系統(tǒng)提供,典型例子就是第三方登錄,用戶登錄信息的驗(yàn)證由第三方完成,并返回給當(dāng)前系統(tǒng)是否驗(yàn)證通過(guò)
    • 當(dāng)然,接口測(cè)試也有類庫(kù)或者工具,例如測(cè)試HTTP的有HttpUnit、Postman等
  3. UI自動(dòng)化測(cè)試
    • UI測(cè)試工具:UFT、Watir、Robot Framework、Selenium
    • 前端:QUnit就是針對(duì)JavaScript的單元測(cè)試工具

《Google測(cè)試之道》 一書中提到,測(cè)試類型分為大、中、小測(cè)試,采用比例1:2:7,大體對(duì)應(yīng)UI層、Service、Unit

UI層 Service Unit
10% 20% 70%

1.3 什么項(xiàng)目適合做自動(dòng)化測(cè)試

  1. 任務(wù)測(cè)試明確,不會(huì)頻繁變動(dòng)
  2. 每日構(gòu)建后的測(cè)試驗(yàn)證
  3. 比較頻繁的回歸測(cè)試
  4. 軟件系統(tǒng)的界面穩(wěn)定,變動(dòng)少
  5. 需要在多平臺(tái)上運(yùn)行的測(cè)試案例,組合便利型的測(cè)試,大量的重復(fù)任務(wù)
  6. 軟件維護(hù)周期長(zhǎng)
  7. 項(xiàng)目進(jìn)度壓力不算太大
  8. 被測(cè)軟件系統(tǒng)開(kāi)發(fā)較為規(guī)范,能夠保證系統(tǒng)的可測(cè)試性
  9. 具備大量的自動(dòng)化測(cè)試平臺(tái)
  10. 測(cè)試人員較強(qiáng)的變成能力

1.4 市面上常見(jiàn)的自動(dòng)化測(cè)試工具

  1. UFT:HP開(kāi)發(fā),QTP與ST合并而來(lái)。企業(yè)級(jí)自測(cè)工具,提供強(qiáng)大醫(yī)用的錄制回放功能,兼容對(duì)象識(shí)別模式與圖像識(shí)別模式兩種識(shí)別方式,支持B/S C/S兩種架構(gòu)
  2. Robot Framework:基于Python編寫的自動(dòng)化測(cè)試框架,可擴(kuò)展,支持關(guān)鍵字,同時(shí)可以測(cè)試多種客戶端或者接口,可以分布式測(cè)試
  3. Watir:基于Web模式的自動(dòng)化功能測(cè)試工具。Wair是一個(gè)Ruby語(yǔ)言庫(kù)
  4. Selenium:是一個(gè)Web應(yīng)用程序測(cè)試工具,支持多平臺(tái)、多瀏覽器、多語(yǔ)言,應(yīng)用廣泛

1.5 Selenium工具介紹

基于Web應(yīng)用程序的自動(dòng)化測(cè)試,但不局限于此,它還支持所有基于web的管理任務(wù)自動(dòng)化

特點(diǎn):

  • 開(kāi)源免費(fèi)
  • 多瀏覽器支持:Firefox、Chrome、IE、Opera、Edge
  • 多平臺(tái)支持:Linux、windows、Mac
  • 多語(yǔ)言:Java、Python、Ruby、JavaScript、C#、C++
  • 對(duì)web頁(yè)面的良好的支持
  • 簡(jiǎn)單API、靈活(用開(kāi)發(fā)語(yǔ)言驅(qū)動(dòng))
  • 支持分布式測(cè)試用例

Selenium:

  • Selenium IDE:嵌入火狐Firefox的一個(gè)插件,實(shí)現(xiàn)簡(jiǎn)單的瀏覽器操作錄制、回放,快速創(chuàng)建bug重現(xiàn)腳本,通過(guò)IDE將重現(xiàn)的步驟記錄下來(lái),重現(xiàn)BUG
  • Selenium Grid:自動(dòng)化測(cè)試輔助工具,Grid通過(guò)利用現(xiàn)有的計(jì)算機(jī)基礎(chǔ)設(shè)施,能加快Web-App的功能測(cè)試,利用Grid可以很方便的實(shí)現(xiàn)多臺(tái)機(jī)器上和異構(gòu)環(huán)境中測(cè)試用例
  • Selenium RC:家族的核心部分,通過(guò)Selenium RC的服務(wù)器作為代理服務(wù)器去訪問(wèn)應(yīng)用。Selenium Libraries庫(kù)主要用于編寫測(cè)試腳本,用來(lái)控制Selenium Server庫(kù)。Selenium Server負(fù)責(zé)控制瀏覽器行為。
    • client
    • Server
      • Launcher:用于啟動(dòng)瀏覽器,把Selenium Core加載到瀏覽器頁(yè)面當(dāng)中,并把瀏覽器的代理設(shè)置為Selenium Server的Http Proxy
      • Http Proxy:代理服務(wù)器(Proxy)是網(wǎng)絡(luò)信息的中轉(zhuǎn)站
      • Core:是被Selenium Server嵌入到到瀏覽器的頁(yè)面中,其實(shí) Selenium Core就是一堆JavaScript函數(shù)的集合,通過(guò)這些JS函數(shù),可以實(shí)現(xiàn)程序?qū)g覽器的操作

Selenium 2.0 = Selenium 1.0 + WebDriver
WebDriver是Selenium RC的替代品,為了保持向下兼容,并沒(méi)有完全拋棄 Selenium Core,新的項(xiàng)目可以直接使用WebDriver

  • Selenium RC:是在瀏覽器中運(yùn)行JS腳本,使用瀏覽器內(nèi)置的JS的編譯器來(lái)翻譯和執(zhí)行selenese(selenese是Selenium命令合集)
  • WebDriver:是通過(guò)原生瀏覽器支持或者瀏覽器擴(kuò)展來(lái)直接控制瀏覽器。WebDriver針對(duì)各個(gè)瀏覽器而開(kāi)發(fā),取代了嵌入到被測(cè)Web應(yīng)用中的JavaScript,與瀏覽器緊密集成,因此支持創(chuàng)建更高級(jí)的測(cè)試,便面的JavaScript安全模型導(dǎo)致的限制,還利用操作系統(tǒng)級(jí)別的調(diào)用,模擬用戶輸入。可以繞過(guò)JavaScript沙箱

1.6 前端技術(shù)介紹

  1. HTML
  2. JavaScript
  3. XML

1.7 前端工具介紹

  1. FireBug
  2. FirePath:快速檢查和生成XPath1.0表達(dá)式
  3. Chrome、IE

1.8 開(kāi)發(fā)語(yǔ)言選擇

本文選擇的是Python

2. 測(cè)試環(huán)境搭建

2.1 Windows下的環(huán)境搭建

2.1.1 安裝Python

2.1.2 安裝setuptools與pip

2.1.3 安裝Selenium

2.1.4 ActivePython

  • Python專用編程和調(diào)試工具,包含Python內(nèi)核,同時(shí)可以訪問(wèn)Windows API的所有服務(wù)
  • 集成PIP,可以用PIP安裝Selenium庫(kù)

2.2 Ubuntu下環(huán)境搭建

2.3 使用IDLE編寫Python

2.4 編寫第一個(gè)自動(dòng)化腳本

在執(zhí)行程序的時(shí)候,如果遇到錯(cuò)誤代碼是如下樣子:

selenium.common.exceptions.WebDriverException: Message: 'geckodriver' executable needs to be in PATH.

則需要下載 geckodriver驅(qū)動(dòng)文件,放在/usr/local/bin目錄里。
下載網(wǎng)址是:https://github.com/mozilla/geckodriver/releases/
如果是Linux系統(tǒng),下載文件名是:geckodriver-v0.16.1-linux64.tar.gz (最新版本即可)

# coding:utf-8
from selenium import webdriver
from time import sleep

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

driver.find_element_by_id("kw").send_keys("Selenium2")
driver.find_element_by_id("su").click()

sleep(5)
driver.quit()

2.5 安裝瀏覽器驅(qū)動(dòng)

地址:Selenium - Web Browser Automation

如果打不開(kāi),百度搜索相應(yīng)的驅(qū)動(dòng)。安裝位置,Windows安裝在path環(huán)境變量下,Linux安裝在/usr/local/bin
FireFoxdriver地址
Chromedriver地址
IEdriver地址 需要對(duì)應(yīng)你的Selenium版本 windows下 IEDriver相關(guān)設(shè)置
HTMLTestRunner.py地址

sudo apt-get install xvfb
sudo apt-get install unzip

wget -N http://chromedriver.storage.googleapis.com/2.26/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
chmod +x chromedriver

sudo mv -f chromedriver /usr/local/share/chromedriver
sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver
sudo ln -s /usr/local/share/chromedriver /usr/bin/chromedriver

FireFox驅(qū)動(dòng)地址

selenium官方加上第三方宣布支持的驅(qū)動(dòng)有很多種;除了PC端的瀏覽器之外,還支持iphone、Android的driver;大概記錄一下selenium支持的各種driver的用途與說(shuō)明。
selenium可支持的PC瀏覽器驅(qū)動(dòng)包括:
FF driver【包含在各自語(yǔ)言的客戶端里】
safari driver【包含在selenium server中】
ie driver
chrome driver 【第三方】
opera driver【第三方】

selenium可支持的偽瀏覽器驅(qū)動(dòng):
PhantomJS Driver【第三方】
HtmlUnit Driver【包含在selenium server中】

selenium可支持的移動(dòng)端驅(qū)動(dòng):
Windows Phone driver 【第三方】
Selendroid -Selenium for android【第三方】
ios-driver 【第三方】
Appium  支持iphone、ipad、android、FirefoxOS【第三方】
上述的所有驅(qū)動(dòng)不僅可以直接通過(guò)各自語(yǔ)言客戶端來(lái)調(diào)用,還是注冊(cè)到selenium grid中進(jìn)行分布式的遠(yuǎn)程調(diào)用。

因?yàn)橐苿?dòng)端的driver都沒(méi)有嘗試過(guò),所以就不做說(shuō)明。PC端的driver都是基于瀏覽器的,主要分為2種類型:
一種是真實(shí)的瀏覽器driver
比如:safari、ff都是以插件形式驅(qū)動(dòng)瀏覽器本身的;ie、chrome都是通過(guò)二進(jìn)制文件來(lái)驅(qū)動(dòng)瀏覽器本身的;
這些driver都是直接啟動(dòng)并通過(guò)調(diào)用瀏覽器的底層接口來(lái)驅(qū)動(dòng)瀏覽器的,因此具有最真實(shí)的用戶場(chǎng)景模擬,主要用于進(jìn)行web的兼容性測(cè)試使用。

一種是偽瀏覽器driver
selenium支持的偽瀏覽器包括htmlunit、PhantomJS;他們都不是真正的在瀏覽器、都沒(méi)有GUI,而是具有支持html、js等解析能力的類瀏覽器程序;這些程序不會(huì)渲染出網(wǎng)頁(yè)的顯示內(nèi)容,但是支持頁(yè)面元素的查找、JS的執(zhí)行等;由于不進(jìn)行css及GUI渲染,所以運(yùn)行效率上會(huì)比真實(shí)瀏覽器要快很多,主要用在功能性測(cè)試上面。
htmlunit是Java實(shí)現(xiàn)的類瀏覽器程序,包含在selenium server中,無(wú)需驅(qū)動(dòng),直接實(shí)例化即可;其js的解析引擎是Rhino
PhantomJS是第三方的一個(gè)獨(dú)立類瀏覽器應(yīng)用,可以支持html、js、css等執(zhí)行;其驅(qū)動(dòng)是Ghost driver在1.9.3版本之后已經(jīng)打包進(jìn)了主程序中,因此只要下載一個(gè)主程序即可;其js的解析引擎是chrome 的V8。

driver類型    優(yōu)點(diǎn)  缺點(diǎn)  應(yīng)用
真實(shí)瀏覽器driver 真實(shí)模擬用戶行為    效率、穩(wěn)定性低 兼容性測(cè)試
HtmlUnit    速度快 js引擎不是主流的瀏覽器支持的 包含少量js的頁(yè)面測(cè)試
PhantomJS   速度中等、模擬行為接近真實(shí)   不能模擬不同/特定瀏覽器的行為 非GUI的功能性測(cè)試
PS:除上述的幾種真實(shí)瀏覽器driver中,也可以通過(guò)不同的手段來(lái)取消瀏覽器的css解析、界面渲染等目的;這樣既可以保證瀏覽器的真實(shí)兼容性、也可以提高執(zhí)行效率問(wèn)題;使用的手段有:autoit、pyvirtualdisplay、瀏覽器設(shè)置等。

2.6 不同語(yǔ)言使用WebDriver

  • 導(dǎo)入selenium(WebDriver)相關(guān)模塊
  • 調(diào)用瀏覽器驅(qū)動(dòng),獲取瀏覽器句柄,并啟動(dòng)
  • 通過(guò)句柄訪問(wèn)地址百度
  • 通過(guò)句柄操作頁(yè)面元素(百度輸入框和按鈕)
  • 通過(guò)句柄關(guān)閉瀏覽器

3. Python基礎(chǔ)

3.1 Python哲學(xué)

3.2 輸入輸出

3.3 分支與循環(huán)

3.4 數(shù)組與字典

3.5 函數(shù)、類和方法

3.6 模組、類庫(kù)、模塊

當(dāng)多個(gè)模塊之間存在引用,模塊內(nèi)之間文件里的類存在繼承和引用關(guān)系
需要在模塊內(nèi)創(chuàng)建一個(gè)空的init.py文件
當(dāng)一個(gè)模塊調(diào)用另一個(gè)模塊的時(shí)候
用:

import sys  
sys.path.append("./model")  # (model就是相應(yīng)的被引用模塊)  
from model import new_count

4. WebDriver API

4.1 從定位元素開(kāi)始

WebDriver在Python中一個(gè)有8種方法找到頁(yè)面元素:

標(biāo)簽 定位元素
id name
class name tag name
link text partial link text
xpath css selector
find_element_by_id() find_element_by_name()
find_element_by_class_name() find_element_by_tag_name()
find_element_by_link_text() find_element_by_partial_link_text() 通過(guò)部分文字定位
find_element_by_xpath() find_element_by_css_selector()

XPath定位:
絕對(duì)路徑定位
find_element_by_xpath("/html/body/div/div[2]/div/div/from/span/input")

利用元素屬性定位:
find_element_by_xpath("http://input[@id='kw']")
find_element_by_xpath("http://input[@name='wd']")
find_element_by_xpath("http://input[@class='s_ipt']")
find_element_by_xpath("http://*[@class='s_ipt']")
find_element_by_xpath("http://input[@maxlength='100']")
find_element_by_xpath("http://input[@autocomplete='off']")
find_element_by_xpath("http://input[@type='submit']")

層級(jí)與屬性結(jié)合:
find_element_by_xpath("http://span[@class='bg_s_ipt_wr']/input")
find_element_by_xpath("http://form[@id='form']/span/input")

使用邏輯運(yùn)算符:
find_element_by_xpath("http://input[@id='kw' and @class='su']/span/input")

css定位
通過(guò)class屬性定位:
find_element_by_css_selector(".s_ipt")
find_element_by_css_selector(".bg s_btn")

通過(guò)id屬性定位:
find_element_by_css_selector("#kw")
find_element_by_css_selector("#su")

通過(guò)標(biāo)簽名定位:
find_element_by_css_selector("input")
find_element_by_css_selector("span>input")

通過(guò)屬性定位:
find_element_by_css_selector("[autocomplete=off]")
find_element_by_css_selector("[name='kw']")
find_element_by_css_selector("[type='submit']")

組合定位:
find_element_by_css_selector("form.fm>span>input.s_ipt")
find_element_by_css_selector("form.fm>span>input#kw")

用by定位元素
略過(guò)。。

4.2 控制瀏覽器

4.3 元素控制

命令 效果
driver.set_window_size(480,800) 控制瀏覽器寬400高800
driver.get(url) 獲取url地址頁(yè)面
driver.forward() 前進(jìn)
driver.back() 后退
driver.quit() 退出
driver.refresh() 刷新頁(yè)面
driver.find_element_by_css_selector("#id").clear() 清除文本
driver.find_element_by_css_selector("#id").send_keys("abc") 模擬按鍵輸入
driver.find_element_by_css_selector("#id").click() 單擊元素
driver.find_element_by_css_selector("#id").submit() 提交
size = driver.find_element_by_css_selector("#id").size 輸入框的尺寸
driver.find_element_by_css_selector("#id").text 文本
driver.find_element_by_css_selector("#id").get_attribute() 獲取id、name、type其他任意屬性
driver.find_element_by_css_selector("#id").is_displayed() 返回元素結(jié)果是否可見(jiàn)

4.4 鼠標(biāo)事件

命令 效果
perform() 執(zhí)行所有ActionChains中儲(chǔ)存的行為
context_click() 右擊
double_click() 雙擊
drag_and_drop() 拖動(dòng)
move_to_element() 鼠標(biāo)懸停
# coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()
driver.get("https://www.baidu.com/")
# 定位右擊的元素
right_click = driver.find_element_by_id("su")
# 執(zhí)行右擊操作
ActionChains(driver).context_click(right_click).perform()

# 將瀏覽器句柄driver作為參數(shù),傳入ActionChains行動(dòng)鏈
# context_click() 鼠標(biāo)右擊操作,需要傳入元素定位
# perform() 可以理解為對(duì)所有行動(dòng)操作列表的提交
# ActionChains(driver).move_to_element(above).perferm() 鼠標(biāo)懸停
# ActionChains(driver).double_click(double_click).perferm() 鼠標(biāo)雙擊
# element, target = driver.find_element_by_id("xx"), driver.find_element_by_id("xx")
# ActionChains(driver).drag_and_drop(element, target).perferm() 鼠標(biāo)拖放

4.5 鍵盤事件

# coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep

driver = webdriver.Firefox()
driver.get("https://www.baidu.com/")

driver.find_element_by_id("kw").send_keys("seleniumm")
# driver.find_element_by_id("su").click()

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" ")  # 添加空格

driver.find_element_by_id("kw").send_keys(u"教程")  # 添加文字

driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'a')  # 輸入框全選

driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'x')  # 輸入框剪切

driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'v')  # 輸入框復(fù)制

driver.find_element_by_id("kw").send_keys(Keys.ENTER)  # 回車代替單擊

sleep(5)

driver.quit()
操作 效果
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') 復(fù)制
send_keys(Keys.CONTROL, 'v') 粘貼
send_keys(Keys.CONTROL, 'x') 剪切
send_keys(Keys.F1) 鍵盤F1
send_keys(Keys.F12) 鍵盤F12

常用鍵盤操作:

操作 效果
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') 復(fù)制
send_keys(Keys.CONTROL, 'v') 粘貼
send_keys(Keys.CONTROL, 'x') 剪切
send_keys(Keys.F1) 鍵盤F1
send_keys(Keys.F12) 鍵盤F12

4.6 獲取驗(yàn)證信息

title = driver.title
now_url = driver.current_url
user = driver.find_element_by_id('spanUid').text

4.7 設(shè)置元素等待

WebDirverWait(driver, 5, 0.5)
WebDirverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)

  • driver:瀏覽器驅(qū)動(dòng)
  • timeout:超時(shí)時(shí)長(zhǎng)
  • poll_frequency:間隔時(shí)長(zhǎng)
  • ignored_exceptions:超時(shí)后的異常信息
# 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
from selenium.webdriver.common.keys import Keys
import time
driver = webdriver.Firefox()
driver.get("https://www.baidu.com")

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

driver.find_element_by_id("kw").send_keys('selenium')
driver.find_element_by_id("kw").send_keys(Keys.ENTER)
# element.send_keys('selenium')
time.sleep(5)
driver.quit()

# until(method, message='') 調(diào)用該方法提供的驅(qū)動(dòng)程序作為一個(gè)參數(shù),直到返回為True

第二種方法:
隱式等待 implicitly_wait()

# coding:utf-8

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from time import ctime

driver = webdriver.Firefox()
driver.implicitly_wait(10)  # 休眠時(shí)間
driver.get("http://www.baidu.com")
try:
    print(ctime())
    driver.find_element_by_id("kw22").send_keys('selenium')
except NoSuchElementException as e:
    print(e)
finally:
    print(ctime())
    driver.quit()

第三種方法:
sleep
from time import sleep
sleep(10)

4.8 復(fù)選

# coding:utf-8

from selenium import webdriver
import os, time

driver = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('checkbox.html')  # abspath()返回絕對(duì)路徑
driver.get(file_path)

# inputs = driver.find_element_by_tag_name('input')
# 
# for i in inputs:
#     if i.get_attribute('type') == 'checkbox':
#         i.click()
#         time.sleep(1)

# checkboxs = driver.find_elements_by_xpath("http://input[@type='checkbox']")
checkboxs = driver.find_elements_by_css_selector("input[type=checkbox]")

for checkbox in checkboxs:
    checkbox.click()
    time.sleep(1)

driver.find_elements_by_css_selector('input[type=checkbox]').pop().click()  # 去掉最后一個(gè)

# pop(0) 第一個(gè)
# pop(-1) 最后一個(gè)
# pop(1) 第二個(gè)

driver.quit()

4.9 多表單切換

driver.switch_to.frame("if")  # 切換到id = if的frame框架,frame()可以去id或者name屬性 或者
xf = driver.find_element_by_xpath("http://*[@class='if']")
driver.switch_to.frame(xf)
switch_to.default_content()  # 跳到最外層表單

4.10 多窗口切換

# coding:utf-8

from selenium import webdriver
import time

driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")

# 獲得百度搜索窗口句柄
sreach_windows = driver.current_window_handle
# a.lb:nth-child(7)
# html body div#wrapper div#head div.head_wrapper div#u1 a.lb

# a_links = driver.find_element_by_css_selector("a.lb:nth-child(7)")
# print a_links.text

# links = driver.find_elements_by_link_text('登錄')
# print links

driver.find_elements_by_link_text('登錄').pop().click()
driver.find_element_by_link_text("立即注冊(cè)").click()

# driver.find_element_by_link_text('登錄').click()
# driver.find_element_by_link_text("立即注冊(cè)").click()

# 獲得當(dāng)前所有打開(kāi)的窗口的句柄
all_handles = driver.window_handles

# 進(jìn)入注冊(cè)窗口
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')
        time.sleep(2)

# 回到搜索窗口
for handle in all_handles:
    if handle == sreach_windows:
        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()
        print driver.current_window_handle
        time.sleep(5)

driver.quit()

4.11 警告框處理

命令 效果
text 返回alert/confirm/prompt中的文字
accpet() 接受現(xiàn)有警告框
dismiss() 解散現(xiàn)有警告框
send_keys(keysToSend) 發(fā)送文本至警告框 keysToSend:將文本發(fā)送至警告框
switch_to_alert() 方法接受彈出來(lái)的窗口

switch_to_alert()方法 定位到 alert/confirm/prompt
text/accept/dismiss/send_keys等方法進(jìn)行操作

命令 效果
text 返回alert/confirm/prompt中的文字
accpet() 接受現(xiàn)有警告框
dismiss() 解散現(xiàn)有警告框
send_keys(keysToSend) 發(fā)送文本至警告框 keysToSend:將文本發(fā)送至警告框
switch_to_alert() 方法接受彈出來(lái)的窗口
# coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time

driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")

# 鼠標(biāo)懸停至“設(shè)置”鏈接
# link = driver.find_element_by_link_text('設(shè)置')
link = driver.find_elements_by_link_text('設(shè)置').pop()
ActionChains(driver).move_to_element(link).perform()

# 打開(kāi)搜索設(shè)置
# time.sleep(5)
# print driver.find_element_by_link_text('搜索設(shè)置')
driver.find_element_by_link_text('搜索設(shè)置').click()

js = "var q=document.getElementsByClassName(\"bdlayer pfpanel\");q.style=\"display: block; top: 0px; opacity: 1;\""
driver.execute_script(js)
time.sleep(3)

# res = driver.find_element_by_css_selector(".bdlayer.pfpanel")
# print res
# print res.is_displayed()

# 設(shè)置
driver.find_element_by_css_selector("#sh_1").click()

# 保存設(shè)置
# driver.find_element_by_class_name("prefpanelgo").click()
driver.find_element_by_css_selector(".prefpanelgo").click()
# driver.find_element_by_link_text('恢復(fù)默認(rèn)').click()
time.sleep(2)

# 接受警告框
driver.switch_to_alert().accept()

driver.quit()

4.12

4.12.1 send_keys實(shí)現(xiàn)上傳

找到對(duì)應(yīng)的input標(biāo)簽,直接send_keys(文件),傳入對(duì)應(yīng)文件

# coding:utf-8
from selenium import webdriver
import os

driver = webdriver.Firefox()
driver.implicitly_wait(5)
file_path = 'file:///' + os.path.abspath('upfile.html')
driver.get(file_path)

# 定位上傳的input,添加本地文件
driver.find_element_by_name('file').send_keys('D:\\upload_file.txt')

driver.quit()

4.12.2 AutoIt實(shí)現(xiàn)上傳

官方下載地址:http://www.aotuitscript.com/site/
windows GUI(圖形用戶界面)自動(dòng)化測(cè)試

功能 作用
AutoIt Windows Info 用于識(shí)別Windows控件信息
Compile Script to.exe 用于將AutoIt生成exe執(zhí)行文件
Run Script 用于執(zhí)行AutoIt腳本
SciTE Script Editor 用于編寫AutoIt腳本

4.13 下載文件

WebDriver允許我們?cè)O(shè)置默認(rèn)的文件下載路徑,也就是說(shuō),文件會(huì)自動(dòng)下載并且存放到設(shè)置的目錄中。
HTTP Content-type 常用對(duì)照表:http://tool.oschina.net/commons
curl -I 可以查看Content-type的值

# coding:utf-8

from selenium import webdriver
import os

fp = webdriver.FirefoxProfile()

fp.set_preference("browser.download.folderList", 2)  # 設(shè)置成0代表保存在默認(rèn)的瀏覽器下載目錄,設(shè)置2代表保存在指定的目錄
fp.set_preference("browser.download.manager.showWhenStarting", False)  # 是否顯示開(kāi)始 True為顯示,F(xiàn)alse為不顯示
fp.set_preference("browser.download.dir", '/home/wy/')
# fp.set_preference("browser.download.dir", os.getcwd())  # 設(shè)置下載目錄 os.getcwd()當(dāng)前的目錄
fp.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream")  # 下載文件的類型 指定要下載頁(yè)面的Content-type值,‘a(chǎn)pplication/octet-stream’為文件類型

driver = webdriver.Firefox(firefox_profile=fp)
driver.get("https://pypi.python.org/pypi/selenium#downloads")
# driver.find_element_by_css_selector(".button.green").click()
# driver.find_element_by_partial_link_text("selenium-2").click()

driver.find_element_by_css_selector(".even>td>span>a").click()

driver.quit()

Chrome瀏覽器類似,設(shè)置其options:
download.default_directory:設(shè)置下載路徑
profile.default_content_settings.popups:設(shè)置為 0 禁止彈出窗口
它的設(shè)置就簡(jiǎn)單多了,看個(gè)示例:

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

from selenium import webdriver
from time import sleep


options = webdriver.ChromeOptions()
prefs = {'profile.default_content_settings.popups': 0, 'download.default_directory': 'd:\\'}
options.add_experimental_option('prefs', prefs)

driver = webdriver.Chrome(executable_path='D:\\chromedriver.exe', chrome_options=options)
driver.get('http://sahitest.com/demo/saveAs.htm')
driver.find_element_by_xpath('//a[text()="testsaveas.zip"]').click()
sleep(3)
driver.quit()

4.14 操作Cookie

操作 效果
get_cookies() 獲得所有cookie信息
get_cookie(name) 返回字典的key為"name"的cookie信息
add_cookie(cookie_dict) 添加cookie ‘cookie_dict’指字典對(duì)象,必須有name和value值
delete_cookie(name,optionsString) 刪除cookie信息 “name”是要?jiǎng)h除的cookie的名稱,“optionsString”是該cookie的選項(xiàng),目前支持的選項(xiàng)包括“路徑”,“域”
delete_all_cookies() 刪除所有cookie信息
# coding:utf-8
from selenium import webdriver

driver = webdriver.Firefox()
driver.implicitly_wait(3)

# 添加cookie
driver.add_cookie({'name': 'key-aaa', 'value': 'key-bbb'})

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

# 獲得cookie信息
cookies = driver.get_cookies()

print cookies

for cookie in cookies:
    print cookie['name'], '->', cookie['value']
driver.quit()

4.15 調(diào)用JavaScript

# coding:utf-8
from selenium import webdriver
from time import sleep

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

# 設(shè)置瀏覽器窗口大小
driver.set_window_size(600, 600)

# 搜索
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
sleep(2)

# 通過(guò)JS設(shè)置瀏覽器窗口的滾動(dòng)條位置
js = "window.scrollTo(100,450)"
driver.execute_script(js)
sleep(3)

driver.quit()

4.16 處理HTML5的視頻播放

# coding:utf-8

from selenium import webdriver
from time import sleep

driver = webdriver.Firefox()
driver.implicitly_wait(5)
driver.get("http://videojs.com/")

video = driver.find_element_by_xpath(".//*[@id='preview-player_html5_api']")
# video = driver.find_element_by_xpath("body/Section[1]/div/video")

# 返回播放文件地址
url = driver.execute_script("return arguments[0].currentSrc;", video)
print url

# 播放視頻
print "start"
driver.execute_script("return arguments[0].play()", video)

sleep(15)

# 暫停視頻
print "pause"
driver.execute_script("arguments[0].pause()", video)

driver.quit()

4.17 窗口截圖

# coding:utf-8

from selenium import webdriver
from time import sleep

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()
sleep(2)

# 截取當(dāng)前窗口,并指定截圖保存位置
driver.get_screenshot_as_file("/home/wy/")

driver.quit()

4.18 關(guān)閉窗口

driver.close()

4.19 驗(yàn)證碼的處理

  1. 叫開(kāi)發(fā)人員去掉驗(yàn)證碼
  2. 設(shè)置萬(wàn)能驗(yàn)證碼
  3. Python-tesseract光學(xué)識(shí)別 Tesseract OCR引擎的封裝類
  4. 記錄 cookie 繞過(guò)驗(yàn)證碼
# ...
# 訪問(wèn)某網(wǎng)站...

driver.get("http://xxx.com")

driver.add_cookie({'name':'Login_UserNumber','value':'username'})
driver.add_cookie({'name':'Login_Password','value':'password'})

4.20 WebDriver原理

  1. WebDriver啟動(dòng)瀏覽器,綁定指定端口,作為Remote Server
  2. Client 通過(guò)CommandExcuter發(fā)送HTTPRequest給Remote Server幀聽(tīng)端口
  3. Remote Server需要依賴原聲的瀏覽器組件 轉(zhuǎn)化瀏覽器的native調(diào)用

接收客戶端DEBUG

# coding:utf-8
from selenium import webdriver
import logging

logging.basicConfig(level=logging.DEBUG)
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()

driver.quit()

5. 自動(dòng)化測(cè)試模型

測(cè)試模型:

  1. 線性測(cè)試
  2. 模塊化驅(qū)動(dòng)測(cè)試
  3. 數(shù)據(jù)驅(qū)動(dòng)測(cè)試
  4. 關(guān)鍵字測(cè)試

5.1 自動(dòng)化測(cè)試模型介紹

5.1.1 線性測(cè)試

通過(guò)錄制或編寫對(duì)應(yīng)用程序的操作步驟產(chǎn)生相應(yīng)的線性腳本,每個(gè)測(cè)試腳本相對(duì)獨(dú)立,且不產(chǎn)生其他依賴與調(diào)用,這是早期的自動(dòng)化測(cè)試的形式,
單純的模擬用戶完整的操作場(chǎng)景,優(yōu)勢(shì)完整獨(dú)立,缺點(diǎn)開(kāi)發(fā)和維護(hù)的成本很高

5.1.2 模塊化測(cè)試

把重復(fù)的操作獨(dú)立成公共模塊,當(dāng)用例執(zhí)行過(guò)程中用到這一個(gè)模塊時(shí),則被調(diào)用,最大限度的消除了重復(fù),提高可維護(hù)性

5.1.3 數(shù)據(jù)驅(qū)動(dòng)測(cè)試

數(shù)據(jù)驅(qū)動(dòng)說(shuō)的直白一點(diǎn)就是數(shù)據(jù)的參數(shù)化,因?yàn)檩斎霐?shù)據(jù)的不同而引起不同的輸出結(jié)果 Datapool

5.1.4 關(guān)鍵字驅(qū)動(dòng)

無(wú)法是把"數(shù)據(jù)"換成"關(guān)鍵字",通過(guò)關(guān)鍵字的改變引起測(cè)試結(jié)果的改變
目前市面上的典型關(guān)鍵字驅(qū)動(dòng)工具 QTP(目前已更名UFT-Unified Functional Testing)、Robot Framework(RIDE)工具為主
這類工具封裝了底層的代碼,提供用戶獨(dú)立的圖形界面,以"填表格"的形式免除測(cè)試人員對(duì)寫代碼的恐懼,從而減低編寫難度

6. selenium IDE

不用翻墻的 安裝地址:https://addons.mozilla.org/en-US/firefox/addon/selenium-ide/

7. unittest 單元測(cè)試框架

8. 自動(dòng)化測(cè)試高級(jí)應(yīng)用

9. Selenium Grid2

10. Python多線程

11. 自動(dòng)化測(cè)試實(shí)戰(zhàn)

  • mztestpro/目錄
    • bbs/ 論壇項(xiàng)目
      • data/ 存放測(cè)試數(shù)據(jù)
      • report/ 用于存放HTML測(cè)試報(bào)告
        • image/ 創(chuàng)建了image目錄用于存放測(cè)試過(guò)程中的截圖
      • test_case/ 測(cè)試用例目錄,用于存放測(cè)試用例及相關(guān)模塊
        • models/ 該目錄下存放了一些公共的配置函數(shù)及公共類
          • driver.py
          • function.py
          • myunit.py
        • page_obj/ 該目錄用于存放測(cè)試用例的頁(yè)面對(duì)象(Page Object),根據(jù)自定義規(guī)則,以“*Page.py”命名的文件為封裝的頁(yè)面對(duì)象文件
          • *Page.py
        • _sta.py 測(cè)試用例文件。根據(jù)測(cè)試文件匹配規(guī)則,”_sta.py“命名的文件將被當(dāng)作自動(dòng)化測(cè)試用例執(zhí)行
    • driver/
    • package/
    • run_bbs_test.py
    • startup.bat
    • 自動(dòng)化測(cè)試項(xiàng)目說(shuō)明文檔.md

12. BDD框架指Lettuce入門

13. GitHub托管項(xiàng)目

14. 持續(xù)繼承Jenkins入門

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容