Appium等待機制--強制等待、隱式等待、顯式等待

書接上回,Appium高級操作--其他操作-CSDN博客文章瀏覽閱讀182次,點贊6次,收藏7次。書接上回Appium高級操作--從源碼角度解析--模擬復雜手勢操作-CSDN博客。 https://blog.csdn.net/fantasy_4/article/details/146162851主要講解了Appium的一些高級操作,比如基于ActionChain類的,操作系統API的方法等,便于解決比較復雜的場景下的手勢模擬。不過在自動化的過程中,經常會出現尋找查找元素時間過長,等待時間設置不合理導致腳本執行時間過程,最終的結果就是自動化運行的速度不如'手工'操作。為了解決上述問題,本篇文章主要講解一下Appium的等待機制

1.影響頁面加載時長的因素

做UI自動化的同學可能多數都會遇到這樣的問題,執行跳轉頁面后再去定位,經常會提示找不到元素,造成找不到元素的原因除了有元素定位本身的問題之外,還可能的原因是頁面本身的加載時長過長,那影響頁面加載時長的因素有哪些呢?

  • 移動端性能

市面上出現生產使用的移動端各不相同,不同的配制,不同的機型,不同的系統,甚至不同的操作系統版本,因此在這些設備上安裝同一款軟件就會產生不同的加載時長。如果調試腳本時使用的是一款配置較好的手機,而實際運行腳本的是另外的配置較差的手機,就會出現明明調試的時候沒問題,正式運行就會出錯。

  • 服務端性能

如果執行自動化的服務端還部署著其他服務,比如缺陷管理工具、代碼管理工具等,這樣服務端存在大量并發用戶請求,就會造成自動化執行時會花費更多的時間才能相應。

  • 網絡因素

如果被測試APP中的Web頁面包含大量圖片,或者請求中存在低劣無效的代碼就會產生大量的數據請求,這是網絡的穩定至關重要。

2.強制等待

所謂強制等待,就是在執行自動化的過程中加上一個強制的等待時間,等待時間結束后期望要跳轉的頁面能夠加載完畢,如果沒有那可能還是要調整時間。

通常使用Python time模塊的time.sleep(s) 來實現

優點:調試代碼時,能夠便于我們觀察腳本的執行情況

缺點:強制等待會導致執行腳本的時間不一致,設置的等待時間參差不齊,尤其是腳本很多時,就會造成腳本越執行越慢。

那么有沒有一種更智能的等待方式呢?能夠實現找到元素就立刻進行下一步操作,如果找不到元素就進行等待呢?

3.隱性等待

隱性等待就能夠完美解決上面提出的問題。

Appium的隱性等待繼承了Selenium的implicitly_wait()方法。

driver.implicitly_wait(5) # 隱性等待5s

優點:可以很智能判斷是否需要執行相應等待時長,一旦設置就會實例化整個會話的生命周期

缺點:會減緩測試速度(尤其是在需要查找某個元素不存在時的用例,會平白浪費時間等待查找該元素是不是存在),而且會干擾顯性等待,不建議使用隱形等待和顯性等待混用

4.顯性等待

顯性等待能夠更精細化的定制一些執行條件,等到條件滿足會后在進行下一步操作。

Appium并沒有引入Selenium的WebDriverWait類,因此要使用顯性等待,只能從Selenium中引入,主要由以下兩部分實現顯性等待

1)Selenium中的WebDriver類:定義超時時間、輪詢頻率等

2)Expected_conditions模塊:提供一些預期條件作為測試腳本進行后續操作的判斷依據

  • 顯性等待整體語法結構

WebdriverWait(dirver, 超時時間,輪詢頻率, 忽略異常).until(可執行方法,超時后返回的信息)

上面代碼的含義:每隔一段時間,一定頻次,就會調用可執行方法,直到方法返回True,如果超時則返回超時后的信息。

注意until中的可執行方法必須是可以調用的,即這個對象一定有__call__()方法

  • WebDriverWait類源碼分析

def __init__(self,driver: D,timeout: float,poll_frequency: float = POLL_FREQUENCY,ignored_exceptions: Optional[WaitExcTypes] = None,
):"""Constructor, takes a WebDriver instance and timeout in seconds.
?Attributes:----------driver- Instance of WebDriver (Ie, Firefox, Chrome or Remote) ora WebElement
?timeout- Number of seconds before timing out
?poll_frequency- Sleep interval between calls- By default, it is 0.5 second.
?ignored_exceptions- Iterable structure of exception classes ignored during calls.- By default, it contains NoSuchElementException only.

WebDriverWait類創建對象可以傳入4個參數:

  • driver:WebDriver實例化-必傳

  • timeout:超時時間-必傳

  • poll_frequency:輪詢頻率-非必傳

  • ignored_exceptions:可忽略異常-非必傳

WebDriverWait類提供兩個方法until()until_not(),兩個方法傳參相同

  • method:可以調用方法-必傳,

  • str: 異常信息-非必傳

兩個方法的含義不同:

?untiluntil_not
等待邏輯等待條件變為 True等待條件變為 False
適用場景等待元素出現或滿足特定條件。等待元素消失或不滿足特定條件。
異常處理如果條件未變為 True,拋出 TimeoutException如果條件未變為 False,拋出 TimeoutException
返回值返回滿足條件的對象(如元素)無返回值(僅等待條件變為 False

(使用的Selenium是配套Appium-Python-Client一起下載的,版本是 4.29.0,其中until_not的方法注釋(定義部分)有錯誤)如下圖

  • Expected_conditions模塊

Expected_conditions模塊是selenium提供的各種預期條件,Expected_conditions有多種方法,黑體字相對比較常用

方法描述
title_is(title: str)判斷頁面的title和預期title是否一致,一直則返回True,否則返回False
title_contains(title: str)判斷頁面的title是否包含預期title是否一致,大小寫敏感一直則返回True,否則返回False
presence_of_element_located(locator: Tuple[str, str])用于檢查某個元素是否存在于DOM中,但不一定可見,一旦找到元素則返回WebElement
presence_of_all_elements_located(locator: Tuple[str, str])用于檢查所有元素是否存在,如果存在返回所有匹配的元素的列表,否則報錯
url_matches(pattern: str)檢查當前driver的url是否包含字符串,包含返回True,不包含返回False
url_to_be(url: str)檢查當前driver的url與預期值是否完全匹配,匹配返回True,否則返回False
url_changes(url: str)檢查當前url和預期值是否一致,不一致返回True,一直返回False
url_contains(url: str)檢查當前driver的url是否包含字符串,包含返回True,不包含返回False
visibility_of(element: WebElement)參數是WebElement,判斷元素是否在當前頁面的DOM中并可見,若是返回True,否則返回False
visibility_of_element_located(locator: Tuple[str, str] )參數是locator,判斷元素是否在當前頁面的DOM中并可見,若是返回True,否則返回False
visibility_of_any_elements_located(locator: Tuple[str, str])至少能定位到一個可見元素,是返回列表 否則報錯
visibility_of_all_elements_located(locator: Tuple[str, str] )找到所有符合條件的可見元素,是返回列表 否則報錯
invisibility_of_element_located(locator: Union[WebElement, Tuple[str, str]] )判斷不可見元素是否存在
invisibility_of_element(element: Union[WebElement, Tuple[str, str]] )判斷元素是都不可見
staleness_of(element: WebElement)判斷刷新后,元素是否仍然在DOM中,如果在返回False,否則返回True
frame_to_be_available_and_switch_to_it(locator: Union[Tuple[str, str], str])判斷frame_locator是否存在,存在則跳轉到對應frame并返回True,否則返回False
text_to_be_present_in_element(locator: Tuple[str, str], text_: str)判斷text是否出現在元素中
text_to_be_present_in_element_value(locator: Tuple[str, str], text_: str )判斷text是否出現在元素的value屬性中
text_to_be_present_in_element_attribute(locator: Tuple[str, str], attribute: str, text: str )判斷text是否出現在元素的屬性中
element_to_be_clickable(mark: Union[WebElement, Tuple[str, str]] )檢查元素是否可見并可以被單擊并且單擊
element_to_be_selected(element: WebElement)入參為WebElement,被定位的元素是否是被選中的,返回布爾值
element_located_to_be_selected(locator: Tuple[str, str])入參為locator,被定位的元素是否是被選中的,返回布爾值
element_selection_state_to_be(element: WebElement, is_selected: bool)檢查給定元素是否是被選中的
element_located_selection_state_to_be(locator: Tuple[str, str], is_selected: bool )查找元素并檢查指定的選擇狀態是否處于該狀態的期望,返回布爾值
new_window_is_opened(current_handles: List[str])傳入當前窗口的句柄,判斷是否有新窗口打開,返回布爾值
number_of_windows_to_be(num_windows: int)判斷窗口數量是否符合預期
alert_is_present()判斷是否有alert,如果有,切換到alert,否則返回False
  • 代碼演示

    from appium import webdriver
    from appium.options.android import UiAutomator2Options
    from appium.webdriver.common.appiumby import AppiumBy
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions
    ?
    desired_caps = {"platformName": "Android","deviceName": "XXXXXXXXXXXXX","appPackage": "com.sankuai.movie","appActivity": "com.sankuai.movie.MovieMainActivity","automationName": "UiAutomator2"
    }
    ?
    print("Desired Capabilities: ", desired_caps)
    ?
    driver = webdriver.Remote("http://localhost:4723", options=UiAutomator2Options().load_capabilities(desired_caps))
    ?
    ?
    try:agree_id = "com.sankuai.movie:id/cyf"ele1 = WebDriverWait(driver, 10).until(expected_conditions.presence_of_element_located((AppiumBy.ID, agree_id)))ele1.click()my_id = 'com.sankuai.movie:id/b50'ele2 = WebDriverWait(driver, 10).until(expected_conditions.invisibility_of_element_located((AppiumBy.ID, my_id)))# WebDriverWait(driver, 10).until_not()ele2.click()ele4 = WebDriverWait(driver,10).until(expected_conditions.element_to_be_clickable((AppiumBy.ID, 'com.sankuai.movie:id/b50')))ele4.click()
    ?
    except Exception as e:raise e
    ?
    finally:# 關閉 Appium 會話driver.quit()
    ?
  • 自定義等待條件

就是在expected_conditions模塊不滿足個需求的情況下,可以使用lambda表達式來自定義等待條件。

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
?
ele3 = WebDriverWait(driver, 10).until(lambda driver: driver.find_elements(AppiumBy.ID, 'com.sankuai.movie:id/b50'))
ele3.click()

5.總結三種等待區別

?強制等待隱性等待顯性等待
實現方式time.sleep(3)driver.implicitly_wait(5)Webdriver類+expected_conditions模塊
靈活程度不管是否找元素,必須等待響應時間找到元素則不等待,否則等待在固定之間
生命周期當前行整個會話每個條件需要單獨設置
使用場景腳本調試頁面加載時間相對固定的全局等待場景,不建議跟顯性等待混用動態頁面或需要等待特定條件的復雜場景,建議多使用

下一章介可能會講解一些關于自動化框架搭建相關內容,可以期待一下哦~

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/73283.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/73283.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/73283.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【架構藝術】Go語言微服務monorepo的代碼架構設計

近期因為項目架構升級原因,筆者著手調研一些go項目monorepo的代碼架構設計,目標是長期把既有微服務項目重要的部分都轉移到monorepo上面,讓代碼更容易維護,協作開發更加方便。雖然經驗不多,但既然有了初步的調研&#…

深入解析 JVM —— 從基礎概念到實戰調優的全鏈路學習指南

文章目錄 一、為什么要學習 JVM?1. 面試必備與技能提升2. 性能優化與問題診斷3. 編寫高質量代碼 二、JVM 基礎概念與體系結構1. JVM 簡介2. JDK、JRE 與 JVM 三、JVM 內存模型1. 線程私有區2. 線程共享區 四、類加載機制與雙親委派1. 類加載過程2. 雙親委派模型3. 動…

前端及后端實現csv文件下載功能

方法一、 前端內容: const url window.URL.createObjectURL(new Blob([res.data])); const link document.createElement(a); link.href url; const fileNameDateTime getFormattedDateTime(); const filename "用戶提現列表"fileNameDateTime.csv…

QT中委托QStyledItemDelegate的使用

目錄 一、子類化委托 二、委托方法實現 1)createEditor 2)setEditorData 3)setModelData 4)updateEditorGeometry 三、委托使用 四、總結 Qt的數據容器控件采用模型/視圖(model/view)架構設計。模型用于存放控件的數據,視圖則用于顯示編輯數據,而委托則是…

OpenCV實現視頻背景提取

在計算機視覺領域,背景減除(Background Subtraction)是一種常用的技術,用于從視頻序列中提取前景對象。 背景減除的核心思想是通過建模背景,然后將當前幀與背景模型進行比較,從而分離出前景對象。 OpenCV…

NFS實驗配置筆記

NFS NFS服務 nfs,最早是Sun這家公司所發展出來的,它最大的功能就是可以透過網絡,讓不同的機器,不同的操作系統,進行實現文檔的共享。所以你可以簡單的將他看做是文件服務器。 實驗準備 ①先準備一個服務器端的操作…

C語言【數據結構】:理解什么是數據結構和算法(啟航)

引言 啟航篇,理解什么是數據結構和算法 在 C 語言編程領域,數據結構和算法是兩個核心且緊密相關的概念 一、數據結構 定義 數據結構是指相互之間存在一種或多種特定關系的數據元素的集合(比如數組),它是組織和存儲數…

Vue.js 3 的設計思路:從聲明式UI到高效渲染機制

目錄 一、聲明式UI與虛擬DOM的靈活性 二、渲染器:虛擬DOM到真實DOM的橋梁 三、組件的本質與實現 四、編譯與運行時的協同優化 五、性能與可維護性的權衡 總結 Vue.js 3 作為新一代前端框架,其設計理念在聲明式UI描述、虛擬DOM優化、組件化架構…

深度學習|MAE技術全景圖:自監督學習的“掩碼魔法“如何重塑AI基礎

一、引言:深度學習的困境與自監督的曙光 深度學習(Deep Learning)無疑是當今人工智能領域基礎中的基礎。從圖像識別到自然語言處理(NLP),它在無數任務中展現了卓越性能。例如,在安防監控中&…

深度學習正則化技術之權重衰減法、暫退法(通俗易懂版)

一、影響模型泛性的因素有?什么是正則化技術?有什么用? 通常,影響模型泛化能力的因素有: 可調節參數的個數:可調節的參數過少,會造成模型過于簡單,欠擬合;過多&#xf…

爬蟲逆向:Unicorn 詳細使用指南

文章目錄 1. Unicorn 介紹1.1 Unicorn 的特點1.2 Unicorn功能2. 安裝 Unicorn2.1 安裝 Python 綁定2.2 安裝 Unicorn 核心庫3. Unicorn 的基本使用3.1 初始化模擬器3.2 映射內存3.3 寫入代碼3.4 設置寄存器3.5 執行代碼3.6 讀取寄存器4. Unicorn 的高級功能4.1 鉤子函數4.2 異常…

【SpringBoot】實現登錄功能

在上一篇博客中,我們講解了注冊頁面的實現。在此基礎上會跳轉到登錄頁面,今天給大家帶來的是使用 SpringBoot,MyBatis,Html,CSS,JavaScript,前后端交互實現一個登錄功能。 目錄 一、效果 二、…

【小白向】Ubuntu|VMware 新建虛擬機后打開 SSH 服務、在主機上安裝vscode并連接、配置 git 的 ssh

常常有人問VMware-Tools裝了也復制粘貼不了怎么辦,這個東西影響因素太多了,具體解決辦法你們可以參考一下:【經驗】VMware|虛擬機只能使用鼠標無法使用鍵盤、裝不了或裝了VMware-Tools無法復制粘貼的可能解決辦法_增強型鍵盤驅動程…

mingw工具源碼編譯

ming-w64 mingw編譯生成的庫,需要mingw的lib文件支持。 https://github.com/mingw-w64/mingw-w64 使用msys2的bash git checkout v8.0.3 ./configure --disable-dependency-tracking --targetx86_64-w64-mingw32 mingw32-make.exe -j4 修改makefile中的make 改成mi…

LSTM方法實踐——基于LSTM的汽車銷量時序建模與預測分析

Hi,大家好,我是半畝花海。本實驗基于汽車銷量時序數據,使用LSTM網絡(長短期記憶網絡)構建時間序列預測模型。通過數據預處理、模型訓練與評估等完整流程,驗證LSTM在短期時序預測中的有效性。 目錄 一、實驗…

Stable Diffusion教程|快速入門SD繪畫原理與安裝

什么是Stable Diffusion,什么是煉丹師?根據市場研究機構預測,到2025年全球AI繪畫市場規模將達到100億美元,其中Stable Diffusion(簡稱SD)作為一種先進的圖像生成技術之一,市場份額也在不斷增長&…

Webpack構建流程詳解優化前端性能\Dev-Server與Proxy\網絡攻擊\HMR

簡版 核心流程圖 根據,Webpack的構建流程分為初始化、編譯和輸出三個階段。初始化階段讀取配置、加載插件、實例化Compiler。編譯階段(構建依賴關系)涉及Compiler類的運行,生成Compilation對象,處理模塊依賴。輸出階…

《Transformer如何進行圖像分類:從新手到入門》

引言 如果你對人工智能(AI)或深度學習(Deep Learning)感興趣,可能聽說過“Transformer”這個詞。它最初在自然語言處理(NLP)領域大放異彩,比如在翻譯、聊天機器人和文本生成中表現出…

Java --- 根據身份證號計算年齡

介紹 根據身份證號計算年齡 Java代碼 /*** 根據身份證號計算年齡* param birthDateStr* return*/public static int calculateAge(String birthDateStr) {try {birthDateStrbirthDateStr.substring(6,68);// 定義日期格式SimpleDateFormat sdf new SimpleDateFormat("…

零成本搭建Calibre個人數字圖書館支持EPUB MOBI格式遠程直讀

文章目錄 前言1.網絡書庫軟件下載安裝2.網絡書庫服務器設置3.內網穿透工具設置4.公網使用kindle訪問內網私人書庫 前言 嘿,各位書蟲們!今天要給大家安利一個超級炫酷的技能——如何在本地Windows電腦上搭建自己的私人云端書庫。亞馬遜服務停了&#xff…