1. 什么是框架
框架(framework)是一個框子 -- 指其約束性,也是一個架子 -- 指其支撐性,是一個基本概念上的結構,用于去解決或者處理復雜的問題。
框架是整個或部分系統(tǒng)的可重用設計,表現為一組抽象構件及構件實例間交互的方法;另一種定義認為,框架是可被應用開發(fā)者定制的應用骨架。前者是從應用方面而后者是從目的方面給出的定義。
框架,其實就是某種應用的半成品,就是一組組件,供你選用完成你自己的系統(tǒng)。簡單說就是使用別人搭好的舞臺,你來做表演。
2.為什么使用框架
1)自己從頭實現太復雜
2)使用框架能夠更專注于業(yè)務邏輯,加快開發(fā)速度
3)框架的使用能夠處理更多細節(jié)問題
4)使用人數多,穩(wěn)定性,擴展性好
3.selenium工作原理
4.selenium環(huán)境搭建
1)python3.7
2)Firefox35(大于43)
3)selenium2框架
穩(wěn)定版 2.48.0 (pip install selenium==2.48.0)
4)瀏覽器驅動
selenium之 chromedriver與chrome版本映射表
注意:Firefox35(大于43)版本不需要下載驅動器,大于這個版本的需要,Chrome需要下載驅動器,下邊分別演示。
5.selenium對瀏覽器操作
1)庫的導入
from selenium import webdriver
2)創(chuàng)建瀏覽器對象
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) 設置瀏覽器位置
5)瀏覽器的關閉操作
close() 關閉當前標簽/窗口
quit() 關閉所有標簽/窗口
6)頁面請求操作
driver.get(url) 請求某個url對應的響應
refresh() 刷新頁面操作
back() 回退到之前的頁面
forward() 前進到之后的頁面
·案例
from selenium import webdriver
import 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獲取斷言信息
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()
with open("a.png", "wb") as f:
f.write(data)
get_screenshot_as_file(file) 直接保存
driver.get_screenshot_as_file("b.png")
7.selenium八大元素定位
from selenium import webdriver
driver = webdriver.Firefox()
# url = "http://www.baidu.com"
# driver.get(url)
# 第一種
# 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) # 輸入數據
# 第三種
# ele = driver.find_element_by_class_name("s_ipt")
# ele.send_keys(12306) # 輸入數據
# 第四種
# ele = driver.find_element_by_xpath("http://*[@id='kw']")
# ele.send_keys(12306) # 輸入數據
# 第五種
# ele = driver.find_element_by_css_selector("#kw")
# ele.send_keys(12306) # 輸入數據
# 第六種
# 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)-------->輸入數據
2)提交操作
element.submit()
9.多標簽之間的切換
場景:有的時候點擊一個鏈接,新頁面并非由當前頁面跳轉過去,而是新開一個頁面打開,這種情況下,計算機需要識別多標簽或窗口的情況。
1)獲取所以窗口的句柄
handles = driver.window_handlers
調用該方法會得到一個列表,在selenium運行過程中的每一個窗口都有一個對應的值存放在里面。
2)通過窗口的句柄進入的窗口
driver.switch_to_window(handles[n])
driver.switch_to.window(handles[n])
通過窗口句柄激活進入某一窗口
·五八同城
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_handles
print("點擊之后句柄:", driver.window_handles)
driver.switch_to.window(list_windowns[1])
eleDaxing = driver.find_element_by_link_text("大興")
eleDaxing.click()
10.多表單切換
在網頁中,表單嵌套是很常見的情況,尤其是在登錄的場景
1) 什么是多表單
實際上就是使用iframe/frame,引用了其他頁面的鏈接,真正的頁面數據并沒有出現在當前源碼中,但是在瀏覽器中我們看到,簡單理解可以使頁面中開了一個窗口顯示另一個頁面
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空間
from selenium import webdriver
#打開游覽器
driver = webdriver.Firefox()
#登錄QQ
url = "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()
發(fā)送文本到警告框
send_keys(data)
用法:driver.switch_to.alert.accept()
·案例
from selenium import webdriver
driver = 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.下拉框
from selenium import webdriver
import time
driver = 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)鼠標操作
·導入動作鏈類,動作鏈可以儲存鼠標的動作,并一起執(zhí)行
from selenium.webdriver import ActionChains
ActionChains(driver)
·鼠標右擊
el = driver.find_element_by_xxx(value)
context_click(el)
對el執(zhí)行右擊
執(zhí)行ActionChains中儲存的所有動作
perform()
常用鼠標動作
ActionChains(driver).context_click(ele).perform() 點擊鼠標右鍵
ActionChains(driver). double_click(ele).perform() 點擊鼠標左鍵
ActionChains(driver).move_to_element(el).perform() 鼠標懸停
·案例
from selenium.webdriver import ActionChains
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
ele = driver.find_element_by_xpath(".//*[@id='s-top-left']/div/a")
# ele.click()
ActionChains(d2river).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) 鍵盤 F1
send_keys(Keys.F12) 鍵盤 F12
14.瀏覽器等待
- 為什么要進行等待?
1.網速慢
2.網站內容過多
3.如果不進行等待而直接定位元素,可能會拋出異常 - selenium中等待的分類:
顯示等待
顯示等待是根據條件進行等待,等待條件出現
1.實現:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(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")))
2.隱式等待
隱式等待是根據是件進行等待,等待特定時間
driver.implicitly_wait(n)
n的單位為秒,n為最大值,在這個最大值內只要該界面上的全部元素都加載完成定就結束沒有加載出元素就拋出 NosuchException.
注意:優(yōu)先隱式等待,次之顯式等待,最次固定等待
16.IDE功能簡介
1.文件:創(chuàng)建、打開和保存測試案例和測試案例集。編輯:復制、粘貼、刪除、撤銷和選擇測試案例中的所有命令。Options : 用于設置seleniunm IDE。
2.用來填寫被測網站的地址。
3.速度控制:控制案例的運行速度。
4.運行所有:運行一個測試案例集中的所有案例。
5.運行:運行當前選定的測試案例。
6.暫停/恢復:暫停和恢復測試案例執(zhí)行。
7.單步:可以運行一個案例中的一行命令。
8.錄制:點擊之后,開始記錄你對瀏覽器的操作。
案例集列表。
9.測試腳本;table標簽:用表格形式展現命令及參數。10.source標簽:用原始方式展現,默認是HTML語言格式,也可以用其他語言展示。
11.查看腳本運行通過/失敗的個數。
12.當選中前命令對應參數。
13.日志/參考/UI元素/Rollup
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re
class Qq(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.base_url = "https://qzone.qq.com/"
self.verificationErrors = []
self.accept_next_alert = True
def test_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)
def is_element_present(self, how, what):
try: self.driver.find_element(by=how, value=what)
except NoSuchElementException as e: return False
return True
def is_alert_present(self):
try: self.driver.switch_to_alert()
except NoAlertPresentException as e: return False
return True
def close_alert_and_get_its_text(self):
try:
alert = self.driver.switch_to_alert()
alert_text = alert.text
if self.accept_next_alert:
alert.accept()
else:
alert.dismiss()
return alert_text
finally: self.accept_next_alert = True
def tearDown(self):
self.driver.quit()
self.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
unittest.main()