Appium UiAutomator2驱动:平台相关的mobil

2023-08-12  本文已影响0人  Domibaba

除了标准的W3C API接口,Uiautomator2还提供了一系列扩展接口来支持Android平台相关的操作。本文所有测试代码的前提是已经安装Appium和相关环境(例如JDKAndroid SDKAVD模拟器),可以参考Appium环境搭建

文件管理

1 传输文件到被测设备

接口参数说明:

参数名称 参数类型 参数是否必须提供 描述 举例说明
remotePath string yes 文件存储到被测设备上的全路径,如果被测设备的文件已经存在,会覆盖已经存在的文件。 /sdcard/foo.bar
payload string yes 待传输文件内容,使用Base64编码。(Pythonwebdriver提供的push_file接口可以直接指定待传输文件的全路径。) QXBwaXVt

举例:(假定待传输文件为/tmp/file_test

# -*- coding: utf-8 -*-

import pytest
import base64
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.appium_service import AppiumService

# 开启服务端
APPIUM_HOST = '127.0.0.1'
APPIUM_PORT = 4723
@pytest.fixture(scope="session")
def start_appium_service():
 server = AppiumService()
 server.start(args=['--address', APPIUM_HOST, '-p', str(APPIUM_PORT)], timeout_ms=60000)
 yield server
 server.stop()

# 创建客户端到服务端的会话
def create_appium_session_by_api(custom_opts = None, appium_host = APPIUM_HOST, appium_port = APPIUM_PORT):
 options = UiAutomator2Options()
 if custom_opts is not None:
 options.load_capabilities(custom_opts)
 return webdriver.Remote(f'http://{appium_host}:{appium_port}', options=options)

# !发送文件到被测设备
def test_push_file(start_appium_service):
 custom_opts = {
 "appium:avd": "testPhone",
 }

 driver = create_appium_session_by_api(custom_opts)
 # 直接指定待传输文件的本地路径
 driver.push_file(destination_path="/sdcard/file_test", source_path="/tmp/file_test")

 # 通过base64编码后进行传输
 binary_data = 'hello android'.encode('utf-8')
 driver.push_file(destination_path="/sdcard/file_test_base64", base64data=f"{base64.b64encode(binary_data).decode('utf-8')}")
 driver.quit()

在被测设备下,可以看到文件已经传输成功。

2 从被测设备获取文件

接口参数说明:

参数名称 参数类型 参数是否必须提供 描述 举例说明
remotePath string yes 被测设备上文件的全路径,如果被测设备的文件不存在,会抛出异常。 /sdcard/foo.bar

接口调用会返回文件内容,基于Base64的编码。

# !获取被测设备上的文件
def test_pull_file(start_appium_service):
 custom_opts = {
 "appium:avd": "testPhone",
 }

 driver = create_appium_session_by_api(custom_opts)
 data = 'hello android'
 driver.push_file(destination_path="/sdcard/file_test_base64", base64data=f"{base64.b64encode(data.encode('utf-8')).decode('utf-8')}")

 # 读取被测设备上文件
 base64_content = driver.pull_file("/sdcard/file_test_base64")
 assert (base64.b64decode(base64_content)).decode('utf-8') == data
 driver.quit()

3 从被测设备获取文件夹

接口参数说明:

参数名称 参数类型 参数是否必须提供 描述 举例说明
remotePath string yes 被测设备上文件夹的全路径,如果被测设备的文件不存在,会抛出异常。 /sdcard/folder/

接口调用会返回文件夹zip压缩后内容,并基于Base64的编码。因此下面的例子,在获取到内容后,首先要使用base64进行内容还原,然后将还原的数据流存到文件中,并使用zipfile库来解压zip格式的压缩包。

# !获取被测设备上的文件夹
def test_pull_folder(start_appium_service):
 custom_opts = {
 "appium:avd": "testPhone",
 }

 driver = create_appium_session_by_api(custom_opts)
 data = 'hello android'
 driver.push_file(destination_path="/sdcard/Download/file_test_base64", base64data=f"{base64.b64encode(data.encode('utf-8')).decode('utf-8')}")

 # 读取被测设备上文件夹
 base64_zip_folder_content = driver.pull_folder("/sdcard/Download/")

 # 解析base64的内容,并存储成文件
 zip_folder_content = (base64.b64decode(base64_zip_folder_content))
 with open("/tmp/test.zip", "wb") as f:
 f.write(zip_folder_content)

 # 解压文件夹
 with zipfile.ZipFile("/tmp/test.zip", 'r') as zip_f:
 zip_f.extractall("/tmp")

 assert os.path.exists("/tmp/Download/file_test_base64")

 file_content = ""
 with open("/tmp/Download/file_test_base64") as f:
 file_content = f.read()
 assert file_content == data

 driver.quit()
上一篇下一篇

猜你喜欢

热点阅读