一、概念
互聯網軟件的開發和發布,已經形成了一套標準流程,最重要的組成部分就是持續集成(Continuous integration,簡稱CI)
1.1. 持續集成(采蜜)
持續集成指的是,頻繁地(一天多次)將代碼集成到主干。
它的好處主要有兩個:
(1)快速發現錯誤。每完成一點更新,就集成到主干,可以快速發現錯誤,定位錯誤也比較容易。
(2)防止分支大幅偏離主干。如果不是經常集成,主干又在不斷更新,會導致以后集成的難度變大,甚至難以集成。
持續集成的目的,就是讓產品可以快速迭代,同時還能保持高質量。它的核心措施是,代碼集成到主干之前,必須通過自動化測試。只要有一個測試用例失敗,就不能集成。
1.2. 持續交付
持續交付(Continuous delivery)指的是,頻繁地將軟件的新版本,交付給質量團隊或者用戶,以供評審。如果評審通過,代碼就進入生產階段。
持續交付可以看作持續集成的下一步。它強調的是,不管怎么更新,軟件是隨時隨地可以交付的。
1.3. 持續部署
定義:持續部署(continuous deployment)是持續交付的下一步,指的是代碼通過評審以后,自動部署到生產環境。
目標:代碼在任何時刻都是可部署的,可以進入生產階段。
前提:能自動化完成測試、構建、部署等步驟。
二、Jenkins介紹
2.1. Jenkins概念
Jenkins 是一個開源軟件項目,是基于Java開發的一種可拓展持續集成工具,主要用于持續、自動地構建 / 測試 / 集成軟件項目以及監控一些定時執行的任務。
2.2. Jenkins目的
1、持續、自動地構建/測試軟件項目。
2、監控軟件開放流程,快速問題定位及處理,提示開放效率。
2.3. 特性
? 易于安裝,只要把 jenkins.war 部署到 Tomcat 即可運行
? 易于配置,所有配置都是通過其提供的 web 界面實現
? 集成 RSS/E-mail,通過 RSS 發布構建結果或當構建完成時通過 e-mail 通知
? 生成 JUnit / TestNG 測試報告
? 分布式構建,支持 Jenkins 能夠讓多臺計算機一起構建/測試
? 插件支持,支持擴展插件,你可以開發適合自己團隊使用的工具
2.4. 產品發布流程
產品設計成型 → 開發人員開發代碼 → 測試人員測試功能 → 運維人員發布上線
三、安裝配置Jenkins
去官網下載jenkins.war包。
3.1 兩種方式開啟Jenkins
方式1:
在tomcat的bin目錄下啟動(最常用)
方式2:
打開cmd,進入jenkins目錄,然后運行命令:java -jar jenkins.war
四、搭建JMeter+Jenkins+Ant持續化
Ant下載及配置安裝
下載Apache-ant
解壓到你想要安裝的目錄
配置環境變量
驗證是否安裝成功
拷貝Jemter包到ant下
新建一個build.xml文件,里面填入如下代碼
<?xml version="1.0" encoding="UTF-8"?><projectname="ant-jmeter-test"default="run"basedir="."><!-- 需要改成自己本地的 Jmeter 目錄--><propertyname="jmeter.home"value="G:\jmeter\apache-jmeter-3.0"/><!-- jmeter生成jtl格式的結果報告的路徑--><propertyname="jmeter.result.jtl.dir"value="G:\jmeter\jmeter-ant-jenkins\testResult"/><!-- jmeter生成html格式的結果報告的路徑--><propertyname="jmeter.result.html.dir"value="G:\jmeter\jmeter-ant-jenkins\testResult"/><!-- 生成的報告的前綴--><propertyname="ReportName"value="TestReport"/><propertyname="jmeter.result.jtlName"value="${jmeter.result.jtl.dir}/report.jtl"/><propertyname="jmeter.result.htmlName"value="${jmeter.result.html.dir}/index.html"/><!-- 接收測試報告的郵箱 --><propertyname="mail_to"value="barryli89@163.com"/><propertyname="lib.dir"value="${jmeter.home}/lib"/><pathid="xslt.classpath"><filesetdir="${lib.dir}"includes="xalan*.jar"/><filesetdir="${lib.dir}"includes="serializer*.jar"/></path><targetname="run"><antcalltarget="test"/><antcalltarget="report"/></target><targetname="test"><taskdefname="jmeter"classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask"/><jmeterjmeterhome="${jmeter.home}"resultlog="${jmeter.result.jtlName}"><!-- 聲明要運行的腳本。"*.jmx"指包含此目錄下的所有jmeter腳本--><testplansdir="G:\jmeter\jmeter-ant-jenkins"includes="*.jmx"/><propertyname="jmeter.save.saveservice.output_format"value="xml"/></jmeter></target><targetname="report"><!-- 因為上面生成報告的時候,不會將相關的圖片也一起拷貝至目標目錄,所以,需要手動拷貝 --></xslt><copytodir="${jmeter.result.html.dir}"><filesetdir="${jmeter.home}/extras"><includename="collapse.png"/><includename="expand.png"/></fileset></copy></target></project>
進行命令行模式后,進入剛才創建的xml文件存放目錄,如:D:\build 輸入ant即可
五、集成jenkins
打開Jenkins,配置Ant環境
新建一個自由風格任務
構建觸發器
構建配置
配置HTML插件
立即構建
針對報告中不顯示聚合報告的情況
Jenkins執行自動化測試后發送測試報告郵件
web端自動化基礎篇
一、認識web自動化測試
什么是自動化測試?
了解為什么要進行自動化測試?
掌握自動化測試的分類?
web自動化測試的使用條件和場景
自動化測試工具的優缺點
自動化測試的前景和發展方向
1.1 什么是自動化測試
首先比較一下手動和自動:
自動操作如下:
http://n1.itc.cn/img8/wb/sohulife/2016/02/24/145626026613873378.GIF
1.1.1 自動化測試的概念
軟件自動化測試就是通過測試工具或者其他手段,按照測試人員的預定計劃對軟件產品進行自動化測試,他是軟件測試的一個重要組成部分,能夠 完成許多手工測試無法完成或者難以實現的測試工作,正確合理的實施自動化測試,能夠快速,全面的對軟件進行測試,從而提高軟件質量,節省經費,縮短軟件的發布周期。
1.1.2 自動化測試的歷史
自動化測試就是任何利用工具來輔助的測試,幾乎在計算機工業產生的第一天,這種測試就出現了。
歷史上從來沒有出現過“測試自動化取代測試工程師工作”這種事情發生,除非你完全忽略測試人員們的真正工作。
測試自動化意味著使用測試工具。自動化測試是個古老的理念。
1.2 為什么要進行自動化測試
1.2.1 自動化測試的好處
縮短測試周期
計算機行業更新迭代快速,大量頻繁的回歸測試消耗時間,自動化測試能夠將重復的實行交給計算機去做,加快測試速度。
避免人為出錯
測試人員不可能持續高度集中,并且人類易受外界影響(頭疼腦熱,精神不振),可能會造成人為錯誤
測試信息存儲
自動化測試將測試信息和數據儲存在文件中,思路清晰明確,交接方便
輕易獲取覆蓋率
自動化測試能夠解放測試人員,使測試人員能夠有更多的精力做那些非重復性的工作。
其他
自動化測試可以是實現自動或者定時執行
注意:自動化測試的方向是對的,而且趨勢也是如此,但是有些自動化實現不了的還是會手動測試的。
1.3 自動化測試的分類
整體分類
1)自動化功能測試
2)自動化性能測試
自動化功能測試的分類:
1)單元測試:程序員搞定2)功能測試3)接口測試:大中型項目或長期項目可以采用自動化測試
性能測試主要是使用測試工具
Loadrunner、Jmeter等,對軟件進行壓力測試、負載測試等等,因為這些無法用手工進行代替,所以必須自動化。
為了測試一個web站點的服務能力,需要模擬上千上萬的請求(比如打開瀏覽器訪問站點),人的速度是遠遠達不到這樣的操作的
1.4 web自動化條件和使用范圍
1.使用自動化的前提條件
1)手動測試已經完成,后期再不影響進度的前提下逐漸實現自動化2)項目周期長,重復性的工作都交給機器去實現3)需求穩定,項目變動不大4)自動化測試腳本復雜度比較低5)可重復利用
2.使用自動化測試的場景
1)頻繁的回歸測試2)冒煙測試3)傳統行業需求變化不大,應用頻繁4)性能測試
1.5 web自動化常用的工具
常見的自動化web測試工具
QTP(收費)
QTP是Mercury公司的Quick Test Professional的簡稱,是一種自動測試工具。
Selenium(開源)
Selenium一個強大的基于瀏覽器的開源自動化測試工具,通常用來編寫web應用的自動化測試
RFT(收費)
IBM Rational Test Professional的簡稱,是一款先進的自動化的功能和回歸測試工具,使用與測試人員和GUI開發人員,基礎是針對Java,.NET的對象計數和基于web應用程序的錄制,回放功能。
1.6 元素的定位
為什么要學習定位元素?
環境及工具
css選擇器
xpath路徑表達式
1.6.1 為什么要學習元素定位?
1)計算機沒有智能到人的程度。2)計算機不能像手動測試人員一樣通過眼看,手操作鼠標點擊,操作鍵盤輸入。3)計算機通過一系列計數手段找到元素(按鈕、輸入框、模擬鍵盤等)
1.6.2 元素定位的工具或手段有哪些?
1)css選擇器2)xpath
1.6.3 環境及工具
材料
1)firefox352)firebug插件3)firepath插件
安裝步驟
1. 下載瀏覽器插件2. 菜單 → 添加附件 → 設置圖標 → 從文件中添加附件
1.7 xpath
1.7.1 什么是xpath?
XPath即為XML路徑語言,它是一種用來(標準通用標記語言的子集)在 HTML\XML 文檔中查找信息的語言。
W3School官方文檔:http://www.w3school.com.cn/xpath/index.asp
1.7.2 什么是XML?
XML 指可擴展標記語言(EXtensible Markup Language)
XML 是一種標記語言,很類似 HTML
XML 的設計宗旨是傳輸數據,而非顯示數據
1.7.3 XML與HTML
image-20210131105328723.png
1.7.4 節點
節點的概念:每個XML/HTML的標簽我們都稱之為節點
image-20210131105451339.png
image-20210131105508204.png
1.7.5 獲取元素
XPath 使用路徑表達式來選取 XML 文檔中的節點或者節點集。這些路徑表達式和我們在常規的電腦文件系統中看到的表達式非常相似。
image-20210131105621486.png
/根節點//title? ? ? 全局模糊定位title//head/.? 定位head元素//haad/.. 定位head元素的父元素 //meta[@conent]? ? ? //meta[@conent=""]? ? ? ?
查找某個特定的節點或者包含某個指定的值的節點
image-20210131105640774.png
/html/head/meta[1]
選擇未知節點
image-20210131105702030.png
選取若干路徑
image-20210131105721728.png
image-20210131105749178.png
1.8 css選擇器
1.8.1 什么是css選擇器?
CSS 中,選擇器是一種模式,用于選擇需要添加樣式的元素。計算機能夠通過css選擇器定位到相應元素,我們在編寫自動化測試腳本的時候很多時候是在不斷地找到css選擇器。
1.8.2 css選擇器語法
1)通過偽類名、id、標簽名定位
image-20210131105944480.png
測試站點:?http://www.baidu.com
2)通過元素之前嵌套關系
image-20210131110014690.png
測試:Form span
3)通過屬性
image-20210131110048947.png
image-20210131110106391.png
4)通過父子關系
Web自動化測試進階
1. 什么是框架
框架(framework)是一個框子 -- 指其約束性,也是一個架子 -- 指其支撐性,是一個基本概念上的結構,用于去解決或者處理復雜的問題。
框架是整個或部分系統的可重用設計,表現為一組抽象構件及構件實例間交互的方法;另一種定義認為,框架是可被應用開發者定制的應用骨架。前者是從應用方面而后者是從目的方面給出的定義。
框架,其實就是某種應用的半成品,就是一組組件,供你選用完成你自己的系統。簡單說就是使用別人搭好的舞臺,你來做表演。
2. 為什么使用框架
1)自己從頭實現太復雜
2)使用框架能夠更專注于業務邏輯,加快開發速度
3)框架的使用能夠處理更多細節問題
4)使用人數多,穩定性,擴展性好
3. selenium工作原理
image.png
selenium原理.png
原理:webdriver是按照server–client的經典設計模式設計的。
server端就是remote server,可以是任意的瀏覽器。當我們的腳本啟動瀏覽器后,該瀏覽器就是remote server,它的職責就是等待client發送請求并做出相應;client端簡單說來就是我們的測試代碼,我們測試代碼中的一些行為,比如打開瀏覽器,轉跳到特定的url等操作是以http請求的方式發送給被測試瀏覽器,也就是remote server;remote server接受請求,并執行相應操作,并在response中返回執行狀態、返回值等信息。
4. selenium環境搭建
1)python3.7
2)Firefox35(大于43)
3)selenium2框架
穩定版 2.48.0 (pip install selenium==2.48.0)
4)瀏覽器驅動
selenium之 chromedriver與chrome版本映射表
注意:Firefox35(大于43)版本不需要下載驅動器,大于這個版本的需要,Chrome需要下載驅動器,下邊分別演示。
5. selenium對瀏覽器操作
1)庫的導入
fromseleniumimportwebdriver
2)創建瀏覽器對象
driver = webdriver.xxx()
使用dir(driver)查看方法
# 必須為大寫driver = webdriver.Firefox()driver = webdriver.Chrome()
3)瀏覽器尺寸相關操作
maximize_window()? ? 最大化get_window_size()? ? 獲取瀏覽器尺寸,打印查看set_window_size()? ? 設置瀏覽器尺寸,400*400
4)瀏覽器位置相關操作
get_window_position()? ? 獲取瀏覽器位置set_window_position(x,y)? ? 設置瀏覽器位置
注意:顯示器以左上角為(0,0),所有的位置操作都是相對于顯示器左上角展開的位移操作,單位是像素。
5)瀏覽器的關閉操作
close()關閉當前標簽/窗口quit()關閉所有標簽/窗口
6)頁面請求操作
driver.get(url)請求某個url對應的響應refresh()刷新頁面操作back()回退到之前的頁面forward()前進到之后的頁面
案例
fromselenium import webdriverimport time# driver = webdriver.Chrome()#不可以找到,必須導入對應的驅動器driver=webdriver.Firefox()url1="http://www.baidu.com"url2="https://zhuanlan.zhihu.com/"# 請求第一個接口driver.get(url1)time.sleep(3)# 刷新driver.refresh()driver.get(url2)# 回退driver.back()time.sleep(3)# 前進driver.forward()time.sleep(3)driver.close()
6. selenium獲取斷言信息
6.1 什么是斷言
斷言是編程術語,表示為一些布爾表達式,程序員相信在程序中的某個特定點該表達式值為真,可以在任何時候啟用和禁用斷言驗證,因此可以在測試時啟用斷言而在部署時禁用斷言。
6.2 獲取斷言信息的操作
current_url 獲取當前訪問頁面url
title 獲取當前瀏覽器標題
page_source 獲取網頁源碼
print(driver.current_url)print(driver.title)print(driver.page_source)
get_screenshot_as_png() 保存圖片
data=driver.get_screenshot_as_png()withopen("a.png","wb")asf:f.write(data)
image.png
get_screenshot_as_file(file) 直接保存
driver.get_screenshot_as_file("b.png")
7. selenium八大元素定位
from selenium import webdriverdriver=webdriver.Firefox()# url = "http://www.baidu.com"# driver.get(url)# 第一種 id# ele = driver.find_element_by_id("kw")# ele.send_keys(12306)? # 輸入數據# from selenium.webdriver.common.by import By# ele = driver.find_element(By.ID,"kw")# ele.send_keys(12306)? # 輸入數據# 第二種 標簽名字# ele = driver.find_element_by_name("wd")# ele.send_keys(12306)? # 輸入數據# 第三種 class# ele = driver.find_element_by_class_name("s_ipt")# ele.send_keys(12306)? # 輸入數據# 第四種 Xpath# ele = driver.find_element_by_xpath("http://*[@id='kw']")# ele.send_keys(12306)? # 輸入數據# 第五種 css class# ele = driver.find_element_by_css_selector("#kw")# ele.send_keys(12306)? # 輸入數據# 第六種 text# ele = driver.find_element_by_link_text("地圖")# ele.click()? # 輸入數據# 第七種:類似于模糊匹配# ele = driver.find_element_by_partial_link_text("地")# ele.click()# 第八種:標簽名定位,必須得保證只有一個這種名字的標簽,使用下面這個搜索# url = "http://cn.bing.com/"# driver.get(url)# ele = driver.find_element_by_tag_name("input")# ele.send_keys(12306)? # 輸入數據
8. 元素的操作
對元素的相關操作,一般要先獲取到元素,再調用相關方法
element = driver.find_element_by_xxx(value)
1)點擊和輸入
點擊操作---------->element.click()
清空/輸入操作:
element.clear()---------------------->清空輸入框
element.send_keys(data)-------->輸入數據
案例
1.打開百度搜索? ? ? ? 2.搜索關鍵字 selenium? ? ? ? 3.清空? ? ? ? ? ? 4.搜索python
2)提交操作
element.submit()
9. 多標簽之間的切換
場景:有的時候點擊一個鏈接,新頁面并非由當前頁面跳轉過去,而是新開一個頁面打開,這種情況下,計算機需要識別多標簽或窗口的情況。
1)獲取所有窗口的句柄
handles = driver.window_handlers
調用該方法會得到一個列表,在selenium運行過程中的每一個窗口都有一個對應的值存放在里面。
2)通過窗口的句柄進入的窗口
driver.switch_to_window(handles[n])
driver.switch_to.window(handles[n])
通過窗口句柄激活進入某一窗口
案例:58同城租房信息:http://bj.58.com
driver.get("http://bj.58.com")ele=driver.find_element_by_xpath(".//*[@id='fcNav']/em/a[1]")ele.click()# 直接報錯,原因是需要句柄eleDaxing=driver.find_element_by_link_text("大興")eleDaxing.click()# 使用句柄driver.get("http://bj.58.com")print("點擊之前句柄:",driver.window_handles)ele=driver.find_element_by_xpath(".//*[@id='fcNav']/em/a[1]")ele.click()list_windowns=driver.window_handlesprint("點擊之后句柄:",driver.window_handles)driver.switch_to.window(list_windowns[1])eleDaxing=driver.find_element_by_link_text("大興")eleDaxing.click()
10. 多表單切換
在網頁中,表單嵌套是很常見的情況,尤其是在登錄的場景
10.1 什么是多表單
實際上就是使用iframe/frame,引用了其他頁面的鏈接,真正的頁面數據并沒有出現在當前源碼中,但是在瀏覽器中我們看到,簡單理解可以使頁面中開了一個窗口顯示另一個頁面
10.2 處理方法
直接使用id值切換進表單
driver.switch_to.frame(value)/driver.switch_to_frame(value)
定位到表單元素,再切換進入
el = driver.find_element_by_xxx(value)
driver.switch_to.frame(el)/driver.switch_to_frame(el)
案例:QQ空間:https://qzone.qq.com/
fromselenium import? webdriver#打開游覽器driver=webdriver.Firefox()#登錄QQurl="https://qzone.qq.com/"driver.get(url)#獲取元素#定位表單元素ele_bd=driver.find_element_by_id("login_frame")driver.switch_to.frame(ele_bd)ele=driver.find_element_by_xpath(".//*[@id='switcher_plogin']")ele.click()#輸入賬號ele2=driver.find_element_by_id("u")ele2.send_keys()#輸入密碼ele3=driver.find_element_by_id("p")ele3.send_keys("")ele4=driver.find_element_by_id("login_button")ele4.click()
11. 彈出框操作
進入到彈出框中
driver.switch_to.alert
接收警告
accept()
解散警告
dismiss()
發送文本到警告框
send_keys(data)
用法:driver.switch_to.alert.accept()
案例:
from seleniumimportwebdriverdriver=webdriver.Firefox()driver.get("http://www.baidu.com")ele_setting=driver.find_element_by_id("s-usersetting-top")ele_setting.click()ele_gaoji=driver.find_element_by_class_name("setpref")ele_gaoji.click()ele_save=driver.find_element_by_class_name("prefpanelgo")ele_save.click()driver.switch_to.alert.accept()
12.下拉框
fromseleniumimportwebdriverimporttimedriver=webdriver.Firefox()driver.get("http://www.baidu.com")ele=driver.find_element_by_id("s-usersetting-top")ele.click()ele1=driver.find_element_by_xpath(".//*[@id='s-user-setting-menu']/div/a[2]")ele1.click()time.sleep(2)ele2=driver.find_element_by_xpath(".//*[@id='yadv-setting-gpc']/div/div[1]/i[1]")ele2.click()list_ele=driver.find_elements_by_class_name("c-select-item")print(list_ele)list_ele[2].click()# for list_i in list_ele:#? ? print(list_i.text)#? ? if list_i.text =="最近一周":#? ? ? ? list_i.click()
13. 鼠標和鍵盤操作
手動測試時鍵盤的操作在selenium頁有實現,關于鼠標的操作由ActionChains()類來提供,關于鍵盤的操作由Key()類來提供
1)鼠標操作
導入動作鏈類,動作鏈可以儲存鼠標的動作,并一起執行
fromselenium.webdriverimportActionChainsActionChains(driver)
鼠標右擊
el=driver.find_element_by_xxx(value)context_click(el)
對el執行右擊
執行ActionChains中儲存的所有動作
perform()
常用鼠標動作:
ActionChains(driver).context_click(ele).perform()點擊鼠標右鍵ActionChains(driver). double_click(ele).perform()點擊鼠標左鍵ActionChains(driver).move_to_element(el).perform()鼠標懸停
案例
from selenium.webdriverimportActionChainsfrom seleniumimportwebdriverimporttimedriver=webdriver.Firefox()driver.get("http://www.baidu.com")ele=driver.find_element_by_xpath(".//*[@id='s-top-left']/div/a")# ele.click()ActionChains(driver).double_click(ele).perform()
2)鍵盤操作
鍵盤操作使用的是Keys類,一般配合send_keys使用
導入
from selenium.webdriver.common.keys import 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,‘a’)全選(Ctrl+A)send_keys(Keys.CONTROL,‘x’)剪切(Ctrl+X)send_keys(Keys.CONTROL,‘v’)粘貼(Ctrl+V)send_keys(Keys.F1)鍵盤 F1send_keys(Keys.F12)鍵盤 F12
14. 瀏覽器等待
1) 為什么要進行等待?
1.網速慢
2.網站內容過多
3.如果不進行等待而直接定位元素,可能會拋出異常
2) selenium中等待的分類:
顯示等待
顯示等待是根據條件進行等待,等待條件出現
實現:
fromselenium.webdriver.common.byimportByfromselenium.webdriver.support.uiimportWebDriverWaitfromselenium.webdriver.supportimportexpected_conditionsasECWebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
WebDriverWait類是由WebDirver 提供的等待方法。在設置時間內,默認每隔一段時間檢測一次當前頁面元素是否存在,如果超過設置時間檢測不到則拋出異常。
案例
WebDriverWait(driver,10,0.5).until(EC.presence_of_element_located((By.CLASS_NAME,"g-hu")))
思考:顯示等待與time的區別?
隱式等待
隱式等待是根據是件進行等待,等待特定時間
driver.implicitly_wait(n)
n的單位為秒,n為最大值,在這個最大值內只要該界面上的全部元素都加載完成定就結束沒有加載出元素就拋出 NosuchException.
注意:優先隱式等待,次之顯式等待,最次固定等待
15. 練習
使用游覽器登錄http://www.baidu.com
搜索淘寶官網
登錄用戶名和密碼
搜索商品(手機,電腦,,,,),給定約束條件(價格,包郵,發貨地址。。。)
將商品添加到購物車
在購物中游覽該商品
根據自己的喜好進行下面的操作
16. 2.IDE功能簡介
image.png
文件:創建、打開和保存測試案例和測試案例集。編輯:復制、粘貼、刪除、撤銷和選擇測試案例中的所有命令。Options : 用于設置seleniunm IDE。
用來填寫被測網站的地址。
速度控制:控制案例的運行速度。
運行所有:運行一個測試案例集中的所有案例。
運行:運行當前選定的測試案例。
暫停/恢復:暫停和恢復測試案例執行。
單步:可以運行一個案例中的一行命令。
錄制:點擊之后,開始記錄你對瀏覽器的操作。
案例集列表。
測試腳本;table標簽:用表格形式展現命令及參數。source標簽:用原始方式展現,默認是HTML語言格式,也可以用其他語言展示。
查看腳本運行通過/失敗的個數。
當選中前命令對應參數。
日志/參考/UI元素/Rollup
# -*- coding: utf-8 -*-fromseleniumimportwebdriverfromselenium.webdriver.common.byimportByfromselenium.webdriver.common.keysimportKeysfromselenium.webdriver.support.uiimportSelectfromselenium.common.exceptionsimportNoSuchElementExceptionfromselenium.common.exceptionsimportNoAlertPresentExceptionimportunittest,time,reclassQq(unittest.TestCase):defsetUp(self):self.driver=webdriver.Firefox()self.driver.implicitly_wait(30)self.base_url="https://qzone.qq.com/"self.verificationErrors=[]self.accept_next_alert=Truedeftest_qq(self):driver=self.driver? ? ? ? driver.get(self.base_url+"/")# ERROR: Caught exception [ERROR: Unsupported command [selectFrame | login_frame;login_href=https%3A%2F%2Fxui.ptlogin2.qq.com%2Fcgi-bin%2Fxlogin%3Fproxy_url%3Dhttps%253A%2F%2Fqzs.qq.com%2Fqzone%2Fv6%2Fportal%2Fproxy.html%26daid%3D5%26%26hide_title_bar%3D1%26low_login%3D0%26qlogin_auto_login%3D1%26no_verifyimg%3D1%26link_target%3Dblank%26appid%3D549000912%26style%3D22%26target%3Dself%26s_url%3Dhttps%253A%252F%252Fqzs.qq.com%252Fqzone%252Fv5%252Floginsucc.html%253Fpara%253Dizone%26pt_qr_app%3D%25E6%2589%258B%25E6%259C%25BAQQ%25E7%25A9%25BA%25E9%2597%25B4%26pt_qr_link%3Dhttps%253A%2F%2Fz.qzone.com%2Fdownload.html%26self_regurl%3Dhttps%253A%2F%2Fqzs.qq.com%2Fqzone%2Fv6%2Freg%2Findex.html%26pt_qr_help_link%3Dhttps%253A%2F%2Fz.qzone.com%2Fdownload.html%26pt_no_auth%3D0 | ]]driver.switch_to.frame(driver.find_element_by_id("login_frame"))driver.find_element_by_id("switcher_plogin").click()# driver.find_element_by_id("uin_del").click()driver.find_element_by_id("u").clear()driver.find_element_by_id("u").send_keys("3084761668")driver.find_element_by_id("p").clear()driver.find_element_by_id("p").send_keys("dafei123457")driver.find_element_by_id("login_button").click()# ERROR: Caught exception [ERROR: Unsupported command [selectWindow | null | ]]# driver.find_element_by_id("tcaptcha_drag_thumb").click()# self.assertEqual(driver.title,"QQ空間")self.assertIn("QQ11空間",driver.title)defis_element_present(self,how,what):try:self.driver.find_element(by=how,value=what)exceptNoSuchElementExceptionase:returnFalsereturnTruedefis_alert_present(self):try:self.driver.switch_to_alert()exceptNoAlertPresentExceptionase:returnFalsereturnTruedefclose_alert_and_get_its_text(self):try:alert=self.driver.switch_to_alert()alert_text=alert.textifself.accept_next_alert:alert.accept()else:alert.dismiss()returnalert_textfinally:self.accept_next_alert=TruedeftearDown(self):self.driver.quit()self.assertEqual([],self.verificationErrors)if__name__=="__main__":unittest.main()