ui自動化筆記 selenium_webdriver,ui自動化框架(web)


Selenium學習筆記

selenium webdriver是業界公認ui自動化測試的標准,其封裝的api可以對瀏覽器的任何地方進行操作

selenium2.0和selenium3.0的區別?

  3.0任何瀏覽器的廠商都支持selenium,他們只要給予驅動就可以了,2.0只支持火狐和谷歌

webdriver工作原理?

  通過webdriver創建一個瀏覽器服務,remote server(底層服務).啟動腳本后會通過驅動打開瀏覽器,並綁定端口,不同瀏覽器端口不同

  client端創建一個session來請求rmote server並發送restful請求,server解析后,完成代碼的操作返回結果

如何定位html中的元素?

  1.查看並分析html中所需定位的元素

  2.找到對於當前頁面來說唯一的屬性

css selector與xpath區別?

  其有着不同的定位方式,擇優選擇最佳的定位方式

  xpath可以通過角標定位到一些css selector定位不到的元素

  css selector基於html,能快速取到值,xpath底層要從xml轉換成html對代碼執行效率會受到影響,還依賴轉化的准確度  

xpath定位  xpath是xml的路徑語言

  /html/body/div/div/div/ul/li/a[@href="/xpath/xpath_syntax.asp"]  從祖先html開始查找定位元素,可以不用寫角標  注意:一個/表示其子元素查找,//表示模糊匹配查找

  //*  獲取頁面所有元素

  //*[@id='xxxx']  @表示以id屬性定位

  //input[@id='xxx']  input表示以input標簽名進行定位

  //input[1]  如果出現不唯一的請求可以通過角標的形式取,注意角標從1開始

  //input[1]/input[1]  層級定位方式,/表示當前層級內

  //input[@id='xxx' and @class='xxx']  #邏輯定位方法,通過多種屬性確立唯一

  xpath(定位方法盡量少用層級定位,如果修改了層級位置會導入所有定位都失效,以屬性定位為主)

css selector定位  html的css選擇器標簽定位

  #i1  表示查找id屬性為i1的元素

  .i1  表示查找class屬性為i1的屬性

  [name='xxx']  表示查找name屬性定位

  input[name='xxx']  可以通過標簽名進行檢索來縮小范圍

  input#name  查找input標簽中id為name的元素

  input[name='xxx'][id='xxx'][class='xxx']  input標簽下多屬性確立唯一

  input>input[id='xxx']  >表示遞進一層

  input[name^='xxx']  ^支持前者模糊匹配

  input[name$='xxx']  $支持后者模糊匹配

  input[name*='xxx']  *表示包含,只要包含字段中的內容都可能會被匹配上

  css selector不支持角標取值,所以我們要靈活運用xpath和css selector結合

 

  由於css是html原始支持,還可以支持很多定位方法,以上一些我們在日常通常都可以用了,如進一步學習可以參考

    http://www.w3school.com.cn/cssref/css_selectors.asp

 

selenium webdriver api-代碼定位,基礎操作

  pip install selenium  

  selenium驅動安裝 https://www.cnblogs.com/RainBol/protected/p/10065838.html

from selenium import webdriver
# 驅動程序,用chrome,當然還可以用firefox,ie驅動
driver = webdriver.Chrome()
# 獲取網址
driver.get("http://www.baidu.com")
# 設置頁面寬長
driver.get_window_size()# 獲取瀏覽器的大小
driver.set_window_size(400, 800)# 定義指定頁面長寬 driver.maximize_window()#最大頁面長寬 # 截圖
driver.get_screenshot_as_file('xx.jpg')# 在當前腳本的同一級目錄生成瀏覽器截屏的圖片文件(其他底層還有三個截圖api) # 八種單數定位方式(都需要確立唯一) driver.find_element_by_name()  #通過name屬性定位 driver.find_element_by_id()  #通過id屬性定位 driver.find_element_by_class_name()  #通過class屬性定位 driver.find_element_by_link_text("")  #文案定位 driver.find_element_by_partial_link_text()  #包含文案定位 driver.find_element_by_css_selector()  #css selector定位 driver.find_element_by_tag_name()  #標簽名定位,如果有多個,獲取的是html頁面中第一個 driver.find_element_by_xpath(".//*[@id='kw']").clear()  #xpath定位
# 八種復數定位方法
  (不常用,單數的element加s就是復數,所有復數形式都返回一個列表,列表順序按html從上到下,如果元素下還有子元素,可以通過元素進行再次定位)
# 其他兩種定位
  driver.find_element('id','i1')  #單數形式,參數id表示通過id定位,i1表示元素值為i1進行定位
  driver.find_elemnets('id','i1')  #復數形式,返回列表
#
提交表單 driver.find_element_by_xpath(".//[@id='kw']").send_keys("selenium") driver.find_element_by_xpath(".//*[@id='kw']").submit() # 控制瀏覽器前進后退 driver.back() driver.forward() # 刷新頁面 driver.refresh() # 瀏覽器關閉 driver.close() # 關閉一個頁面也叫關閉一個tag,當頁面只有一個tag的時候就直接關閉瀏覽器了 driver.quit() # 退出驅動也就是關閉瀏覽器

等待,操作瀏覽器,懸浮

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains  # 引入actionchains類
from selenium.webdriver.common.keys import Keysfrom selenium.common.exceptions import NoSuchElementException
from time import ctime
from selenium.webdriver.support.select import Select
import time

browser = webdriver.Chrome()  # 打開網頁驅動
#等待  一般等待分為三種,系統等待,隱士等待,顯示等待

# 隱式等待10s
 """
 implicitly_wait():隱式等待
 當使用了隱士等待執行測試的時候,如果 WebDriver沒有在 DOM中找到元素,將繼續等待,超出設定時間后則拋出找不到元素的異常
 換句話說,當查找元素或元素並沒有立即出現的時候,隱式等待將等待一段時間再查找 DOM,默認的時間是0
 一旦設置了隱式等待,則它存在整個 WebDriver 對象實例的聲明周期中,隱式的等到會讓一個正常響應的應用的測試變慢,
 它將會在尋找每個元素的時候都進行等待,這樣會增加整個測試執行的時間,所以在ui自動化實現比較雞肋
 """
browser.implicitly_wait(10)

# 顯示等待 ↓
'''
顯示等待  ==>顯示等待為selenium的核心,用好它能增加自動化的執行速度,提高效率
自設置了顯示等待,在設置后到指定設置時間內,會按設置的步長等待,直到找到元素或超時
'''

browser.get("https://www.baidu.com")  # 打開網址
print("設置瀏覽器寬1200、高1400顯示")
browser.set_window_size(1200, 1400)
from selenium.webdriver.support.ui import WebDriverWait   from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By
element = WebDriverWait(browser, 5, 0.5).until( EC.presence_of_element_located((By.ID, "kw")) )
  #browser, 5, 0.5分別表示對象,超時時間,步長   
  #By.ID,"kw"分別表示通過id屬性,定位的值

# 系統等待 ↓
'''
  time.sleep(5)
  系統等待用在測試調試階段
'''
time.sleep(
2)

title
= browser.title # title:用於獲得當前頁面的標題。 print(title) # 打印當前頁面的title now_url = browser.current_url # 打印當前頁面URL # current_url:用戶獲得當前頁面的URL。 print(now_url) size = browser.find_element_by_id("kw").size # 找到輸入框的頁面屬性 print(size) text = browser.find_element_by_id("kw").text # 獲取搜索條目的文本信息 print(text) attribute = browser.find_element_by_id("kw").get_attribute('type') # 返回元素屬性值 print(attribute) result = browser.find_element_by_id("kw").is_displayed() # 查看是否可見 print(result) browser.find_element_by_id("kw").clear() # 清除內容 # 如果超出10s拋出異常 try: print(ctime()) search_test = browser.find_element_by_id("kw").send_keys("seleniuma") # 輸入seleniuma time.sleep(2) except NoSuchElementException as e: print(e) finally: print(ctime()) # 鍵盤按鍵 browser.find_element_by_id("kw").send_keys(Keys.BACK_SPACE) browser.find_element_by_id("su").send_keys(Keys.ENTER) time.sleep(2) browser.refresh() # 刷新 time.sleep(2) browser.find_element_by_id("kw").clear() search_test2 = browser.find_element_by_id("kw").send_keys("webdriver") # 輸入webdriver time.sleep(2) browser.find_element_by_id('su') # 提交表單 # 鼠標懸浮 adove = browser.find_element_by_class_name("pf") # 找到adove ActionChains(browser).move_to_element(adove).perform() # 方法 :定位到執行元素鼠標懸停操作 browser.find_element_by_class_name("setpref").click() # 找到下拉條中元素進行點擊操作,click:點擊事件 time.sleep(2) # 懸停下拉框+顯示條數 # search03 = browser.find_element_by_link_text("設置") # ActionChains(browser).move_to_element(search03).perform() # time.sleep(2) # 搜索結果顯示條數 sel = browser.find_element_by_xpath("//select[@id='nr']") Select(sel).select_by_value('50') # 顯示50條 time.sleep(5) browser.find_element_by_link_text("保存設置").click() time.sleep(2) # 返回原來的樣子 browser.switch_to.alert.accept() time.sleep(2) search03 = browser.find_element_by_link_text("設置") ActionChains(browser).move_to_element(search03).perform() time.sleep(2) av = browser.find_element_by_link_text("搜索設置") av.click() time.sleep(2) browser.find_element_by_id("nr").click() time.sleep(2) # 搜索結果顯示條數 sel = browser.find_element_by_xpath("//select[@id='nr']") Select(sel).select_by_value('10') # 顯示10條 # …… time.sleep(2) browser.find_element_by_link_text("保存設置").click() time.sleep(2) browser.close()

等待擴展 

  WebDriverWait參數

def __init__(self, driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None):
    pass
#driver:類的實例
#timeout:超時時間
poll_frequency=POLL_FREQUENC:#調用until或until_not中的方法的間隔時間,默認值0.5秒
ignored_exceptions=None:#忽略的異常,如果在調用until或until_not的過程中拋出這個元組中的異常,
則不中斷代碼,繼續等待,如果拋出的是這個元組外的異常,則中斷代碼,拋出異常。默認只有NoSuchElementException
#以上是構造函數,下面介紹方法,總共兩個until和until_not
def until_not(self, method, message=''):#當某元素消失或什么條件不成立則繼續執行
    pass
def until(self, method, message=''):#當某元素出現或什么條件成立則繼續執行
    pass
#method:在等待期間,每隔一段時間調用這個傳入的方法,直到返回值不是False    
#message: 如果超時,拋出TimeoutException,將message傳入異常

  等待操作

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
driver.maximize_window()

# 判斷某個元素進入dom樹中,可以是不可見的元素,找到返回WebElement對象屬性
WebDriverWait(driver, 10, 1).until(EC.presence_of_element_located((By.CSS_SELECTOR, '#kw')))

# 判斷某組元素進入dom樹中,可以是不可見的元素,找到返回WebElement對象列表
WebDriverWait(driver, 10, 1).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#kw')))

# 判斷title是否正確,返回布爾值
WebDriverWait(driver, 10, 1).until(EC.title_is(u"百度一下,你就知道"))

# 包含判斷title是否正確,返回布爾值
WebDriverWait(driver, 10, 1).until(EC.title_contains('百度'))

# 判斷某個元素是否被加到了dom樹里,並不代表該元素一定可見,如果定位到就返回WebElement
WebDriverWait(driver, 10, 1).until(EC.presence_of_element_located((By.ID, 'kw')))

# 判斷是否至少有1個元素存在於dom樹中,如果定位到就返回列表
WebDriverWait(driver, 10, 1).until(EC.visibility_of_all_elements_located((By.ID, 'kw')))

# 判斷某個元素是否可見
WebDriverWait(driver, 10, 1).until(EC.visibility_of(driver.find_element(by=By.ID, value='kw')))

# 判斷某個元素是否別添加到dom里並可見,可見代表元素可顯示且寬和高都大於0
WebDriverWait(driver, 10, 1).until(EC.visibility_of_element_located((By.ID, 'kw')))

# 判斷某個元素是否包含預期字符串,返回布爾值
WebDriverWait(driver, 10, 1).until(EC.text_to_be_present_in_element((By.XPATH, "//*[@id='u1']/a[8]"), u'設置'))

# 判斷指定元素的屬性值中是否包含預期字符串,返回布爾值
WebDriverWait(driver, 10, 1).until(EC.text_to_be_present_in_element_value((By.CSS_SELECTOR, '#su'), '百度一下'))

# 判斷該frame是否可以switch進,如果可以返回True並且switch進去,否則返回False
WebDriverWait(driver,10,1).until(EC.frame_to_be_available_and_switch_to_it())


# 判斷某個元素中是否可見並且是enable的,代表可點擊
WebDriverWait(driver, 10, 1).until(EC.element_to_be_clickable((By.XPATH, "//*[@id='u1']/a[8]"))).click()

# 等待某個元素從dom樹中移除WebDriverWait(driver,10,1).until(EC.staleness_of(driver.find_element(By.ID,'su')))
# 判斷某個元素是否被選中了,一般用在下拉列表
WebDriverWait(driver, 10).until(EC.element_to_be_selected(driver.find_element(By.XPATH, "//*[@id='nr']/option[1]")))

# 判斷某個元素的選中狀態是否符合預期
WebDriverWait(driver, 10).until(
    EC.element_selection_state_to_be(driver.find_element(By.XPATH, "//*[@id='nr']/option[1]"), True))

# 判斷某個元素的選中狀態是否符合預期
WebDriverWait(driver, 10).until(EC.element_located_selection_state_to_be((By.XPATH, "//*[@id='nr']/option[1]"), True))

# 判斷頁面上是否存在alert,如果有就切換到alert並返回alert的內容
instance = WebDriverWait(driver, 10).until(EC.alert_is_present())

文件上傳,cookie,滾動條,js執行

from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get('http://sahitest.com/demo/php/fileUpload.htm')
driver.find_element_by_name("file").send_keys("C:\\Users\\admin\Desktop\\test.txt")#選擇本地文件上傳
driver.find_element_by_name("submit").click()
driver.quit()

driver = webdriver.Chrome()
driver.set_window_size(1920,1080)
driver.get("http://www.youdao.com")
# 獲得cookie信息
cookie = driver.get_cookies()
# 將獲得cookie的信息打印
print(cookie)
print("向cookie的name 和value中添加會話信息")
driver.add_cookie({'name': 'key-aaaaaaa', 'value': 'value-bbbbbb'})
# 遍歷cookies中的name 和value信息並打印,當然還有上面添加的信息
for cookie in driver.get_cookies():
    print("%s -> %s" % (cookie['name'], cookie['value']))
driver.get("http://www.testclass.net/selenium_python/javascript/")
#滾動條操作
js = "window.scrollTo(100,700);"  #scrollTo(x,y)
#執行js代碼
driver.execute_script(js)  
time.sleep(3)
driver.quit()

 警告框處理

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
browser = webdriver.Firefox()
browser.implicitly_wait(10)
browser.get("https://www.baidu.com")
time.sleep(2)
link = browser.find_element_by_link_text("設置")
ActionChains(browser).move_to_element(link).perform()
browser.find_element_by_link_text("搜索設置").click()
time.sleep(2)
browser.find_element_by_link_text("保存設置").click()
time.sleep(2)
print (browser.switch_to_alert().text)      #先打印再接受警告框
ar = browser.switch_to.alert.accept()        #點擊確定警告框
dis = browser.switch_to.alert.dismiss()    #點擊取消警告框
browser.quit()

多窗口切換

from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")

# 獲取當前對象的窗口句柄
sreach_windows = driver.current_window_handle

driver.find_element_by_link_text('登錄').click()

driver.find_element_by_link_text("立即注冊").click()

# 獲得當前所有打開的窗口的句柄,以列表形式返回
all_handles = driver.window_handles # 進入注冊窗口
for handle in all_handles:
    if handle != sreach_windows:#遍歷如果不屬於之前的那個頁面就執行下面操作
        driver.switch_to.window(handle)#跳轉到另一個頁面
        print('now register window!')
        driver.find_element_by_name("userName").send_keys('這個是用戶名')
        driver.find_element_by_id('TANGRAM__PSP_3__phone').send_keys('123456')
        time.sleep(2)
# 以上過於復雜,可以參考以下兩行
last_handle = driver.windows_handles[-1]# 表示拿到列表最后一個值,也就是最后一個頁面的窗口句柄
driver.switch_to.window(last_handle)# 讓瀏覽器跳到剛剛指定頁面  
# 兩個頁面之間tab切換 driver.switch_to.window(all_handles[0]) time.sleep(5) driver.switch_to.window(all_handles[1]) time.sleep(5) driver.switch_to.window(all_handles[0]) driver.quit()

 判斷checkbox勾選

off = driver.find_element_by_id('xxx')# 定位到checkbox勾選元素
print(on.is_selected())# 判斷是否勾選,返回布爾值

iframe定位

driver.switch_to.frame('xxx')# 切換進入到當前html下的frame層
driver.switch_to.parent_frame()# 返回上一層
driver.switch_to.default_content()# 直接返回最外層

拖拽指令

from selenium.webdriver.common.action_chains import ActionChains
s1 = driver.find_element_by_id('xxx')# s1為推拽起始元素
t1 = driver.find_element_by_class_name('xxx')# t1位推拽目標元素
ActionChains(driver).drag_and_drop(s1,t1).perform()

 

UI自動化框架(web)

我們為什么要做ui自動化測試?

  項目基於穩定的前提,由於老功能在原先基礎要增加新功能點,為了避免在舊業務上有過多資源來回歸測試,可以用ui自動化來對其業務進行回歸測試,不適用與新業務

我們為什么要做ui自動化框架?

  目前互聯網公司ui自動化框架現狀:

    1.運行不穩定

    2.維護麻煩,源碼修改后需要重新定位

    3.自動化測試用例與頁面數據腳本寫在一起,排查時業務混亂

  自動化框架解決思路:

    1.顯示等待框架封裝
    2.PO思想(page object) 每個頁面為一個類class,每個功能為一個函數def,web端和app端都以這種思想為主
    3.自動化測試用例與頁面數據腳本分離

  所以可以基於selenium webdriver原生代碼,unittest單元測試api,報告,截圖,日志和現狀結合實現的框架能很好的幫助我們做好框架

框架中怎么為業務邏輯做斷言?

  1.判斷元素消失,代表業務成功

  2.判斷另一個元素出現,且該元素一定是唯一的

有哪些框架值得我們使用?

  我個人推薦蟲師大大的框架,pyse,poium,還有seleniumbase等都是優秀的改良版測試框架,內置增加了api足夠我們使用了,當然還有一些很好用的其他框架,歡迎推薦

 

版權聲明:本文原創發表於 博客園,作者為 RainBol 本文歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則視為侵權。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM