1.Appium 用途和特点

Appium 是一个移动 App (手机应用)自动化工具。

手机APP 自动化有什么用?

  • 自动化完成一些重复性的任务

    比如微信客服机器人

  • 爬虫

    就是通过手机自动化爬取信息。

    为什么不通过网页、HTTP 爬取呢?有的系统没有网页,也不方便通过HTTP爬取

  • 自动化测试

    很多企业里面有这样的需求

 

Appium 自动化方案的特点:

  • 开源免费

  • 支持多个平台

    iOS (苹果)、安卓 App 的自动化都支持。

  • 支持多种类型的自动化

    支持 苹果、安卓 应用 原生界面 的自动化

    支持 应用 内嵌 WebView 的自动化

    支持 手机浏览器 中的 web网站自动化

    支持 flutter 应用的自动化

  • 支持多种编程语言

    像 Selenium 一样, 可以用多种编程语言 调用它 开发自动化程序。

自动化原理

我们先来看一下Appium自动化的原理图

image

这图是不是很眼熟?

对啦,和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版本安装失败

nodejs

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 的步骤:

  1. 进入解压后的目录:

    打开命令提示符(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 的路径。

  2. 列出可用的 SDK 组件:

    使用以下命令列出可用的 SDK 组件:

    sdkmanager --sdk_root=D:\android-sdk --list

    确保将 C:\path\to\android-sdk 替换为你希望安装 Android SDK 的路径。

  3. 安装 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线后,手机界面弹出 类似 如下提示。

image

选择 允许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=''


3.语法

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-clientjava-client)的 API 命名和用法可能略有不同。
  • WebDriverWait 与 EC: 为了编写更健壮的测试,强烈建议使用显式等待 ( WebDriverWait ) 结合预期条件 ( EC ) 来等待元素出现或状态改变,而不是使用固定的 time.sleep()
  • Mobile Execution Commands: driver.execute_script() 可以用来执行 Appium 提供的 "mobile:" 开头的命令,用于实现一些高级功能,例如模拟生物识别、网络条件、传感器等。 查阅 Appium 文档获取完整的 mobile 命令列表。

这个表格提供了 Appium 的主要语法和常用 API 的概述。要深入学习,强烈建议阅读 Appium 官方文档以及您选择的编程语言的客户端库文档。 练习编写测试脚本是掌握 Appium 的最佳途径。