1. 什么是框架
框架(framework)是一個(gè)框子 -- 指其約束性,也是一個(gè)架子 -- 指其支撐性啥箭,是一個(gè)基本概念上的結(jié)構(gòu)属划,用于去解決或者處理復(fù)雜的問題。
框架是整個(gè)或部分系統(tǒng)的可重用設(shè)計(jì)腹躁,表現(xiàn)為一組抽象構(gòu)件及構(gòu)件實(shí)例間交互的方法;另一種定義認(rèn)為南蓬,框架是可被應(yīng)用開發(fā)者定制的應(yīng)用骨架纺非。前者是從應(yīng)用方面而后者是從目的方面給出的定義哑了。
框架,其實(shí)就是某種應(yīng)用的半成品烧颖,就是一組組件弱左,供你選用完成你自己的系統(tǒng)。簡單說就是使用別人搭好的舞臺(tái)炕淮,你來做表演拆火。
2. 為什么使用框架
1)自己從頭實(shí)現(xiàn)太復(fù)雜
2)使用框架能夠更專注于業(yè)務(wù)邏輯,加快開發(fā)速度
3)框架的使用能夠處理更多細(xì)節(jié)問題
4)使用人數(shù)多涂圆,穩(wěn)定性们镜,擴(kuò)展性好
3. selenium工作原理
image.png
4. selenium環(huán)境搭建
1)python3.7
2)Firefox35(大于43)
3)selenium2框架
穩(wěn)定版 2.48.0 (pip install selenium==2.48.0)
4)瀏覽器驅(qū)動(dòng)
selenium之 chromedriver與chrome版本映射表
Firefox瀏覽器對應(yīng)各個(gè)版本驅(qū)動(dòng)下載地址
注意:Firefox35(大于43)版本不需要下載驅(qū)動(dòng)器,大于這個(gè)版本的需要乘综,Chrome需要下載驅(qū)動(dòng)器憎账,下邊分別演示。
5. selenium對瀏覽器操作
1)庫的導(dǎo)入
fromseleniumimportwebdriver
2)創(chuàng)建瀏覽器對象
driver = webdriver.xxx()
使用dir(driver)查看方法
# 必須為大寫driver = webdriver.Firefox()driver = webdriver.Chrome()
3)瀏覽器尺寸相關(guān)操作
maximize_window()? ? 最大化get_window_size()? ? 獲取瀏覽器尺寸卡辰,打印查看set_window_size()? ? 設(shè)置瀏覽器尺寸,400*400
4)瀏覽器位置相關(guān)操作
get_window_position()? ? 獲取瀏覽器位置set_window_position(x,y)? ? 設(shè)置瀏覽器位置
注意:顯示器以左上角為(0,0),所有的位置操作都是相對于顯示器左上角展開的位移操作邪意,單位是像素九妈。
5)瀏覽器的關(guān)閉操作
close()關(guān)閉當(dāng)前標(biāo)簽/窗口quit()關(guān)閉所有標(biāo)簽/窗口
6)頁面請求操作
driver.get(url)請求某個(gè)url對應(yīng)的響應(yīng)refresh()刷新頁面操作back()回退到之前的頁面forward()前進(jìn)到之后的頁面
案例
fromselenium import webdriverimport time# driver = webdriver.Chrome()#不可以找到,必須導(dǎo)入對應(yīng)的驅(qū)動(dòng)器driver=webdriver.Firefox()url1="http://www.baidu.com"url2="https://zhuanlan.zhihu.com/"# 請求第一個(gè)接口driver.get(url1)time.sleep(3)# 刷新driver.refresh()driver.get(url2)# 回退driver.back()time.sleep(3)# 前進(jìn)driver.forward()time.sleep(3)driver.close()
6. selenium獲取斷言信息
6.1 什么是斷言
斷言是編程術(shù)語雾鬼,表示為一些布爾表達(dá)式萌朱,程序員相信在程序中的某個(gè)特定點(diǎn)該表達(dá)式值為真,可以在任何時(shí)候啟用和禁用斷言驗(yàn)證策菜,因此可以在測試時(shí)啟用斷言而在部署時(shí)禁用斷言晶疼。
6.2 獲取斷言信息的操作
current_url? ? 獲取當(dāng)前訪問頁面url
title? ? ? 獲取當(dāng)前瀏覽器標(biāo)題
page_source? ? ? 獲取網(wǎng)頁源碼
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)# 第一種# ele = driver.find_element_by_id("kw")# ele.send_keys(12306)? # 輸入數(shù)據(jù)# from selenium.webdriver.common.by import By# ele = driver.find_element(By.ID,"kw")# ele.send_keys(12306)? # 輸入數(shù)據(jù)
# 第二種# ele = driver.find_element_by_name("wd")# ele.send_keys(12306)? # 輸入數(shù)據(jù)
# 第三種# ele = driver.find_element_by_class_name("s_ipt")# ele.send_keys(12306)? # 輸入數(shù)據(jù)#
?第四種# ele = driver.find_element_by_xpath("http://*[@id='kw']")# ele.send_keys(12306)? # 輸入數(shù)據(jù)#
?第五種# ele = driver.find_element_by_css_selector("#kw")# ele.send_keys(12306)? # 輸入數(shù)據(jù)
# 第六種# ele = driver.find_element_by_link_text("地圖")# ele.click()? # 輸入數(shù)據(jù)
# 第七種:類似于模糊匹配# ele = driver.find_element_by_partial_link_text("地")# ele.click()
# 第八種:標(biāo)簽名定位,必須得保證只有一個(gè)這種名字的標(biāo)簽又憨,使用下面這個(gè)搜索# url = "http://cn.bing.com/"# driver.get(url)# ele = driver.find_element_by_tag_name("input")# ele.send_keys(12306)? # 輸入數(shù)據(jù)
8. 元素的操作
對元素的相關(guān)操作翠霍,一般要先獲取到元素,再調(diào)用相關(guān)方法
element = driver.find_element_by_xxx(value)
1)點(diǎn)擊和輸入
點(diǎn)擊操作---------->element.click()
清空/輸入操作:
element.clear()---------------------->清空輸入框
element.send_keys(data)-------->輸入數(shù)據(jù)
案例
1.打開百度搜索? ? ? ? 2.搜索關(guān)鍵字 selenium? ? ? ? 3.清空? ? ? ? ? ? 4.搜索python
2)提交操作
element.submit()
9. 多標(biāo)簽之間的切換
場景:有的時(shí)候點(diǎn)擊一個(gè)鏈接蠢莺,新頁面并非由當(dāng)前頁面跳轉(zhuǎn)過去寒匙,而是新開一個(gè)頁面打開,這種情況下躏将,計(jì)算機(jī)需要識別多標(biāo)簽或窗口的情況锄弱。
1)獲取所以窗口的句柄
handles = driver.window_handlers
調(diào)用該方法會(huì)得到一個(gè)列表,在selenium運(yùn)行過程中的每一個(gè)窗口都有一個(gè)對應(yīng)的值存放在里面祸憋。
2)通過窗口的句柄進(jìn)入的窗口
driver.switch_to_window(handles[n])
driver.switch_to.window(handles[n])
通過窗口句柄激活進(jì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()# 直接報(bào)錯(cuò)会宪,原因是需要句柄eleDaxing=driver.find_element_by_link_text("大興")eleDaxing.click()# 使用句柄driver.get("http://bj.58.com")print("點(diǎn)擊之前句柄:",driver.window_handles)ele=driver.find_element_by_xpath(".//*[@id='fcNav']/em/a[1]")ele.click()list_windowns=driver.window_handlesprint("點(diǎn)擊之后句柄:",driver.window_handles)driver.switch_to.window(list_windowns[1])eleDaxing=driver.find_element_by_link_text("大興")eleDaxing.click()
10. 多表單切換
在網(wǎng)頁中,表單嵌套是很常見的情況蚯窥,尤其是在登錄的場景
10.1 什么是多表單
實(shí)際上就是使用iframe/frame掸鹅,引用了其他頁面的鏈接喜命,真正的頁面數(shù)據(jù)并沒有出現(xiàn)在當(dāng)前源碼中,但是在瀏覽器中我們看到河劝,簡單理解可以使頁面中開了一個(gè)窗口顯示另一個(gè)頁面
10.2 處理方法
直接使用id值切換進(jìn)表單
driver.switch_to.frame(value)/driver.switch_to_frame(value)
定位到表單元素壁榕,再切換進(jìn)入
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. 彈出框操作
進(jìn)入到彈出框中
driver.switch_to.alert
接收警告
accept()
解散警告
dismiss()
發(fā)送文本到警告框
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. 鼠標(biāo)和鍵盤操作
手動(dòng)測試時(shí)鍵盤的操作在selenium頁有實(shí)現(xiàn),關(guān)于鼠標(biāo)的操作由ActionChains()類來提供赎瞎,關(guān)于鍵盤的操作由Key()類來提供
1)鼠標(biāo)操作
導(dǎo)入動(dòng)作鏈類牌里,動(dòng)作鏈可以儲(chǔ)存鼠標(biāo)的動(dòng)作,并一起執(zhí)行
fromselenium.webdriverimportActionChainsActionChains(driver)
鼠標(biāo)右擊
el=driver.find_element_by_xxx(value)context_click(el)
對el執(zhí)行右擊
執(zhí)行ActionChains中儲(chǔ)存的所有動(dòng)作
perform()
常用鼠標(biāo)動(dòng)作:
ActionChains(driver).context_click(ele).perform()點(diǎn)擊鼠標(biāo)右鍵ActionChains(driver). double_click(ele).perform()點(diǎn)擊鼠標(biāo)左鍵ActionChains(driver).move_to_element(el).perform()鼠標(biāo)懸停
案例
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使用
導(dǎo)入
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(chǎn)’)全選(Ctrl+A)send_keys(Keys.CONTROL,‘a(chǎn)’)全選(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) 為什么要進(jìn)行等待务甥?
1.網(wǎng)速慢
2.網(wǎng)站內(nèi)容過多
3.如果不進(jìn)行等待而直接定位元素牡辽,可能會(huì)拋出異常
2) selenium中等待的分類:
顯示等待
顯示等待是根據(jù)條件進(jìn)行等待,等待條件出現(xiàn)
實(shí)現(xiàn):
fromselenium.webdriver.common.byimportByfromselenium.webdriver.support.uiimportWebDriverWaitfromselenium.webdriver.supportimportexpected_conditionsasECWebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
WebDriverWait類是由WebDirver 提供的等待方法敞临。在設(shè)置時(shí)間內(nèi)态辛,默認(rèn)每隔一段時(shí)間檢測一次當(dāng)前頁面元素是否存在,如果超過設(shè)置時(shí)間檢測不到則拋出異常挺尿。
案例
WebDriverWait(driver,10,0.5).until(EC.presence_of_element_located((By.CLASS_NAME,"g-hu")))
思考:顯示等待與time的區(qū)別奏黑?
隱式等待
隱式等待是根據(jù)是件進(jìn)行等待,等待特定時(shí)間
driver.implicitly_wait(n)
n的單位為秒,n為最大值,在這個(gè)最大值內(nèi)只要該界面上的全部元素都加載完成定就結(jié)束沒有加載出元素就拋出? NosuchException.
注意:優(yōu)先隱式等待编矾,次之顯式等待熟史,最次固定等待
15. 練習(xí)
使用游覽器登錄http://www.baidu.com
搜索淘寶官網(wǎng)
登錄用戶名和密碼
搜索商品(手機(jī),電腦窄俏,蹂匹,,凹蜈,),給定約束條件(價(jià)格,包郵,發(fā)貨地址限寞。。仰坦。)
將商品添加到購物車
在購物中游覽該商品
根據(jù)自己的喜好進(jìn)行下面的操作
16. 2.IDE功能簡介
image.png
文件:創(chuàng)建履植、打開和保存測試案例和測試案例集。編輯:復(fù)制缎岗、粘貼静尼、刪除、撤銷和選擇測試案例中的所有命令传泊。Options : 用于設(shè)置seleniunm IDE鼠渺。
用來填寫被測網(wǎng)站的地址。
速度控制:控制案例的運(yùn)行速度眷细。
運(yùn)行所有:運(yùn)行一個(gè)測試案例集中的所有案例拦盹。
運(yùn)行:運(yùn)行當(dāng)前選定的測試案例。
暫停/恢復(fù):暫停和恢復(fù)測試案例執(zhí)行溪椎。
單步:可以運(yùn)行一個(gè)案例中的一行命令普舆。
錄制:點(diǎn)擊之后恬口,開始記錄你對瀏覽器的操作。
案例集列表沼侣。
測試腳本祖能;table標(biāo)簽:用表格形式展現(xiàn)命令及參數(shù)。source標(biāo)簽:用原始方式展現(xiàn)蛾洛,默認(rèn)是HTML語言格式养铸,也可以用其他語言展示。
查看腳本運(yùn)行通過/失敗的個(gè)數(shù)轧膘。
當(dāng)選中前命令對應(yīng)參數(shù)钞螟。
日志/參考/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()