環(huán)境:
Python:3.6.1
selenium:3.4.3
Firefox:54.0.1
geckodriver:0.15.0
chrome:59.0.3
chromedriver:v3.1
自動化測試基礎(chǔ)
1、軟件測試分類
根據(jù)項(xiàng)目流程:單元測試(編碼)、集成測試(設(shè)計(jì))、系統(tǒng)測試(需求)、驗(yàn)收測試
根據(jù)代碼是否可見:白盒測試、黑盒測試、灰盒測試
功能測試:邏輯功能測試、界面測試、易用性測試、安裝測試、兼容性測試
性能測試:負(fù)載測試、壓力測試
手工測試:手工執(zhí)行測試用例
自動化測試:性能自動化和功能自動化
冒煙測試:在對系統(tǒng)進(jìn)行正式測試之前,先驗(yàn)證主要功能是否實(shí)現(xiàn),是否具備可測性
回歸測試:修改代碼之后確保沒有引入新的錯(cuò)誤,或?qū)е缕渌a產(chǎn)生錯(cuò)誤
隨機(jī)測試:為了模擬用戶的操作,測試中輸入的數(shù)據(jù)都是隨機(jī)的,以便發(fā)現(xiàn)一些邊緣性的錯(cuò)誤
探索性測試:強(qiáng)調(diào)主觀能動性,碰到問題時(shí)主動改變策略
安全測試:驗(yàn)證產(chǎn)品是否符合安全需求定義和產(chǎn)品質(zhì)量標(biāo)準(zhǔn)
2、什么項(xiàng)目適合自動化
1)項(xiàng)目需求變動不頻繁(回歸測試,每日構(gòu)建后的測試驗(yàn)證)
2)項(xiàng)目周期長
3)自動化測試腳本可復(fù)用
3、自動化測試分類和工具
1)分類:UI自動化、接口自動化、單元測試自動化
2)工具:
QTP:企業(yè)級自動化測試工具,支持B/S,C/S架構(gòu)
robot framework:Python語言編寫,支持關(guān)鍵字驅(qū)動,分布式測試
Watir:基于web模式的功能自動化測試工具
selenium:支持多語言、多平臺、多瀏覽器
4、selenium工具
1)特點(diǎn):多語言---Java、Python、PHP、ruby
? ? ? ? ? ? ? ? 多平臺---Windows、Linux、Mac
? ? ? ? ? ? ? ?多瀏覽器----Firefox、chrome、IE
? ? ? ? ? ? ? ? 開源、免費(fèi)
? ? ? ? ? ? ? ? 簡單、靈活
2)selenium1.0
selenium IDE:實(shí)現(xiàn)瀏覽器操作的簡單錄制和回放,支持多種語言
selenium Grid:自動化測試輔助工具
? ? ? ? ? ? ? ? ? ? ? ? ? 并行執(zhí)行
? ? ? ? ? ? ? ? ? ? ? ? ? 通過一個(gè)主機(jī)控制用例在不同環(huán)境、不同瀏覽器下執(zhí)行
selenium RC:selenium的核心,支持多種編程語言編寫腳本,通過selenium服務(wù)器作為代理服務(wù)器去訪問應(yīng)用,從而實(shí)現(xiàn)測試的目的。
selenium RC:client libraries---編寫測試腳本,控制selenium server的庫
? ? ? ? ? ? ? ? ? ? ? ? selenium server---控制瀏覽器行為
selenium server:selenium core---一堆js函數(shù),嵌入到瀏覽器中,通過這些函數(shù)控制瀏覽器操 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?作
? ? ? ? ? ? ? ? ? ? ? ? ? ? launcher---啟動瀏覽器,并將selenium core加載到瀏覽器中,將selenium ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? server的http proxy設(shè)置為瀏覽器的代理服務(wù)器
3)selenium2.0
webdriver替代了selenium RC,為了向下兼容性,selenium RC仍然可以使用
selenium RC通過嵌入到瀏覽器中的js函數(shù)操作
webdriver針對各瀏覽器開發(fā),通過原生瀏覽器支持或者瀏覽器擴(kuò)展控制瀏覽器
簡單自動化測試腳本

Python webdriver API
1、瀏覽器操作
1)瀏覽器最大化
driver.maximize_window()
2)設(shè)置瀏覽器寬和高
driver.set_window_size(400,800)
3)控制瀏覽器前進(jìn)、后退
driver.forward()
driver.back()
2、簡單對象的定位
find_element_by_id()----唯一
find_element_by_name()----唯一
find_element_by_linx_text()----操作對象是文字超鏈接
find_element_by_partial_link_text()----操作對象是文字超鏈接
find_element_by_class_name()
find_element_by_tag_name()
find_element_by_xpath()
暫時(shí)可以通過firepath定位xpath路徑,以后再研究
find_element_by_css_selector()
這個(gè)真的不懂,firebug里面可以定位
3、操作測試對象
clear()---------------清除內(nèi)容,如默認(rèn)用戶名和密碼
click()---------------模擬鼠標(biāo)點(diǎn)擊操作
send_keys()------向輸入框輸入
submit()------------提交表單
4、WebElement接口常用方法
size--------------------返回元素尺寸
text----------------------獲取元素文本信息
get_attribute(name)-------------獲取元素某個(gè)屬性值
is_displayde-----------------------該元素用戶是否可見


5、鼠標(biāo)事件
ActionChains類操作鼠標(biāo)事件
ActionChains的使用
from selenium.webdriver.common.actionchains import ActionChains
ActionChains的執(zhí)行原理
調(diào)用ActionChains方法的時(shí)候,用戶行為不會立刻執(zhí)行,而是將所有操作放在一個(gè)隊(duì)列中,當(dāng)執(zhí)行perform()方法時(shí),按照放入隊(duì)列的順序先進(jìn)先出執(zhí)行
ActionChains方法的書寫格式
ActionChains(driver).context_click(操作對象).perform()
鼠標(biāo)點(diǎn)擊
context_click()------------------鼠標(biāo)右擊
double_click()------------------鼠標(biāo)雙擊(應(yīng)用場景:查看圖片,雙擊選定文字)
click()-----------------------------鼠標(biāo)點(diǎn)擊
click_and_hold()---------------按住鼠標(biāo)左鍵不懂
鼠標(biāo)移動
move_to_element(目標(biāo)元素)------------------------移動到某個(gè)元素
move_by_offset(xoffset,yoffset)--------------------移動到某個(gè)坐標(biāo)
鼠標(biāo)拖曳
drag_and_drop(source,target)------將元素從起點(diǎn)source移動到終點(diǎn)target
drag_and_drop_by_offset(source,xoffset,yoffset)-------按照坐標(biāo)移動
6、鍵盤事件
Keys類操作鍵盤事件
Keys類的使用
from selenium.webdriver.common.keys import Keys
常用的組合鍵
send_keys(Keys.CONTROL,'a')----------------全選
send_keys(Keys.CONTROL,'c')----------------復(fù)制
send_keys(Keys.CONTROL,'v')----------------粘貼
send_keys(Keys.CONTROL,'x')----------------剪切
常用的非組合鍵
send_keys(Keys.ENTER)--------------------------------回車鍵
send_keys(Keys.BACK_SPACE)----------------------刪除鍵
send_keys(Keys.SPACE)--------------------------------空格鍵
send_keys(Keys.TAB)------------------------------------制表鍵
send_keys(Keys.ESCAPE)------------------------------回退鍵
send_keys(Keys.F5)---------------------------------------刷新鍵

7、獲得頁面URL和title
1)獲得當(dāng)前頁面title,判斷頁面跳轉(zhuǎn)是否符合預(yù)期
title = driver.title
2)獲得當(dāng)前URL,一般用來測試重定向
url = driver.current_url
8、設(shè)置等待時(shí)間
sleep():設(shè)置固定休眠時(shí)間。Python的time包提供sleep方法
implicitly_wait():webdriver提供的一個(gè)隱性等待的時(shí)間,在一個(gè)時(shí)間段內(nèi)只能的等待,超時(shí)則拋出異常
WebDriverWait():webdriver提供的另一個(gè)方法,在設(shè)置時(shí)間內(nèi),默認(rèn)每隔一段時(shí)間去檢測頁面元素是否存在,如果超出設(shè)置時(shí)間檢測不到則拋出異常。


WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
driver - WebDriver 的驅(qū)動程序(Ie, Firefox, Chrome 或遠(yuǎn)程)
timeout - 最長超時(shí)時(shí)間,默認(rèn)以秒為單位
poll_frequency - 休眠時(shí)間的間隔(步長)時(shí)間,默認(rèn)為0.5 秒
ignored_exceptions - 超時(shí)后的異常信息,默認(rèn)情況下拋NoSuchElementException 異常。
9、定位一組對象
find_elements返回的是一個(gè)list
定位一組對象,一般應(yīng)用于下列場景:
? ? ? ? ? ?批量操作對象,比如將頁面上的CheckBox都選上
1)find_elements_by_tag_name()

2)find_element_by_css_selector()

10、定位frame中的對象
針對frame嵌套的情況,使用switch_to.frame(id/name/xpath)切換到被嵌套的frame中


11、多窗口處理
要想在多個(gè)窗口之間切換,首先要獲得每一個(gè)窗口的唯一標(biāo)識符號(句柄)。通過獲得的句柄來區(qū)別分不同的窗口,從而對不同窗口上的元素進(jìn)行操作
driver.current_window_handle----------------------獲得當(dāng)前窗口的句柄
driver.window_handles--------------------------------獲得所有窗口的句柄
driver.switch_to_handle("句柄")---------------------切換回句柄所屬的窗口
driver.close()---------------------------------------------關(guān)閉當(dāng)前窗口
driver.quit()-----------------------------------------------關(guān)閉所有窗口


12、下拉菜單處理
1)傳統(tǒng)下拉菜單
先定位到下拉菜單,再點(diǎn)擊選項(xiàng)

2)下拉菜單需點(diǎn)擊才能顯示選項(xiàng)
有兩次點(diǎn)擊動作,第一次點(diǎn)擊下拉菜單,第二次點(diǎn)擊選項(xiàng)
3)下拉菜單不需點(diǎn)擊,鼠標(biāo)放上去就會顯示選項(xiàng),則可以使用move_to_element()方法定位
4)針對下拉菜單標(biāo)簽是select的
導(dǎo)入Select類:from selenium.webdriver.support.select import Select
使用方法:Select(driver.find_element_by_name("xxx")).select_by_index()
選擇列表:
select_by_index(index)---------------------------根據(jù)index屬性定位選項(xiàng),index從0開始
select_by_value(value)---------------------------根據(jù)value屬性定位
select_by_visible_text(text)----------------------根據(jù)選項(xiàng)文本值來定位
first_selected_option()----------------------------選擇第一個(gè)選項(xiàng)

清除列表
deselect_by_index(index)---------------------------根據(jù)index屬性清除選定的選項(xiàng),index從0開始
deselect_by_value(value)---------------------------根據(jù)value屬性
deselect_by_visible_text(text)----------------------根據(jù)選項(xiàng)文本值
deselect_all()--------------------------------------------清除所有選項(xiàng)
13、上傳文件
上傳過程一般是打開一個(gè)系統(tǒng)的window窗口,從窗口選擇文件添加,一般會卡在如何操作Window窗口。其實(shí),沒那么復(fù)雜,只要定位上傳按鈕,通過send_keys()添加文件路徑就可以了。
上傳控件標(biāo)簽為input

上傳控件標(biāo)簽為非input
可以借助第三方工具:Autolt
14、下載文件
webdriver允許設(shè)置默認(rèn)下載路徑,從而可以跳過下載彈窗提示
1)chrome下載
思路:實(shí)例化一個(gè)option對象
? ? ? ? ? ?設(shè)置配置,并加載到option中
? ? ? ? ? ?啟動瀏覽器,點(diǎn)擊下載鏈接
優(yōu)勢:使用谷歌瀏覽器下載,不需要針對各種文件類型進(jìn)行配置

2)Firefox下載
對于Firefox,需要我們設(shè)置其Profile:
browser.download.dir:指定下載路徑
browser.download.folderList:設(shè)置成2表示使用自定義下載路徑;設(shè)置成0表示下載到桌面;設(shè)置成1表示下載到默認(rèn)路徑
browser.download.manager.showWhenStarting:在開始下載時(shí)是否顯示下載管理器
browser.helperApps.neverAsk.saveToDisk:對所給出文件類型不再彈出框進(jìn)行詢問
Firefox需要針對每種文件類型進(jìn)行設(shè)置,這里需要我們查詢對應(yīng)文件的MIME類型,可以用以下鏈接進(jìn)行查詢:MIME 參考手冊

15、調(diào)用js和控制瀏覽器滾動條
1)webdriver提供了execute_script(script,*args)方法調(diào)用js
2)控制瀏覽器滾動條
應(yīng)用場景:判斷法律文件是否閱讀完,滾動條拉倒最下面,表示用戶已看完
? ? ? ? ? ? ? ? ? ?要操作的元素不在視覺范圍內(nèi),需要拖動滾動條
火狐瀏覽器

谷歌瀏覽器

16、處理cookie
driver.get_cookies()-------------------------------獲得所有cookie
driver.get_cookie(name)-------------------------獲得name屬性的cookie
driver.add_cookie(cookie_dic)-----------------添加cookie(cookie格式為字典,)
driver.delete_cookie(name)---------------------刪除特定cookie
driver.delete_all_cookies()----------------------刪除所有cookie
17、驗(yàn)證碼問題
跳過驗(yàn)證碼的方法:
1)去掉驗(yàn)證碼
2)設(shè)置萬能碼
3)通過cookie跳過驗(yàn)證碼登錄
18、webdriver原理
1)WebDriver 啟動目標(biāo)瀏覽器,并綁定到指定端口。該啟動的瀏覽器實(shí)例,做為web driver 的remote server。
2)Client 端通過CommandExcuter 發(fā)送HTTPRequest 給remote server 的偵聽端口(通信協(xié)議: the?webriver wire protocol)
3)Remote server 需要依賴原生的瀏覽器組件(如:IEDriverServer.exe、chromedriver.exe),來轉(zhuǎn)化轉(zhuǎn)化瀏覽器的native 調(diào)用。
自動化測試模型
1、自動化測試模型介紹
1)模塊化與類庫
將腳本中重復(fù)可復(fù)用的部分拿出來寫成一個(gè)公共的模塊,需要的時(shí)候就調(diào)用它,可以大大提高測試人員編寫腳本的效率。如將登錄和退出模塊化
模塊化的優(yōu)點(diǎn):提高效率,不用編寫重復(fù)腳本
? ? ? ? ? ? ? ? ? ? ? ? ?需要修改代碼時(shí),只需要修改模塊代碼,調(diào)用模塊的代碼不需要修改
2)數(shù)據(jù)驅(qū)動
數(shù)據(jù)驅(qū)動可理解成參數(shù)化,輸入數(shù)據(jù)的不同從而導(dǎo)致輸出結(jié)果的不同
將數(shù)據(jù)與腳本分離
3)關(guān)鍵字驅(qū)動
通過關(guān)鍵字的改變引起結(jié)果的改變
QTP、robot framework 等都是以關(guān)鍵字驅(qū)動為主的自動化工具
2、登錄模塊化


3、數(shù)據(jù)驅(qū)動(參數(shù)化)
參數(shù)化方式:讀取TXT文件和CSV文件、函數(shù)、字典?
1)讀取TXT文件

分別打開兩個(gè)文件,將用戶名和密碼賦值給變量,傳遞給輸入框

缺點(diǎn):用戶名和密碼在不同的文件中,修改較麻煩
? ? ? ? ? ?文件中只能保存一個(gè)用戶名和密碼,不能循環(huán)讀取
2)登錄參數(shù)化(函數(shù))
user_info.py

登錄模塊中,通過2個(gè)變量來接受函數(shù)返回的值(用戶名、密碼),?

3)登錄參數(shù)化(字典)
user_info.py

登錄模塊通過字典的鍵值對取值

4)表單參數(shù)化
通過WPS 或excel 創(chuàng)建表格,文件另存為選擇CSV 格式

csv.reader()用于讀取CSV 文件,user[0] 表示表格中第一行第一列的數(shù)據(jù)(用戶名),user[1]表示表格中第一行第二列的數(shù)據(jù)(郵箱),后面類推。通過CSV 讀取文件比較靈活,可以循環(huán)讀取每一條數(shù)據(jù),從而又不局限每次所讀取數(shù)據(jù)的個(gè)數(shù)。
自動化測試用例設(shè)計(jì)
1、手工測試用例和自動化測試用例
手工測試用例
? 較好的異常處理能力,能通過人為的邏輯判斷校驗(yàn)當(dāng)前步驟的功能實(shí)現(xiàn)正確與否。
? 人工執(zhí)行用例具有一定的步驟跳躍性。
? 人工測試步步跟蹤,能夠細(xì)致的定位問題。
? 主要用來發(fā)現(xiàn)功能缺陷
自動化測試用例
? 執(zhí)行對象是腳本,任何一個(gè)判斷都需要編碼定義。
? 用例步驟之間關(guān)聯(lián)性強(qiáng)。
? 主要用來保證產(chǎn)品主體功能正確完整和讓測試人員從繁瑣重復(fù)的工作中解脫出來。
? 目前自動化測試階段定位在冒煙測試和回歸測試。
2、測試類型
1)測試靜態(tài)內(nèi)容
用于驗(yàn)證靜態(tài)性的、不變化的UI元素的存在性
如,頁面底部備案信息,以及頁面頂部的圖片
2)測試鏈接
如果頁面鏈接經(jīng)常變化或文件不時(shí)被重定向,可以嘗試自動化測試
3)功能測試
功能測試通常是需要自動化測試的最復(fù)雜的測試類型,但也通常是最重要的。典型的測試是登錄,注冊網(wǎng)站賬戶,用戶帳戶操作,帳戶設(shè)置變化,復(fù)雜的數(shù)據(jù)檢索操作等等。功能測試通常對應(yīng)著您的應(yīng)用程序的描述應(yīng)用特性或設(shè)計(jì)的使用場景。
4)測試動態(tài)元素
5)ajax測試
Ajax 是一種支持動態(tài)改變用戶界面元素的技術(shù)。頁面元素可以動態(tài)更改,但不需要瀏覽器重新載入頁面,如動畫,RSS 源,其他實(shí)時(shí)數(shù)據(jù)更新等等。
6)斷言assert和驗(yàn)證verify
斷言的優(yōu)點(diǎn)和缺點(diǎn):
優(yōu)點(diǎn):你可以直截了當(dāng)?shù)乜吹綑z查是否通過。
缺點(diǎn):當(dāng)檢查失敗,后續(xù)的檢查不會被執(zhí)行,無法收集那些檢查的結(jié)果狀態(tài)
驗(yàn)證的優(yōu)點(diǎn)和缺點(diǎn):
優(yōu)點(diǎn):遇到失敗時(shí),測試不會終止
缺點(diǎn):不能得到測試失敗的相關(guān)反饋
及時(shí)得到反饋會更合適,因此斷言通常比驗(yàn)證更常使用。
3、Python異常斷言?
1)異常的拋出機(jī)制:
1> 如果在運(yùn)行時(shí)發(fā)生異常,解釋器會查找相應(yīng)的處理語句(稱為handler).
2> 要是在當(dāng)前函數(shù)里沒有找到的話,它會將異常傳遞給上層的調(diào)用函數(shù),看看那里能不能處理。
3> 如果在最外層(全局“main”)還是沒有找到的話,解釋器就會退出,同時(shí)打印出traceback 以便讓用戶找到錯(cuò)誤產(chǎn)生的原因。
注意:雖然大多數(shù)錯(cuò)誤會導(dǎo)致異常,但一個(gè)異常不一定代表錯(cuò)誤,有時(shí)候它們只是一個(gè)警告,有時(shí)候它們可能是一個(gè)終止信號,比如退出循環(huán)等。
2)捕捉異常
try....except...

輸出報(bào)錯(cuò)信息

try...finally...
finally語句必須要要執(zhí)行,比如:文件關(guān)閉,把數(shù)據(jù)庫連接返回給連接池


如圖,按Ctrl+C中斷程序
finally中的語句仍然被執(zhí)行
3)raise拋出異常

4、webdriver截圖
Webdriver 提供錯(cuò)誤截圖函數(shù)get_screenshot_as_file(),可以幫助我們跟蹤bug,在腳本無法繼續(xù)執(zhí)行時(shí)候, get_screenshot_as_file()函數(shù)將截取當(dāng)前頁面的截圖保存到指定的位置

5、編寫自動化測試實(shí)例
編寫自動化測試用例的原則:
1、一個(gè)腳本是一個(gè)完整的場景,從用戶登陸操作到用戶退出系統(tǒng)關(guān)閉瀏覽器。
2、一個(gè)腳本腳本只驗(yàn)證一個(gè)功能點(diǎn),不要試圖用戶登陸系統(tǒng)后把所有的功能都進(jìn)行驗(yàn)證再退出系統(tǒng)
3、盡量只做功能中正向邏輯的驗(yàn)證,不要考慮太多逆向邏輯的驗(yàn)證,逆向邏輯的情況很多(例如手號輸錯(cuò)有很多種情況),驗(yàn)證一方面比較復(fù)雜,需要編寫大量的腳本,另一方面自動化腳本本身比較脆弱,很多非正常的邏輯的驗(yàn)證能力不強(qiáng)。(我們盡量遵循用戶正常使用原則編寫腳本即可)
4、腳本之間不要產(chǎn)生關(guān)聯(lián)性,也就是說編寫的每一個(gè)腳本都是獨(dú)立的,不能依賴或影響其他腳本。
5、如果對數(shù)據(jù)進(jìn)行了修改,需要對數(shù)據(jù)進(jìn)行還原。
6、在整個(gè)腳本中只對驗(yàn)證點(diǎn)進(jìn)行驗(yàn)證,不要對整個(gè)腳本每一步都做驗(yàn)證。
unittest單元測試框架
1、引入單元測試框架
測試類:



setup()方法要在每個(gè)方法執(zhí)行前執(zhí)行一次
teardown()方法在每個(gè)方法執(zhí)行后執(zhí)行一次