1. 程式人生 > 其它 >APP自動化實戰之混合應用測試

APP自動化實戰之混合應用測試

什麼是混合應用?
一句話:Html5頁面 + 原生頁面。
混合應用不是在app上直接寫HTML5的頁面,而是把HTML5頁面放進一個webview的原生控制元件中。

什麼是webview?
webview是原生應用的一個控制元件,可以巢狀h5頁面,另外還有可以巢狀圖片的imageview等。webview能做到和web頁面進行互動的功能。

拓展:安卓原生元件有哪些?
imageview,用於顯示圖片

textview,用於顯示文字

layout,相當於html中的


button,用於顯示按鈕

  • checkbox,多選框:
  • switch,開關:
  • ratingbar,評分條
  • seekbar,拖動條
  • toast,彈出後瞬間消失的提示框:
  • webview,用於顯示網頁,相當於html中iframe,網頁中又套了個網頁

如何快速辨別當前頁面為webview?

  • 通過uiautomator2或appium inspector等原生app定位工具,當定位到整個頁面的class為:android.webkit.WebView,即可證明當前頁面為webview;

  • 通過頁面的一些特徵識別。如當前頁面左上角有一個X等

  • 用uc-Devtools、chrome-inspect等H5開發者工具可檢視到app資訊,則證明當前進入了webview頁面。

測試web app的前提

apk中設定setWebContentsDebuggingEnabled=True。這裡如果不設定或者設定為false時,H5的開發者工具是無法檢測到當前的H5頁面的。所以得找開發開啟webview除錯模式。

webview測試步驟

  • 通過uiautomatorviewer、appium inspector等原生app開發者工具定位原生應用的控制元件時,發現class為android.view.View,或其他一些方法判斷出當前是H5頁面;
  • 通過uc-Devtool等H5開發工具定位到web頁面;
  • 此時已從原生環境進入webview中的H5環境,原生app開發者工具就失去了作用,得用H5開發者工具進行元素定位。但在程式碼中,並不能立刻在H5中進行元素定位、元素操作,得進行上下文切換,即從原生環境切換至webview中的H5環境(類似於selenium中切換iframe):

1.從原生環境切換至webview中的H5環境:driver.switch_to.context(context)(這裡的context是webview的context)
2.從H5切回到原生:driver.switch_to.context(None)

  • 在desired_capacities中提供web瀏覽器的驅動:
    • chromedriverExecutableDir:r"瀏覽器驅動所在目錄"
    • chromedriverExecutable:r"瀏覽器驅動所在路徑,得包括驅動"
  • 在H5頁面執行元素定位、元素操作

程式碼實戰

場景分析

我們要實現的場景如下。
首先,進入首頁後,點選師資團隊。這裡需要注意的是,這個元素並不能通過id進行定位。

我們在找id時,可以發現有8個元素的id都是同一個:

id不行,content-desc也為空,那麼只有通過uiautomator或xpath方式進行定位,兩種方式的定位都有一個相似點,就是找元素的一個或多個獨有的屬性。
這裡我們使用xpath進行定位。那麼看下它有哪些獨特的屬性。可以看到這裡的text是獨一無二的:

接下來通過xpath表示式,可找到的元素只有一個:

定位師資團隊元素並點選後,就跳轉到了師資團隊頁面。在這個頁面中,在看APP Source中,可以看到有一個webview,說明這個原生頁面中嵌套了一個h5頁面:

那麼原生app的開發者工具就不管用了,我們要接著轉到H5的開發者工具來進行元素定位。這裡我們用的是谷歌瀏覽器自帶的inspect。
在瀏覽器中輸入:chrome://inspect,即可進入H5開發者工具的介面。在這裡檢測到了H5的頁面:

點選inspect後,進入了H5的控制檯。這裡我們要定位檸檬班這個元素並打印出來。可以看到,它是一個h1標籤,它的文字是檸檬班,我們可以通過這兩個特徵使用xpath進行定位:
//h1[text()=“檸檬班”]

場景分析走完之後,接著就可以開始寫程式碼了:

程式碼

import time

from appium import webdriver
from appium.webdriver.common.mobileby import MobileBy
from appium.webdriver.common.multi_action import MultiAction
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

package = "com.lemon.lemonban"
caps = {
    "platformName": "Android",
    "deviceName": "emulator-5554",
    "appPackage": package,
    "appActivity": ".activity.MainActivity",
    "automationName": "UiAutomator1",
    "chromedriverExecutableDir":r"C:\chromedriver"
}

# 初始化客戶端
driver = webdriver.Remote(
    command_executor='http://127.0.0.1:4723/wd/hub',
    desired_capabilities=caps,
)

# 隱式等待
driver.implicitly_wait(20)

#定位元素並點選
element = driver.find_element_by_xpath('//*[@text="師資團隊"]')
element.click()

#列印當前頁面的上下文環境
print(driver.contexts)

#切換至webview的context
driver.switch_to.context('WEBVIEW_' + package)

#定位webview中的元素
element_in_webview = driver.find_element_by_xpath('//h1[text()="檸檬班"]')
print(element_in_webview)

這裡需要注意的是,在原生頁面中,文字text是元素的屬性,所以要用@text=“XXX”;而到了H5,文字text就成了函式,所以要用text()=“XXX”。

chromedriver版本問題

在執行時報了個錯:

['NATIVE_APP', 'WEBVIEW_com.lemon.lemonban']
Traceback (most recent call last):
  File "C:/Users/rainstar/PycharmProjects/pyproject/APP_project_v0/混合應用.py", line 36, in <module>
    driver.switch_to.context('WEBVIEW_' + package)
  File "C:\Users\rainstar\PycharmProjects\pyproject\venv\lib\site-packages\appium\webdriver\switch_to.py", line 34, in context
    self._driver.execute(MobileCommand.SWITCH_TO_CONTEXT, {'name': context_name})
  File "C:\Users\rainstar\PycharmProjects\pyproject\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\Users\rainstar\PycharmProjects\pyproject\venv\lib\site-packages\appium\webdriver\errorhandler.py", line 31, in check_response
    raise wde
  File "C:\Users\rainstar\PycharmProjects\pyproject\venv\lib\site-packages\appium\webdriver\errorhandler.py", line 26, in check_response
    super().check_response(response)
  File "C:\Users\rainstar\PycharmProjects\pyproject\venv\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: An unknown server-side error occurred while processing the command. Original error: No Chromedriver found that can automate Chrome '52.0.2743'. See https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/web/chromedriver.md for more details.

Process finished with exit code 1

報錯的原因是,沒有與52.0.2743版本相匹配的chromedriver。所以得下載一個52.0.2743版本的chromedriver。
那麼遇到chromedriver版本不相容的問題該怎麼解決呢?

  • 首先,先在H5開發者工具中檢視app所需要的chromedriver版本:

接著去https://npm.taobao.org/mirrors/chromedriver/下載一個版本一致的chromedriver即可。
在這裡並沒有高版本匹配低版本的規則,下載高版本的chromedriver照樣還是會報錯,所以得下跟app要求一致的版本。

————————————————
版權宣告:本文為CSDN博主「weixin_44885027」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/weixin_44885027/article/details/113531688