1. 程式人生 > >一個selenium+python的自動化測試demo

一個selenium+python的自動化測試demo

主要是基礎函式的使用,帶個人註釋,進行了歸納,直接執行會報錯的那種Demo。

目前並不齊全,後期繼續更新。

有什麼問題歡迎提出來交流~

# coding:UTF-8
from selenium import webdriver
import unittest
import sys
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
#通過關鍵字as把excepted_conditiont預期條件判斷類重新命名為EC,則可以在之後使用EC代替excepted_condition
from selenium.webdriver.support import excepted_condition as EC
from time import sleep, ctime
import os

if sys.getdefaultencoding()!='utf-8':
	reload(sys)
	sys.setdefaultencoding('utf-8')

#選擇元素
class DemoAboutSelect(unittest.testcase):
	def setUp(self):
		self.driver = webdriver.Firefox()
		self.base_url = 'http://baidu.com'

	def test(self):
		driver = self.driver
		driver.get(self.base_url)
		
		#可以通過元素的id來定位,id是HTML頁面中元素的唯一的屬性,適合用來定位
		driver.find_element_by_id('')
		
		#可以通過元素的name來定位,name在HTML中不唯一
		driver.find_element_by_name('')
		
		#可以通過元素的class來定位,class在HTML中不唯一
		driver.find_element_by_class_name('')
		
		#可以通過元素的標籤名來定位,tag_name在HTML中不唯一
		driver.find_element_by_tag_name('')
		
		#可以通過元素標籤對之間的文字資訊來定位,文字資訊在HTML中有可能是唯一的
		driver.find_element_by_link_text('')

		#可以通過元素標籤對之間的一部分文字資訊來定位,在HTML中有可能並不唯一
		driver.find_element_by_partial_link_text('')
		
		#可以通過XPATH方式來定位(可以通過FF、Chrome、Edge除錯工具快速生成xpath)
		#可以傳入在HTML中的絕對定位、元素屬性、運算子driver.find_element_by_xpath('')
		
		#XPATH可以通過絕對路徑方式來定位
		driver.find_element_by_xpath('/html/body/div/div[3]/div/imput')
		
		#xpath可以利用元素屬性方式來定位
		#元素屬性方式:'//' + '標籤名或*萬用字元' + '[@' + '要使用的元素屬性' + '=' + '要定位元素屬性的值'
		driver.find_element_by_xpath("//input[@id='su']")
		
		#xpath可以同時使用元素屬性方式+絕對路徑方式來定位,通過屬性較多的父級找到子級
		driver.find_element_by_xpath("//input[@id='su']/input")
		
		#xpath可以使用邏輯運算子+元素屬性+路徑方式來定位,適合一個屬性不能唯一定位元素的情況下 
		driver.find_element_by_xpath("//input[@name='su' and @class='btclass']/div/input")
		
		#可以通過CSS方式來定位元素[.class, #id, *, tag_name, 層級, [屬性='值']] 等組合定位
		driver.find_element_by_css_selector('')
		
		#可以通過By方式來定位元素,find_element(By.定位方式, 定位相關引數)
		#使用前要匯入By類:from selenium.webdriver.common.by import By
		#定位方式:ID,NAME,CLASS_NAME,TAG_NAME,LINK_TEXT,PARTIAL_LINK_TEXT,XPATH,CSS_SELECTOR
		driver.find_element(By.ID,'kw')
		
		
		#定位一組元素,通常用於以下場景:1.批量操作元素;2.先獲取一組元素,再從這組物件中過濾出需要操作的元素
		#在這裡其實是有點問題的,比如id,這個東西在一個HTML裡面是唯一的不能有id重複的元素,定位出來永遠只有一個,用find_elements_by_id()其實有點違背了HTML的規則了,除非有些特殊情況下是想以一個數組形式來獲取一個元素,但這是很浪費資源的一件事,目前想不出來什麼情況下可以用到
		driver.find_elements_by_id('kw')
		driver.find_elements_by_name('su')
		driver.find_elements_by_class_name('su')
		driver.find_elements_by_tag_name('kw')
		driver.find_elements_by_link_text('kw')
		driver.find_elements_by_partial_link_text('su')
		driver.find_elements_by_xpath('su')
		driver.find_elements_by_css_selector('su')
		#可從裡面使用pop()指定某一個元素來操作
		driver.find_elements_by_class_name('class').pop(-1).click()


	def teatDown(self):
		self.driver.quit()

#操作類
class DemoAboutOperate(unittest.testcase):
	def setUp(self):
		self.driver = webdriver.Firefox()
		self.base_url = 'http://baidu.com'
	
	
	#操作視窗、瀏覽器(改變視窗大小,瀏覽器前進、後退、重新整理)
	def testOperateWithWindow(self):
		driver = self.driver
		driver.get(self.base_url)
		
	#控制瀏覽器window
		#控制瀏覽器大小set_window_size(width, height),用於自適應移動端時可以設定
		driver.set_window_size(480, 720)
		
		#用於PC端一般希望全屏顯示可以使用maximize_window(),不需要引數
		driver.maximize_window()
		
		#控制瀏覽器後退,back()
		driver.back()
		
		#控制瀏覽器前進
		driver.forward()
		
		#控制瀏覽器重新整理
		driver.refresh()
		
		#獲取當前所有開啟的視窗的控制代碼,返回陣列形式,window_handle 
		handle2 = driver.window_handles
		
		#獲取當前/焦點視窗的控制代碼,current_window_handle
		handle1 = driver.current_window_handle

		#切換到指定視窗控制代碼的視窗,switch_to.window(handle)
		driver.switch_to.window(handle1)
	
	
	#操作元素
	def testOperateWithElement(self):
		driver = self.driver
		driver.get(self.base_url)
		
		
	#簡單元素操作(清除內容、傳送寫入內容、點選、提交)
		#清空內容,用於避免文字輸入框中輸入造成與預設提示語拼接
		driver.find_element(By.ID, 'kw').clear()
		
		#模擬按鍵輸入,模擬鍵盤向輸入框輸入內容,傳送鍵盤按鍵,模擬檔案上傳
		driver.find_element(By.ID, 'kw').send_keys('value')
		
		#模擬單擊,用於可以被單擊的物件,可以包括按鈕,文字/圖片連結,複選框,單選框,下拉框等
		driver.find_element(By.ID, 'su').click()
		
		#模擬提交操作,可以用於搜尋框模擬搜尋按鈕效果,提交一個按鈕,有時可以和click方法互動使用
		driver.find_element(By.ID, 'kw').submit()
		
		
	#WebElement介面其他常用方法(獲得元素尺寸、元素文字內容、屬性的值、返回是否可見)
		#可返回元素的尺寸{'width':value1, 'height':value2} size沒有()
		driver.find_element(By.ID, 'kw').size
		
		#可返回元素的文字內容,text沒有()
		driver.find_element(By.ID, 'kw').text
		
		#可返回元素的屬性
		driver.find_element(By.ID, 'kw').get_attribute('type')
		
		#可返回該元素是否使用者可見 true/false
		driver.find_element(By.ID, 'kw').is_displayed()
		
		
	#滑鼠事件(模擬單擊、懸停、雙擊、拖放、提交)
		#使用前要匯入 ActionChains 類:from selenium.webdriver.common.action_chains import ActionChains
		#呼叫 ActionChains 需要把瀏覽器驅動作為引數傳入 
		#格式:ActionChains (瀏覽器驅動).操作(元素)
		
		#變數化元素(個人新增步驟,避免以下例子程式碼過長,才變數化,非必要)
		element1 = driver.find_element(By.ID, 'kw')
		element2 = driver.find_element(By.ID, 'su')
		
		#模擬滑鼠右鍵操作,context_click()需要傳入點選的元素
		ActionChains(driver).context_click(element1)
		
		#模擬滑鼠懸停,move_to_element()
		ActionChains(driver).move_to_element(element1)
		
		#模擬滑鼠雙擊操作
		ActionChains(driver).double_click(element1)
		
		#模擬滑鼠拖放操作 drag_and_drop(source, target) 拖動的源元素,釋放到目標元素上
		ActionChains(driver).drag_and_drop(element1, element2)
		
		#perform() 執行 ActionChains 中儲存的行為,可以理解為對整個操作的提交動作
		ActionChains(driver).context_click(element1).perform()
		
		
	#鍵盤事件(鍵盤按下操作,可單鍵可組合鍵)
		#使用鍵盤上按鍵前要匯入 Keys 類:from selenium.webdriver.common.keys import Keys
		#send_keys(Keys.yourself_keyboard [,'組合鍵'])
		#BACK_SPACE刪除\SPACE空格\TAB製表\ESCAPE回退鍵\ENTER回車鍵\CONTROL控制鍵\F1\F2...\組合鍵
		#輸入刪除鍵
		element1.send_keys(Keys.BACK_SPACE)
		#輸入空格鍵
		element1.send_keys(Keys.SPACE)
		#輸入Tab鍵(製表)
		element1.send_keys(Keys.TAB)
		#輸入回退鍵
		element1.send_keys(Keys.ESCAPE)
		#輸入回車鍵
		element1.send_keys(Keys.ENTER)
		#輸入組合鍵Ctrl+a
		element1.send_keys(Keys.CONTROL, 'a')
		#輸入F1鍵
		element1.send_keys(Keys.F1)
		
		
	#獲得驗證資訊
		#來驗證是否符合預期結果,可以從title、URL、text來驗證執行結果的對錯
		#獲取當前頁面的標題,title
		title1 = driver.title
		#獲取當前頁面的URL,current_url
		now_url1 = driver.current_url
		#獲取元素的文字,text
		now_text = driver.text
		
		
	#設定元素等待
		#顯示等待: WebDriverWait().until() 某個條件成立時繼續,否則在達到最大時長時丟擲超時異常TimeoutException
		#使用前需要匯入WebDriverWait:from selenium.webdriver.support.ui import WebDriverWait
		#WebDriverWait(driver, timeout, check_per_secondtime, ignored_exceptions=None)
		#ignored_exceptions超時後丟擲的異常,預設丟擲NoSuchElementException異常
		#WebDriverWait通常會搭配until(method, value) /until_not(method, value)使用
		element3 = WebDriverWait(driver, 5, 0.5).until(EC.presence_of_element_located((By.ID, 'kw')))
		# EC excepted_condition類提供的預期條件判斷方法
		#{title_is:判斷當前頁面的標題是否等於預期, title_contains:判斷當前頁面的標題是否包含預期字串, presence_of_element_located:判斷元素是否被加在DOM樹裡,包含不可見元素, visibility_of_element_located:判斷元素的定位是否非隱藏且寬高不為0(引數是定位), visibility_of:判斷元素是否非隱藏且寬高不為0(引數是定位好的元素), presence_of_all_element_located:判斷至少有一個元素存在於DOM樹中, text_to_be_present_in_element:判斷元素中的text是否包含預期字串, text_to_be_present_in_element_value:判斷元素的value屬性是否包含預期字串, frame_to_be_available_and_switch_to_it:判斷該表單是否可以切換進去,可以則切換並返回True, invisibility_of_element_located:判斷元素是否不存在於DOM樹或不可見, element_to_be_clickable:判斷元素是否可見且可點選, staleness_of:等到一個元素從DOM樹中移除, element_to_be_selected:判斷元素是否被選中(下拉列表), element_selection_state_to_be:判斷元素的選中狀態是否符合預期, element_located_selection_state_to_be:判斷元素的定位的選中狀態是否符合預期, alert_is_present:判斷頁面上是否存在alert} is_displayed()元素是否可見
		
		#隱式等待:implicitly_wait()設定全域性固定等待時長s,找不到時才等待,超出時長報異常
		driver.implicitly_wait(10)
		
		#sleep休眠方法:設定某一次等待的固定時長,然後繼續,單位為秒
		#使用前需要匯入sleep: from time import sleep
		sleep(8)
		
		
	#表單操作(切換表單、跳出表單、切回主文件)
		#frame/iframe表單巢狀頁面時使用,需要切換iframe和frame兩個頁面
		#switch_to.frame() 可以傳入id\name,也可以傳入定位物件,或者傳入frame的下標index從0開始
		#傳入id\name此處有問題,和HTML有關,同一個HTML文件中id和name可以相同,這樣傳參會出現問題,建議還是傳入定位物件
		#傳入定位物件
		element4 = driver.fine_element_by_xpath('/html/body/div/li/frame')
		driver.switch_to.frame(element4)
		#傳入id/name
		driver.switch_to.frame('if')
		#傳入下標index
		driver.switch_to.frame(2)
		
		#switch_to.parent_content() 跳出當前一級的表單,預設是匹配最近的 switch_to.frame()方法,該方法有可能不可用
		driver.switch_to.parent_content()
		
		#切到父frame,有多層frame時有用,但一般這種巢狀多層的frame是有影響到效能的問題的,可以讓開發改進
		driver.switch_to.parent_frame()
		
		#切換到主文件,或者理解為最外層的頁面
		driver.switch_to.default_content()
		
		
	#switch_to家族的其他(切到當前焦點元素、切到當前alert、confirm、prompt框、切到某個瀏覽器視窗)
		#driver.switch_to.active_element.send_keys('selenium') 返回當前取得焦點的webdriver物件,然後操作
		#driver.switch_to.alert.send_keys()  返回瀏覽器的alert物件,可對瀏覽器alert、confirm、prompt框操作
		#driver.switch_to.window(window_name)  切到某個瀏覽器視窗
		
		
	#警告框的處理 先使用switch_to.alert()定位到警告框 包括 alert\confirm\prompt
		#accept() 接受現有警告框
		driver.switch_to.alert().accept()
		
		#dismiss() 解散現有警告框
		driver.switch_to.alert().dismiss()
		#也可以定位到警告框之後,返回警告框的文字資訊 text , 或者傳送文字資訊 send_keys(message)
	
	
	#如果要使用本地的HTML文件進行測試,get的時候傳入檔案地址
	def testWithLocalhostHTMLFile(self):
		driver = self.driver
		
		#使用本地檔案進行測試
		#在當前py同個路徑時使用'file:///' + os.path.abspath('xxx.html')
		#使用非當前路徑的檔案時'file:///' + 檔案的絕對路徑如'F:\doc\find.html'
		#os.path.abspath('file.html')用於獲取當前路徑下的檔案,需要提前匯入os類
		#import os
		file_path = 'file:///' + os.path.abspath('result.html')
		driver.get(file_path)
	
	
	#上傳檔案
	def testWithUploadFile(self):
		driver = self.driver
		driver.get(self.base_url)
		
		#send_keys方法完成,傳入檔案的絕對路徑,適用input標籤,可以避免操作windows控制元件
		driver.find_element_by_id('su').send_keys('E:\\disk\file.txt')
		#Autolt方法實現
		#執行autoit的指令碼來實現
	
	
	def tearDown(self):
		self.driver.quit()

class 


if __name__ == '__main__':
	testunit = unittest.TestSuite()
	testunit.addTest(DemoAboutSelect('test'))