【W(wǎng)ebUIAuto】1.web端UI自動化

環(huán)境安裝步驟

1.準(zhǔn)備好python環(huán)境
2.準(zhǔn)備selenium環(huán)境
3.下載瀏覽器對應(yīng)版本的driver,點(diǎn)擊下載chromedriver
4.driver配置環(huán)境變量
5.在python里導(dǎo)入對應(yīng)依賴

selenium IDE 錄制

seleniumIDE官網(wǎng)

點(diǎn)擊進(jìn)入擴(kuò)展程序

selenium 用例編寫

python-selenium文檔
selenium常用等待

  • 直接等待
    time.sleep(3) 等待3秒
  • 隱式等待
    driver.implicitly_wait(5) 輪訓(xùn)查找(默認(rèn)0.5)元素是否出現(xiàn),如果沒出現(xiàn)就拋出異常
  • 顯示等待
from selenium import webdriver
from selenium.webdriver.common.by import By
class TestWebUi:
    def setup(self):
        self.driver = webdriver.Chrome()
        self.driver.get("http://www.baidu.com")
        # 隱式等待
        self.driver.implicitly_wait(5)
    def teardown(self):
        self.driver.close()

    def test_search(self):

        self.driver.find_element(By.ID,'kw').send_keys('騰訊課堂')
        self.driver.find_element(By.ID, 'su').click()
        self.driver.find_element(By.LINK_TEXT,'騰訊課堂【官方】_騰訊課堂【官方】騰訊課堂官網(wǎng)').click()
          #顯示等待
        WebDriverWait(self.driver,10).until(expected_conditions.presence_of_all_elements_located((By.LINK_TEXT,'官方')))
        
web控件定位,操作
  • 操作
    輸入: self.driver.find_element(By.ID,'kw').send_keys('騰訊課堂')
    點(diǎn)擊: self.driver.find_element(By.ID, 'su').click()
  • 定位-xpath
    作用域(appium、selenim)
表達(dá)式 結(jié)果
/div/input[1] 取div子元素的第一個(gè)input元素
/div/input[last()] 取div子元素的最后個(gè)input元素
/div/input[last()-1] 取div子元素的倒數(shù)第二個(gè)input元素
/div/input[position()<3] 取div子元素的前兩個(gè)book元素
//div[@class='classname'] 得到所有div元素,且這些元素?fù)碛兄禐閏lassaname的class屬性
/div/input[price>35] 得到所有div元素下的所有input,且其中的price元素值大于35,且這些元素?fù)碛兄禐閏lassaname的class屬性
nodename 選取此節(jié)點(diǎn)的所有子節(jié)點(diǎn)
/ 從根節(jié)點(diǎn)選取
// 匹配選擇當(dāng)前節(jié)點(diǎn),不考慮其位置
. 選取當(dāng)前節(jié)點(diǎn)
.. 選取當(dāng)前節(jié)點(diǎn)父節(jié)點(diǎn)
@ 選取屬性
  • 定位-css selector
    appium 原生元素不能用 css selector定位
表達(dá)式 結(jié)果 例子描述
.class .intro 選擇 class = "intro"的所有元素
.id .idname 選擇 id= "idname"的所有元素
* * 選擇所有元素
element div 選擇所有<div>元素
element,element div,p 選擇所有<div>元素和所有<p>元素
element element div p 選擇<div>元素內(nèi)部的所有<p>元素
element>element div>p 選擇父元素為<div>元素的所有<p>元素
element+element div+p 選擇緊接在<div>元素之后的所有<p>元素
css select f方式
web控件交互

Actions

  • 官方文檔
  • ActionChains:執(zhí)行鼠標(biāo)點(diǎn)擊、雙擊、右鍵、拖拽事件
  • TouchActions: 模擬PC移動端、點(diǎn)擊、滑動、拖拽、多點(diǎn)觸控操作
  • 執(zhí)行原理,調(diào)用actionChains方法,不會立即執(zhí)行,而是講所有的操作,按順序放在一個(gè)隊(duì)列里,調(diào)用perform()方法時(shí),隊(duì)列中的事件會依次執(zhí)行
  • 基本用法
  1. 生成一個(gè)動作 action = ActionChains(driver)
  2. 動作添加方法1 action.方法1
  3. 調(diào)用perform()方法執(zhí)行(action.perform())
  • 寫法
  1. 鏈?zhǔn)綄懛? ActionChains(driver).move_to_element(element).click(element).perform()
  2. 分布寫法
    action= ActionChains(driver)
    action.move_to_element(element)
    actions.click(element)
    actions.perform()

ActionChains示例

class TestActionChains():
    def setup(self):
        self.driver = webdriver.Chrome()
        self.driver.get("http://sahitest.com/demo/clicks.htm")
        self.driver.implicitly_wait(5)

    def teardown(self):
        self.driver.close()

    def test_case_click(self):
        element_click = self.driver.find_element(By.XPATH,'//input[@value="click me"]')
        element_dbclick = self.driver.find_element(By.XPATH,'//input[@value="dbl click me"]')
        element_rclick = self.driver.find_element(By.XPATH,'//input[@value="right click me"]')
        action = ActionChains(self.driver)
        action.click(element_click)
        action.double_click(element_dbclick)# 雙擊操作
        action.context_click(element_rclick)# 右擊操作
        action.perform()
        sleep(3)
    def test_move_to(self):
        # 光標(biāo)移動到某個(gè)元素
        self.driver.get("http://www.baidu.com")
        element = self.driver.find_element(By.ID,'s-usersetting-top')
        action = ActionChains(self.driver)
        action.move_to_element(element)
        action.perform()
        sleep(2)
    def test_dragdrog(self):
        self.driver.get("http://sahitest.com/demo/dragDropMooTools.htm")
        ele1= self.driver.find_element(By.ID,'dragger')
        ele2= self.driver.find_element(By.XPATH,"/html/body/div[2]")
        action = ActionChains(self.driver)
        action.drag_and_drop(ele1,ele2).perform()
        action.click_and_hold(ele1).release(ele2).perform()
        action.click_and_hold(ele1).move_to_element(ele2).perform()
        sleep(3)
    def test_keys(self):
        # 模擬鍵盤操作
        self.driver.get("http://sahitest.com/demo/label.htm")
        ele = self.driver.find_element(By.XPATH,"/html/body/label[1]/input")
        ele.click()
        action = ActionChains(self.driver)
        action.send_keys("username").pause(1)# 添加一秒等待
        action.send_keys(Keys.SPACE).pause(1)
        action.send_keys("張三").pause(1)
        action.send_keys(Keys.BACK_SPACE).perform()
        sleep(3)

TouchAction
官方文檔
TouchAction 示例滑動頁面

class TestTouchAction():
    def setup(self):
        option = webdriver.ChromeOptions()
        option.add_experimental_option('w3c', False)
        self.driver = webdriver.Chrome(options=option)
        self.driver.get("http://baidu.com")
        self.driver.implicitly_wait(5)

    def teardown(self):
        self.driver.close()

    def test_scrollbottom(self):
        ele_se = self.driver.find_element(By.ID, 'kw')
        ele_se.send_keys('selenium測試')
        ele_c =  self.driver.find_element(By.ID, 'su')

        action = TouchActions(self.driver)
        action.tap(ele_c)
        action.perform()
        # 滑動頁面
        action.scroll_from_element(ele_se, 0, 1200).perform()
        sleep(3)
表單
  • 表單定義
    1. 表單是一個(gè)包含表單元素的區(qū)域
    2. 表單元素是允許用戶在表單中輸入信息的元素
    3. 表單使用標(biāo)簽<form>定義
    4. 操作表單元素步驟
      a. 首先要定位到表單元素
      b. 然后操作元素(點(diǎn)擊、輸入、清空)
class TestFrom:
    def setup(self):
        self.driver = webdriver.Chrome()
        self.driver.get("http://testerhome.com/account/sign_in")
        self.driver.implicitly_wait(5)

    def teardown(self):
        self.driver.close()

    def test_form(self):
        self.driver.find_element(By.ID, 'user_login').send_keys('abcdee')
        self.driver.find_element(By.ID, 'user_password').send_keys('12312312')
        self.driver.find_element(By.XPATH, '//*[text()[contains(.,"記住")]]').click()
        self.driver.find_element(By.XPATH, '//*[@id="new_user"]/div[4]/input').click()
        sleep(3)

多窗口,frame處理

  • selenium 處理多窗口
  1. 多個(gè)窗口識別
    a. 獲取當(dāng)前窗口句柄:driver。current_window_handle
    b. 在獲取所有窗口句柄 driver。window_handles
    c. 判斷是否想要操作的窗口,如果是就可以對窗口進(jìn)行操作,如果不是跳轉(zhuǎn)到另外一個(gè)窗口,對另一個(gè)窗口操作 driver.switch_to_window

  2. 多個(gè)窗口切換

from time import sleep

from selenium.webdriver.common.by import By

from web_ui.base import Base
class TestWindows(Base):
    def test_windows(self):
        self.driver.get("http://www.baidu.com")
        self.driver.find_element(By.LINK_TEXT, '登錄').click()

        self.driver.find_element(By.XPATH, '//*[text()[contains(.,"立即注冊")]]').click()
        # 獲取當(dāng)前所有窗口
        windows = self.driver.window_handles
        print(windows)
        # 切換到最最新打開的窗口
        self.driver.switch_to_window(windows[-1])
        self.driver.find_element(By.ID,'TANGRAM__PSP_4__userName').send_keys('username')
        self.driver.find_element(By.ID,'TANGRAM__PSP_4__phone').send_keys('13200001234')
        sleep(2)
        #切換到 最開始的窗口
        self.driver.switch_to_window(windows[0])

        self.driver.find_element(By.ID,'TANGRAM__PSP_11__footerULoginBtn').click()
        self.driver.find_element(By.ID, 'TANGRAM__PSP_11__userName').send_keys('abcdef')
        sleep(2)

  • frame 分類,frameset、frame、iframe
    frameset 不會影響正常定位,可以用id、name 定位
    frame和iframe 需要特殊操作

  • selenium處理 frame

  1. 多個(gè)frame識別
    有兩種,嵌套的、非嵌套
  2. 多個(gè)frame之前切換
    driver.switch_to.frame() # 根據(jù)ID或者index切換frame
    driver.switch_to_default_content() # 切換到默認(rèn)frame
    driver.switch_to.parent_frame() # 切換到父級frame
    未嵌套iframe
    driver.switch_to_frame('frame id')
    driver.switch_to_frame('frame-index')無id用索引處理,從0開始
   def test_frame(self):
        self.driver.get('http://runoob.com/try/try.php?filename=jqueryui-api-droppable')
        # 根據(jù) id切換frame
        self.driver.switch_to_frame('iframeResult')
        print(self.driver.find_element(By.ID, 'draggable').text)
        #切換到 父級frame
        self.driver.switch_to.parent_frame()
        # 切換到默認(rèn)frame
        self.driver.switch_to.default_content()
        print(self.driver.find_element(By.ID, 'submitBTN').text)
多瀏覽器處理
from  selenium import  webdriver
import os
class Base():
    def setup(self):
        browser = os.getenv('browser')
        if browser == 'firefox':
            self.driver = webdriver.firefox()
        elif browser == 'headless':
            self.driver = webdriver.PhantomJS()
        else:
            self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(5)
        self.driver.maximize_window()
    def teardown(self):
        self.driver.quit()
執(zhí)行java script
    def test_javascript(self):
        # 通過js滑動到頁面底部
        self.driver.get("http://www.baidu.com")
        self.driver.find_element(By.ID,'kw').send_keys('selenium測試')
        # 通過 js 獲得元素
        ele = self.driver.execute_script("return document.getElementById('su')")
        ele.click()
        self.driver.execute_script("document.documentElement.scrollTop=100")
        sleep(2)
        # sleep(1)
        print(self.driver.execute_script('return document.title;return JSON.stringify(performance.timing)'))
        for code in [
            'return document.title','return JSON.stringify(performance.timing)'
        ]:
            print(self.driver.execute_script(code))
  • 修改日期
    def test_wirte_time(self):
        self.driver.get('http://12306.cn/index')
        # 執(zhí)行js讓輸入框可編輯
        time_ele = self.driver.execute_script('a=document.getElementById("train_date");a.removeAttribute("readonly")')
        sleep(3)
        # 寫入值
        self.driver.execute_script('a=document.getElementById("train_date");a.value = ("2021-08-09")')
        #  清楚元素的,readonly屬性
        self.driver.execute_script("arguments[0].removeAttribute('readonly')",findElement(self.driver,'xm_cpsj'))
        self.driver.execute_script(f"$arguments[0].attr('value','{cpsj}');",findElement(self.driver,'xm_cpsj'))

        sleep(2)
        # 打印元素  value
        print(self.driver.execute_script("return document.getElementById('train_date').value"))
  • 文件上傳彈窗處理
    # 上傳圖片
    def test_upload(self):
        self.driver.get("http://www.baidu.com")
        self.driver.find_element(By.CLASS_NAME, 'soutu-btn').click()
        sleep(2)
        self.driver.find_element(By.CLASS_NAME, 'upload-pic').send_keys('x.jpg')
        sleep(3)
    def test_alter(self):
        self.driver.get('http://runoob.com/try/try.php?filename=jqueryui-api-droppable')
        self.driver.switch_to_frame('iframeResult')
        drag = self.driver.find_element(By.ID,'draggable')
        drop = self.driver.find_element(By.ID, 'droppable')
        action = ActionChains(self.driver)
        action.drag_and_drop(drag,drop).perform()
        sleep(2)
        print('點(diǎn)擊 alter 確認(rèn)')
        self.driver.switch_to_alert().accept()
        self.driver.switch_to.default_content()
        self.driver.find_element(By.ID,'submitBTN').click()
        sleep(3)

PageObject設(shè)計(jì)模式 PageObject原理及六大原則

  • 公共方法代表頁面提供的功能
  • 不暴露頁面元素信息
  • 不在頁面內(nèi)斷言(在業(yè)務(wù)層做斷言)
  • 方法應(yīng)該返回別的 PageObject或用于斷言的數(shù)據(jù)
  • 不要給整個(gè)頁面建模
  • 同樣的行為不同的結(jié)果,應(yīng)建模成不同的方法
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 摘要: 之前用Selenium做UI自動化測試從初學(xué)到熟練碰到過很多問題,這里就不一一細(xì)說了,所以把最基本的操作都...
    Vicky_習(xí)慣做唯一閱讀 11,626評論 1 23
  • 一、自動化測試所屬分類(站在代碼可見度角度分類) 1. 黑盒測試(功能測試)2. 灰盒測試(接口測試)3. 白盒測...
    MAVIS_42bf閱讀 1,033評論 0 0
  • 參考鏈接: web自動化測試教案:http://www.cnblogs.com/zidonghua/p/74300...
    永杰gg閱讀 1,228評論 0 0
  • 一、概念 互聯(lián)網(wǎng)軟件的開發(fā)和發(fā)布,已經(jīng)形成了一套標(biāo)準(zhǔn)流程,最重要的組成部分就是持續(xù)集成(Continuous in...
    __65a0閱讀 1,060評論 0 4
  • 完善融寶UI自動化框架 繼續(xù)總結(jié)自動化測試API "29.模擬鍵盤單個(gè)按鍵/組合按鍵操作," # import t...
    公子小白123閱讀 1,164評論 0 1

友情鏈接更多精彩內(nèi)容