Appium自动化
1.Appium 用途和特点
Appium
是一个移动 App (手机应用)自动化工具。
手机APP 自动化有什么用?
-
自动化完成一些重复性的任务
比如微信客服机器人
-
爬虫
就是通过手机自动化爬取信息。
为什么不通过网页、HTTP 爬取呢?有的系统没有网页,也不方便通过HTTP爬取
-
自动化测试
很多企业里面有这样的需求
Appium
自动化方案的特点:
-
开源免费
-
支持多个平台
iOS (苹果)、安卓 App 的自动化都支持。
-
支持多种类型的自动化
支持 苹果、安卓 应用 原生界面 的自动化
支持 应用 内嵌 WebView 的自动化
支持 手机浏览器 中的 web网站自动化
支持 flutter 应用的自动化
-
支持多种编程语言
像 Selenium 一样, 可以用多种编程语言 调用它 开发自动化程序。
自动化原理
我们先来看一下Appium自动化的原理图
这图是不是很眼熟?
对啦,和Selenium 原理图很像。因为 Appium自动化架构就是借鉴的Selenium。
大家看看这幅图, 包含了 3个主体部分 : 自动化程序、Appium Server、移动设备
-
自动化程序
自动化程序是由我们来开发的,实现具体的 手机自动化 功能。
要发出具体的指令控制手机,也需要使用 客户端库。
和Selenium一样,Appium 组织 也提供了多种编程语言的客户端库,包括 java,python,js, ruby等,方便不同编程语言的开发者使用。
我们需要安装好客户端库,调用这些库,就可以发出自动化指令给手机。
-
Appium Server
Appium Server 是 Appium 组织开发的程序,它负责管理手机自动化环境,并且转发 自动化程序的控制指令 给 手机,并且转发 手机给 自动化程序的响应消息。
-
手机设备
我们这里说的手机设备,其实不仅仅是手机,包括所有 苹果、安卓的移动设备,比如:手机、平板、智能手表等。
为了直观方便的讲解,这里我们简称: 手机
当然手机上也包含了 我们要自动化控制的 手机应用APP。
手机设备为什么能 接收并且处理自动化指令呢?
因为,Appium Server 会在手机上 安装一个 自动化代理程序, 代理程序会等待自动化指令,并且执行自动化指令
比如:要模拟用户点击界面按钮,Appium 自动化系统的流程是这样的:
-
自动化程序 调用客户端库相应的函数, 发送
点击元素
的指令(封装在HTTP消息里)给 Appium Server -
Appium Server 再转发这个指令给 手机上的自动化代理
-
手机上的自动化代理 接收到 指令后,调用手机平台的自动化库,执行点击操作,返回点击成功的结果给 Appium Server
-
Appium Server 转发给 自动化程序
-
自动化程序了解到本操作成功后,继续后面的自动化流程
其中,自动化代理控制,使用的什么库来实现自动化的呢?
如果测试的是苹果手机, 用的是苹果的 XCUITest 框架 (IOS9.3版本以后)
如果测试的是安卓手机,用的是安卓的 UIAutomator 框架 (Android4.2以后)
这些自动化框架提供了在手机设备上运行的库,可以让程序调用这些库,像人一样自动化操控设备和APP,比如:点击、滑动,模拟各种按键消息等。
2.自动化环境搭建
2.1 安装nodejs
推荐高版本的,16版本安装appim成功,10版本安装失败
2.2.安装Appium
在终端输入
npm install -g appium
注意FQ,或更换来源
npm install -g cnpm --registry=https://registry.npm.taobao.org
然后安装
cnpm install -g appium
appium安装到/usr/lib/node-v5.6.0-linux-x64/bin下。
由于已经有了环境变量,所以直接在终端运行
appium
[Appium] Welcome to Appium v1.22.3
[Appium] Appium REST http interface listener started on 0.0.0.0:4723
2.3 安装JDK
乌版图安装openjdk
1、更新软件包列表:
sudo apt-get update
2、安装openjdk-16-jdk:(如果安装失败试试17,18或19以上类推)
sudo apt-get install openjdk-16-jdk
- 3、查看java版本,看看是否安装成功:
java -version
2.4 安装 Android SDK
方法1:
1 新建一个终端窗口并打开
cd /opt/
sudo mkdir android-sdk
sudo chmod 777 android-sdk
cd android-sdk
2 下载sdkmanager解压
访问 Android 官方网站的下载页面:https://developer.android.com/studio#downloads
下载 "Command line tools only" 版本的 Android SDK。
curl -o commandlinetools.zip https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
sudo unzip commandlinetools.zip
rm -rf commandlinetools.zip
3 启动sdkmanager
# 进入解压后的目录
cd cmdline-tools/bin
# 列出可用的 SDK 组件
./sdkmanager --sdk_root=/opt/android-sdk/ --list
# 安装 Android 平台、平台工具和构建工具
./sdkmanager --sdk_root=/opt/android-sdk/ "platforms;android-35"
./sdkmanager --sdk_root=/opt/android-sdk/ "platform-tools"
./sdkmanager --sdk_root=/opt/android-sdk/ "build-tools;35.0.0"
4。环境配置 (mac是~/.zshrc)
echo 'export ANDROID_HOME=/opt/android-sdk' >> ~/.bashrc # 或 ~/.zshrc
echo 'export PATH=${ANDROID_HOME}/tools:$PATH' >> ~/.bashrc # 或 ~/.zshrc
echo 'export PATH=${ANDROID_HOME}/platform-tools:$PATH' >> ~/.bashrc # 或 ~/.zshrc
# 生效
source ~/.bashrc
验证
echo $ANDROID_HOME
adb --version
1、当出现提示:An unknown server-side error occurred while processing the command. Original error: Neither ANDROID_HOME nor ANDROID_SDK_ROOT environment variable was exported. Read https://developer.android.com/studio/command-line/variables for more details
确定环境变量没用问题,可以重启电脑试试
在 Windows 10 上,你可以按照类似的步骤来安装 Android Command Line Tools,只需根据 Windows 的命令提示符语法进行相应调整。
以下是在 Windows 10 上安装 Android Command Line Tools 的步骤:
进入解压后的目录:
打开命令提示符(Command Prompt)或 PowerShell,然后使用
cd
命令进入你解压 Android Command Line Tools 的目录。例如:cd D:\android-sdk\cmdline-tools\bin
确保将
C:\path\to\android\cmdline-tools
替换为你实际解压 Android Command Line Tools 的路径。列出可用的 SDK 组件:
使用以下命令列出可用的 SDK 组件:
sdkmanager --sdk_root=D:\android-sdk --list
确保将
C:\path\to\android-sdk
替换为你希望安装 Android SDK 的路径。安装 Android 平台、平台工具和构建工具:
使用以下命令安装 Android 平台、平台工具和构建工具:
sdkmanager --sdk_root=D:\android-sdk "platforms;android-35" sdkmanager --sdk_root=D:\android-sdk "platform-tools" sdkmanager --sdk_root=D:\android-sdk "build-tools;35.0.0"
确保将
C:\path\to\android-sdk
替换为你实际希望安装 Android SDK 的路径。通过上述步骤,你可以在 Windows 10 上安装 Android Command Line Tools,并安装特定的 Android 平台、平台工具和构建工具。确保根据实际路径和命令提示符语法进行相应调整。如果你遇到任何问题,请随时提供更多详细信息,我将尽力协助你。
环境变量用win10方法
方法2:
对于安卓APP的自动化,Appium Server 是需要 Android SDK的。
因为要用到里面的一些工具,比如 要执行命令设置手机、传送文件、安装应用、查看手机界面等。
Ubuntu下Android SDK安装与配置
(1)下载SDK:http://tools.android-studio.org/index.php/sdk
或者命令
wget http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz
(2)解压下载的压缩包
tar -zxvf android-sdk_r24.4.1-linux.tgz
sudo mv android-sdk-linux /usr/local/
cd /usr/local/android-sdk-linux/tools
更新SDK,下载platform-tools、add-ons
./android update sdk --no-ui
3、配置PATH路径:
命令:
sudo vim /etc/profile
在文件末尾加入如下内容:
#android sdk
export ANDROID_SDK=/usr/local/android-sdk-linux
export PATH=${PATH}:$ANDROID_SDK/tools:$ANDROID_SDK/platform-tools
【保存并退出】
source /etc/profile
至此 android SDK 安装配置完毕。
下载完成后可以进入tools目录,命令行输入android打开SDK Manager
android
参考http://www.testqa.cn/article/detail/224#Android_SDK_2
一、异常如下(安卓sdk方法2没用环境变量导致):
An unknown server-side error occurred while processing the command. Original error: Could not find 'adb.exe' in PATH. Please set the ANDROID_HOME or ANDROID_SDK_ROOT environment variables to the corect Android SDK root directory path.
最后安装Appium-Python-Client
pip3 install Appium-Python-Client
已知:appium和ATX冲突:如下
Traceback (most recent call last):
File "mobile.py", line 16, in <module>
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
File "/home/yys/.local/lib/python3.8/site-packages/appium/webdriver/webdriver.py", line 229, in __init__
super().__init__(
File "/home/yys/.local/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 275, in __init__
self.start_session(capabilities, browser_profile)
File "/home/yys/.local/lib/python3.8/site-packages/appium/webdriver/webdriver.py", line 319, in start_session
response = self.execute(RemoteCommand.NEW_SESSION, w3c_caps)
File "/home/yys/.local/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 430, in execute
self.error_handler.check_response(response)
File "/home/yys/.local/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 247, 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: The instrumentation process cannot be initialized. Make sure the application under test does not crash and investigate the logcat output.
Stacktrace:
UnknownError: An unknown server-side error occurred while processing the command. Original error: The instrumentation process cannot be initialized. Make sure the application under test does not crash and investigate the logcat output.
at getResponseForW3CError (/opt/node-v16.15.1-linux-x64/lib/node_modules/appium/node_modules/appium-base-driver/lib/protocol/errors.js:804:9)
at asyncHandler (/opt/node-v16.15.1-linux-x64/lib/node_modules/appium/node_modules/appium-base-driver/lib/protocol/protocol.js:380:37)
连接手机
上述的软件环境都准备好以后,要自动化手机APP,需要:
-
在你运行程序的电脑上 用 USB线 连接上 你的安卓手机
-
进入
手机设置
->关于手机
,不断点击版本号
菜单(7次以上), -
退出到上级菜单,在开发者模式中,启动USB调试
如果手机连接USB线后,手机界面弹出 类似 如下提示。
选择 允许USB调试。
注意:
有的手机系统,可能需要一些额外的选项需要设置好。
比如,有的手机,开发者选项里 需要打开 允许通过USB安装应用
等。
总之,给USB开发调试 尽可能方便的控制手机。
连接好以后,打开命令行窗口, 执行 adb devices -l
命令来列出连接在电脑上的安卓设备。
如果输出 类似如下的内容:
List of devices attached
4d0035dc767a50bb device product:t03gxx model:GT_N7100 device:t03g
表示电脑上可以查看到 连接的设备,就可以运行自动化程序了。
一个例子
下面是一段使用 Appium 自动化的打开 B站 应用,搜索 白月黑羽
发布的教程视频,并且打印视频标题的示例。
from appium import webdriver
from appium.webdriver.extensions.android.nativekey import AndroidKey
desired_caps = {
'platformName': 'Android', # 被测手机是安卓
'platformVersion': '8', # 手机安卓版本
'deviceName': 'xxx', # 设备名,可以填写ip端口号进行无线连接
'appPackage': 'tv.danmaku.bili', # 启动APP Package名称
'appActivity': '.ui.splash.SplashActivity', # 启动Activity名称
'unicodeKeyboard': True, # 使用自带输入法,输入中文时填True
'resetKeyboard': True, # 执行完程序恢复原来输入法
'noReset': True, # 不要重置App
'newCommandTimeout': 6000,
'automationName' : 'UiAutomator2'
# 'app': r'd:\apk\bili.apk',
}
# 连接Appium Server,初始化自动化环境
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
# 设置缺省等待时间
driver.implicitly_wait(5)
# 如果有`青少年保护`界面,点击`我知道了`
iknow = driver.find_elements_by_id("text3")
if iknow:
iknow.click()
# 根据id定位搜索位置框,点击
driver.find_element_by_id("expand_search").click()
# 根据id定位搜索输入框,点击
sbox = driver.find_element_by_id('search_src_text')
sbox.send_keys('白月黑羽')
# 输入回车键,确定搜索
driver.press_keycode(AndroidKey.ENTER)
# 选择(定位)所有视频标题
eles = driver.find_elements_by_id("title")
for ele in eles:
# 打印标题
print(ele.text)
input('**** Press to quit..')
driver.quit()
运行代码前,要先 运行 Appium Desktop
查找 应用 Package 和 Activity
没有apk
如果你应用已经安装在手机上了,可以直接打开手机上该应用,进入到你要操作的界面
然后执行
adb shell dumpsys activity recents | find "intent={"
会显示如下,最近的 几个 activity 信息,
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=tv.danmaku.bili/.ui.splash.SplashActivity}
intent={act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000300cmp=com.huawei.android.launcher/.unihome.UniHomeLauncher}
intent={flg=0x10804000 cmp=com.android.systemui/.recents.RecentsActivity bnds=[48,1378][10322746]}
intent={flg=0x10000000 cmp=com.tencent.mm/.ui.LauncherUI}
其中第一行就是当前的应用,我们特别关注最后
cmp=tv.danmaku.bili/.ui.splash.SplashActivity
应用的package名称就是 tv.danmaku.bili
应用的启动Activity就是 .ui.splash.SplashActivity
有apk
如果你已经获取到了 apk,在命令行窗口执行
d:\tools\androidsdk\build-tools\29.0.3\aapt.exe dump badging d:\tools\apk\bili.apk | find "package: name="
输出信息中,就有应用的package名称
package: name='tv.danmaku.bili' versionCode='5531000' versionName='5.53.1' platformBuildVersionName='5.53.1' compileSdkVersion='28' compileSdkVersionCodename='9'
在命令行窗口执行
d:\tools\androidsdk\build-tools\29.0.3\aapt.exe dump badging d:\tools\apk\bili.apk | find "launchable-activity"
输出信息中,就有应用的启动Activity
launchable-activity: name='tv.danmaku.bili.ui.splash.SplashActivity' label='' icon=''
Appium 的语法主要体现在客户端库提供的 API,用来与 Appium Server 交互,从而控制移动设备或模拟器。由于 Appium 支持多种编程语言(Java, Python, JavaScript, Ruby, C# 等),不同语言的语法略有差异。以下表格列出 Appium 的核心概念、通用操作和常用 API(以 Python 为例,其他语言类似),并给出一些示例:
核心概念
概念 | 描述 |
---|---|
Desired Capabilities | 一个 JSON 对象,用于配置 Appium 会话。定义了测试环境的各种属性,如平台、设备、应用等。 |
Session | Appium Server 与客户端之间的连接。通过 Desired Capabilities 建立。 |
WebDriver | 遵循 WebDriver 协议的客户端库,用于发送命令给 Appium Server。 |
Element | 移动应用界面上的一个控件(按钮、文本框、列表等)。 |
Locator | 定位策略,用于在应用界面上查找元素。 |
通用操作
操作 | 描述 | Python 示例 (使用 appium-python-client ) |
---|---|---|
启动 Appium 会话 | 使用 Desired Capabilities 创建 WebDriver 实例。 | driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) |
关闭 Appium 会话 | 关闭 WebDriver 实例。 | driver.quit() |
查找元素 | 使用 Locator 查找一个或多个元素。 | element = driver.find_element(AppiumBy.ID, "com.example.app:id/my_button") |
元素交互 | 点击、输入文本、获取文本等。 | element.click() element.send_keys("Hello") text = element.text |
屏幕操作 | 滑动、缩放、截屏等。 | driver.swipe(start_x, start_y, end_x, end_y) driver.get_screenshot_as_file("screenshot.png") |
应用操作 | 安装、启动、关闭、卸载应用等。 | driver.install_app("path/to/app.apk") driver.launch_app() driver.close_app() |
上下文切换 | 在 Native App 和 Webview 之间切换。 | driver.switch_to.context("NATIVE_APP") driver.switch_to.context("WEBVIEW_1") |
等待 | 显式等待、隐式等待。 | WebDriverWait(driver, 10).until(EC.presence_of_element_located((AppiumBy.ID, "my_element"))) |
常用 Locator (定位策略)
Locator | 描述 | Python 示例 (使用 appium-python-client ) |
---|---|---|
ID |
通过元素的 resource-id 属性定位(Android)或 name 属性(iOS)。 | driver.find_element(AppiumBy.ID, "com.example.app:id/my_button") |
XPATH |
通过 XPath 表达式定位。 | driver.find_element(AppiumBy.XPATH, "//android.widget.Button[@text='OK']") |
CLASS_NAME |
通过元素的 class 属性定位。 | driver.find_element(AppiumBy.CLASS_NAME, "android.widget.Button") |
ACCESSIBILITY_ID |
通过元素的 accessibility id 属性定位(推荐用于跨平台测试)。 | driver.find_element(AppiumBy.ACCESSIBILITY_ID, "my_button") |
IOS_PREDICATE |
通过 iOS Predicate 字符串定位(仅限 iOS)。 | driver.find_element(AppiumBy.IOS_PREDICATE, "label == 'OK'") |
IOS_CLASS_CHAIN |
通过 iOS Class Chain 字符串定位(仅限 iOS,比 XPath 更快)。 | driver.find_element(AppiumBy.IOS_CLASS_CHAIN, '**/XCUIElementTypeButton[ label == "OK"]') |
ANDROID_UIAUTOMATOR |
通过 Android UiAutomator 选择器定位(仅限 Android)。 | driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("OK")') |
IMAGE |
通过图像模板定位元素(实验性功能)。需要先保存基准图像。 | driver.find_element(AppiumBy.IMAGE, 'path/to/image.png') |
常用元素操作
操作 | 描述 | Python 示例 |
---|---|---|
click() |
点击元素 | element.click() |
send_keys(text) |
向元素输入文本 | element.send_keys("Hello, Appium!") |
clear() |
清除元素中的文本(例如,文本框) | element.clear() |
text |
获取元素的文本内容 | text = element.text |
get_attribute(name) |
获取元素的属性值 | value = element.get_attribute("checked") |
is_displayed() |
检查元素是否可见 | visible = element.is_displayed() |
is_enabled() |
检查元素是否启用 | enabled = element.is_enabled() |
is_selected() |
检查元素是否被选中(例如,复选框、单选按钮) | selected = element.is_selected() |
location |
获取元素左上角的坐标,返回一个字典,包含x和y | location = element.location |
size |
获取元素的大小,返回一个字典,包含width和height | size = element.size |
常用 TouchAction 和 MultiTouch (复杂手势)
操作 | 描述 | Python 示例 |
---|---|---|
TouchAction().press().wait().move_to().release() |
模拟手指按下、等待、移动、释放的动作,可以用来实现滑动、拖拽等操作。 | TouchAction(driver).press(x=100, y=200).wait(1000).move_to(x=500, y=200).release().perform() |
MultiTouch().add(touch_action) |
将多个 TouchAction 对象组合成一个 MultiTouch 对象,可以用来实现多指操作,例如缩放、旋转等。 |
ta1 = TouchAction(driver).press(x=100, y=200).wait(1000).move_to(x=200, y=300).release() ta2 = TouchAction(driver).press(x=500, y=200).wait(1000).move_to(x=400, y=300).release() MultiTouch(driver).add(ta1).add(ta2).perform() |
其他常用 API
API | 描述 | Python 示例 |
---|---|---|
driver.orientation |
获取或设置设备方向(竖屏、横屏) | driver.orientation = "LANDSCAPE" |
driver.back() |
模拟按下设备返回键 | driver.back() |
driver.hide_keyboard() |
隐藏键盘 | driver.hide_keyboard() |
driver.open_notifications() |
打开通知栏(仅限 Android) | driver.open_notifications() |
driver.get_window_size() |
返回窗口大小 | driver.get_window_size() |
driver.background_app(seconds) |
将应用置于后台指定秒数 | driver.background_app(5) |
driver.is_app_installed(bundle_id) |
检查应用是否已安装 | driver.is_app_installed('com.example.myapp') |
driver.start_activity(app_package, app_activity) |
直接启动应用的某个 Activity(仅限 Android) | driver.start_activity('com.example.app', '.MainActivity') |
driver.execute_script(script, *args) |
执行自定义的 JavaScript 脚本 (通常用于 Appium 不直接支持的特殊操作) | driver.execute_script("mobile: scroll", {"direction": "down"}) |
重要注意事项:
- 不同平台差异: Android 和 iOS 平台的元素属性和定位策略有所不同。例如,Android 通常使用
resource-id
,而 iOS 使用name
或accessibilityIdentifier
。 - Appium 版本: Appium 的 API 可能会随着版本更新而变化。请参考您使用的 Appium 版本的官方文档。
- 客户端库: 不同语言的客户端库(如
appium-python-client
、java-client
)的 API 命名和用法可能略有不同。 - WebDriverWait 与 EC: 为了编写更健壮的测试,强烈建议使用显式等待 (
WebDriverWait
) 结合预期条件 (EC
) 来等待元素出现或状态改变,而不是使用固定的time.sleep()
。 - Mobile Execution Commands:
driver.execute_script()
可以用来执行 Appium 提供的 "mobile:" 开头的命令,用于实现一些高级功能,例如模拟生物识别、网络条件、传感器等。 查阅 Appium 文档获取完整的 mobile 命令列表。
这个表格提供了 Appium 的主要语法和常用 API 的概述。要深入学习,强烈建议阅读 Appium 官方文档以及您选择的编程语言的客户端库文档。 练习编写测试脚本是掌握 Appium 的最佳途径。
本文作者: 永生
本文链接: https://yys.zone/detail/?id=179
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
评论列表 (0 条评论)