APP自动化基础之appium

appium介绍

什么是appium?

(官方)appium是一个开源的测试自动化框架,可以与原生的、混合的和移动的web应用程序一起使用。它使用webDriver协议驱动ios、android、windows、mac应用程序。
可以看出appium不仅可以用来测试移动端的app,还可以测试移动端的web以及pc端的桌面应用程序。

appium支持的平台及其测试框架

  • ios:xcuitest
  • android:uiautomator1、uiautomator2、Espresso
  • windows桌面应用:winappdriver
  • mac桌面应用:macdriver
  • 移动端web

appium特点

  • 开源。
  • 跨平台:可支持各种移动端和电脑端的测试。
  • 多语言:任何语言,只要能访问appium server端的api,都能用来进行测试。

appium设计哲学

  • 没有必要为了自动化而重新编译你的应用或以任何方式修改它。就是说测试应用时,没必要修改应用中的源代码来进行测试,因为各个平台都封装了各自系统自带的测试框架,它可以起到桥梁的作用,能将客户端及服务端连接起来;
  • 不应该被限制在特定的语言或框架上编写运行测试。也就是说android应用是用java开发的,那么没必要非要用java语言进行测试,可以用python、C、php等,而且也不要仅局限与一个测试框架。理论上只要能调用appium server的api,就能进行测试;
  • 移动端自动化框架在自动化接口方面不应该重造轮子。appium server复用了selenium webdriver中的大部分接口,再封装移动端、桌面程序所特有的api。
  • 移动端自动化框架应该开源。

appium与selinium的关系

客户端:webdriver模块

appium
我们进入appium的webdriver模块,可以看到它导入了selenium的一些类及方法,比如用于元素定位的By,还有用于与server端建立连接的RemoteConnection,以及向sever发送指令的RemoteCommand。
接下来我们看下appium的webdriver类继承的类:

class WebDriver(
    AppiumSearchContext,
    ActionHelpers,
    Activities,
    Applications,
    Clipboard,
    Context,
    Common,
    DeviceTime,
    Display,
    ExecuteDriver,
    ExecuteMobileCommand,
    Gsm,
    HardwareActions,
    ImagesComparison,
    IME,
    Keyboard,
    Location,
    LogEvent,
    Network,
    Performance,
    Power,
    RemoteFS,
    ScreenRecord,
    Session,
    Settings,
    Sms,
    SystemBars
)

我们点进AppiumSearchContext这个类看看,可以看到它又继承了webdriver这个类:在这里插入图片描述
而这个webdriver就是属于selenium的:
在这里插入图片描述

从这里可以看出,Chrome跟appium都是继承了selenium中的webdriver,然后根据浏览器或手机特性再去封装各自的代码。

客户端:mobileby

我们可以再看下appium的定位元素的类:MobileBy,可以看到它也是继承了selenium的By类,然后再封装了手机所特有的定位方式:

from selenium.webdriver.common.by import By


class MobileBy(By):
    IOS_PREDICATE = '-ios predicate string'
    IOS_UIAUTOMATION = '-ios uiautomation'
    IOS_CLASS_CHAIN = '-ios class chain'
    ANDROID_UIAUTOMATOR = '-android uiautomator'
    ANDROID_VIEWTAG = '-android viewtag'
    ANDROID_DATA_MATCHER = '-android datamatcher'
    ANDROID_VIEW_MATCHER = '-android viewmatcher'
    WINDOWS_UI_AUTOMATION = '-windows uiautomation'
    ACCESSIBILITY_ID = 'accessibility id'
    IMAGE = '-image'
    CUSTOM = '-custom'

服务端:协议

在服务端上,appium其实也是复用了selenium的。selenium webdriver使用的协议是json wire protocol,它是自动化web浏览器的标准,并且成为了w3c的工作草案;而appium则在复用json wire protocol大部分api的基础上,根据手机的特性又封装了自己的api,然后向w3c提出了自己的方案:Mobile Json Wire Protocol。

appium原理

appium原理与selenium大体上是相同的,只是在server端与测试主体之间的联系有些差异。
首先,在客户端,我们可以用java、python、php语言编写appium的脚本,然后就会通过mobile json wire protocol协议(也就是调用appium server端的接口)将请求以json的数据传输格式发送给appium server。接到请求后,appium server就会根据客户端代码中command_executor、desired_capabilities两个参数里的具体数据来决定发送请求给哪个平台。如果desired_capabilities参数中指明了平台为安卓,就会调用android sdk tools中的adb与android端的真机或模拟器建立连接,然后使用android sdk tools中的测试框架uiautomator来操作平台上的app。操作完成后,把信息(错误信息 or 成功信息)返回给appium server,server再将信息中的重点内容传给客户端的控制台,用户也可直接在appium server的桌面程序上的控制台看到信息。
在这里插入图片描述

appium实战

desiredcapabilities

什么是desiredcapabilities?

desiredcapabilities就是在appium客户端在跟appium服务端进行通信时所需要传递的一些参数,也就是告诉服务端要测试的对象是什么?它长什么样?要到哪里找?
在这里插入图片描述

desiredcapabilities参数

下面摘录了一些desiredcapabilities的参数:

通用

|automationName|

你想使用的自动化测试引擎|Appium (默认) 或 Selendroid|

|platformName|

你要测试的手机操作系统|iOS, Android, 或 FirefoxOS|

|platformVersion|

手机操作系统版本|例如: 7.1, 4.4|

|deviceName|

使用的手机类型或模拟器类型|iPhone Simulator, iPad Simulator, iPhone Retina 4-inch, Android Emulator, Galaxy S4, 等。

在 iOS 上,这个关键字的值必须是使用 instruments -s devices 得到的可使用的设备名称之一。在 Android
上,这个关键字目前不起作用。|

|app|

.ipa or .apk文件所在的本地绝对路径或者远程路径,也可以是一个包括两者之一的.zip

Appium会先尝试安装路径对应的应用在适当的真机或模拟器上。

针对Android系统,如果你指定app-packageapp-activity(具体见下面)的话,那么就可以不指定app

会与 browserName 冲突 |比如/abs/path/to/my.apk
http://myapp.com/app.ipa|

|browserName|

需要进行自动化测试的手机 web 浏览器名称。

如果是对应用进行自动化测试,这个关键字的值应为空。

|iOS 系统上可以用 ‘Safari‘ ,Android 系统上可以用‘Chrome‘, ‘Chromium‘, 或
‘Browser‘。|

|newCommandTimeout|

设置命令超时时间,单位:秒。

达到超时时间仍未接收到新的命令时 Appium 会假设客户端退出然后自动结束会话。|比如 60

|autoLaunch|

Appium是否需要自动安装和启动应用。默认值true|true, false|

|language|

(Sim/Emu-only) 设定模拟器 ( simulator / emulator ) 的语言。|如: fr|

|locale|

(Sim/Emu-only) 设定模拟器 ( simulator / emulator ) 的区域设置。|如: fr_CA|

|udid| 连接的物理设备的唯一设备标识|如: 1ae203187fc012g|

|orientation|

(Sim/Emu-only) 在一个设定的方向模式中开始测试|LANDSCAPE (横向) 或 PORTRAIT (纵向) |

|autoWebview|

直接转换到 WebView 上下文。 默认值 false、|true, false|

|noReset|

不要在会话前重置应用状态。默认值false。|true, false|

|fullReset|

(iOS) 删除整个模拟器目录。(Android) 通过卸载——而不是清空数据——来重置应用状态。在 Android
上,这也会在会话结束后自动清除被测应用。默认值
false|true, false|

android特有

|appActivity|

你要从你的应用包中启动的 Android Activity 名称。

它通常需要在前面添加 . (如:使用.MainActivity 而不是 MainActivity)
|MainActivity, .Settings|

|appPackage|

你想运行的Android应用的包名|

比如com.example.android.myApp, com.android.settings|

|appWaitActivity|

你想要等待启动的 Android Activity 名称|SplashActivity|

|deviceReadyTimeout|

设置等待一个模拟器或真机准备就绪的超时时间|5|

|androidCoverage|

用于执行测试的 instrumentation 类。

作为命令 adb shell am instrument -e coverage true -w-w 参数。|
com.my.Pkg/com.my.Pkg.instrumentation.MyInstrumentation|

|enablePerformanceLogging|

(仅适用于 Chrome 和 webview) 开启 Chromedriver 的性能日志。 (默认 false) | true,
false|

|androidDeviceReadyTimeout|

等待设备在启动应用后准备就绪的超时时间。以秒为单位。|如 30|

|androidDeviceSocket|

开发工具的 socket 名称。只有在被测应用是一个使用 Chromium 内核的浏览器时需要。 socket 会被浏览器打开,然后
Chromedriver 把它作为开发者
工具来进行连接。|如 chrome_devtools_remote|

|avd|

需要启动的 AVD (安卓虚拟设备) 名称。|如 api19|

|avdLaunchTimeout|

以毫秒为单位,等待 AVD 启动并连接到 ADB 的超时时间。(默认值 120000)| 300000|

|avdReadyTimeout|

以毫秒为单位,等待 AVD 完成启动动画的超时时间。(默认值 120000)| 300000|

|avdArgs|

启动 AVD 时需要加入的额外的参数。|如 -netfast|

|useKeystore|

使用一个自定义的 keystore 来对 apk 进行重签名。默认值 false|true or false|

|keystorePath|

自定义 keystore 的路径。默认: ~/.android/debug.keystore|如 /path/to.keystore|

|keystorePassword|

自定义 keystore 的密码。|如 foo|

|keyAlias|

key 的别名 |如 androiddebugkey|

|keyPassword|

key 的密码 |如 foo|

|chromedriverExecutable|

webdriver 可执行文件的绝对路径 (如果 Chromium 核心提供了对应的 webdriver, 应该用它代替 Appium
自带的 webdriver) |/abs/path/to/webdriver|

|autoWebviewTimeout|

以毫秒为单位,等待 Webview 上下文激活的时间。默认值 2000| 如 4|

|intentAction|

用于启动 activity 的 intent action。 (默认值 android.intent.action.MAIN)| 如
android.intent.action.MAIN, android.intent.action.VIEW|

|intentCategory|

用于启动 activity 的 intent category。 (默认值
android.intent.category.LAUNCHER) | 如
android.intent.category.LAUNCHER,
android.intent.category.APP_CONTACTS

|intentFlags|

用于启动 activity 的标识 ( flags ) (默认值 0x10200000) | 如 0x10200000

|optionalIntentArguments|

用于启动 activity 的额外 intent 参数。请查看 Intent
参数
| 如
--esn <EXTRA_KEY>, --ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE>

|dontStopAppOnReset|

在使用 adb 启动应用时不要停止被测应用的进程。如果被测应用是由另一个锚应用(anchor app)创建的,请把这个参数设置为
false 以允许锚应用 在使用 adb
启动被测应用时保持运行。换句话说,当 dontStopAppOnReset 设为 true 时,我们在 adb shell am start 命令中不会包含 -S 标志。
如果这个参数没有被设置或设为 false,我们会加入 -S 标志。默认值: false| truefalse|

|unicodeKeyboard|

使用 Unicode 输入法。默认值 false| truefalse|

|resetKeyboard|

在设定了 unicodeKeyboard 关键字的 Unicode 测试结束后,重置输入法到原有状态。如果单独使用,将会被忽略。默认值
false| truefalse|

|noSign|

跳过检查和对应用进行 debug 签名的步骤。只能在使用 UiAutomator 时使用,使用 selendroid 是不行。默认值
false | truefalse|

|ignoreUnimportantViews|

调用 uiautomator 的函数 setCompressedLayoutHierarchy()。由于 Accessibility
命令在忽略部分元素的情况下执行速度会加快,这个关键字能加
快测试执行的速度。被忽略的元素将不能够被找到,因此这个关键字同时也被实现成可以随时改变的 *设置 ( settings ) * 。默认值
false | true
false|

|disableAndroidWatchers|

关闭 android 监测应用无响应(ANR)和崩溃(crash)的监视器,这能够在 android 设备/模拟器上减少 cpu
使用量。这个参数只能在使用
UiAutomator 时工作,在使用 selendroid 时无效。默认值: false。| true 或者 false|

|chromeOptions|

允许传入 chrome driver 使用的 chromeOptions 参数。

必传参数
  • platformName:android还是ios;
  • deviceName:设备名称,可通过adb devices命令得到;
  • app:需要安装的apk包的路径。如果已经安装好了,一般不会再用这个参数;
  • automationName:自动化测试引擎,一般写UiAutomator1,如果不写会默认用UiAutomator2,可能会出现问题;
  • appPackage&appActivity:这两个参数一般都是连着用的。当apk包已经安装好了之后,就通过这两个命令来指定移动端上的app。appPackage是app的包名,它是唯一的;appActivity则是能与用户进行交互的应用窗体标识。这连个参数可通过以下方式获取到:
    • (常用)aapt dump badging apk的本地路径
    • (常用)adb shell dumpsys activity|find “mFocusedActivity”
      真机或模拟器上打开app,即可获取包名和activity:
      在这里插入图片描述
    • adb logcat | findStr -i displayed
    • adb shell am monitor
      以aapt命令为例。执行后,找到packagename即对应的是appPackage;launchable-activity即对应的是appActivity。
      在这里插入图片描述
代码示例
from appium import webdriver

caps = {
    "platformName": "Android",
    "deviceName": "emulator-5554",
    "automationName": "UiAutomator1",
    "appPackage": "com.xxzb.fenwoo",
    "appActivity": "com.xxzb.fenwoo.activity.addition.WelcomeActivity"
}
driver = webdriver.Remote(
    command_executor="http://127.0.0.1:4723/wd/hub",
    desired_capabilities=caps
)

appium server是如何运行的?

这里我们写了一段appium的代码,来看下appium server是如何运行的:

from appium import webdriver

caps = {
  "platformName": "Android",
  "deviceName": "emulator-5554",
  "automationName": "UiAutomator1",
  "appPackage": "cc.forestapp",
  "appActivity": "cc.forestapp.applications.SplashActivity",
  "noReset": True
}
driver = webdriver.Remote(
    command_executor="http://127.0.0.1:4723/wd/hub",
    desired_capabilities=caps
)

from appium.webdriver.common.mobileby import MobileBy
element = driver.find_element(MobileBy.ID,"cc.forestapp:id/button_text")
element.click()

在appium服务端启动时,把日志级别设成debug,会实时打印出执行日志,从日志中我们可以了解到appium server的执行逻辑,以及一些很重要的信息。
在这里插入图片描述
appium server执行时分为三个阶段:准备阶段、执行阶段、结束阶段。

准备阶段

这一阶段主要工作是发送请求给appium server,然后server调用adb执行adb指令连接目标并打开app一级自动化测试框架uiautomator。

首先,appium客户端会调用api:/wd/hub/session,并把代码中的参数:command_executor、desired_capabilities作为传参。appium server接收到请求后,会校验请求参数有没有问题,没问题的话就会拿command_executor、desired_capabilities作为参数创建一个android的驱动对象:
在这里插入图片描述

上面这些都准备好之后,就会去检查adb的环境有没有准备好,然后查看sdk的版本号并使用最新的一个:
在这里插入图片描述

接着就会调用adb devices指令,查看有几台设备并连接到指定设备:
在这里插入图片描述
接着会执行一个adb shell的命令:adb -P 5037 -s emulator-5554 shell getprop ro.build.version.sdk去获取目标sdk的版本号,这里获取到的是22,而我们这边的sdk用的是28,可以向下兼容:
在这里插入图片描述
如果获取的目标sdk版本要高于本地的sdk,则会报错。
接着会去查看代码中appPackage指定的apk包是否在目标上,并且等待设备出现及尝试ping通目标:
在这里插入图片描述
接着会去获取appium.settings包的信息,如果没有就会去安装:
在这里插入图片描述

这个appium settings的程序就是控制台中的BaseDriver,它负责接收接收appium server传过来的指令并执行指令操作app:在这里插入图片描述
接下来这一段可能是去获取appium settings的相关信息并进行相关配置:
在这里插入图片描述
接着去获取设备平台的相关信息,包括版本等:
在这里插入图片描述
接着会重置apk,也就是将apk恢复到新安装的状态,此时打开apk可能会有新手指引等界面出现。如果想跳过重置apk,可以在desired_capabilities中设置一个参数:noReset。
在这里插入图片描述
接着就回去打开uiautomator:
在这里插入图片描述

执行阶段

这个阶段主要就是执行用户编写的appium脚本对应的指令。
首先会准备一下bootstrap:
在这里插入图片描述
关于bootstrap,这里摘录下别的博主的描述:

那么我们应该怎么来给bootstrap做一个定义呢?我不知道官方有没有做一个定义,但是按照我自己的语言,我会这样来定义它:
Bootstrap是Appium运行在安卓目标测试机器上的一个UiAutomator测试脚本,该脚本的唯一一个测试方法所做的事情是在目标机器开启一个socket服务器来把一个session中Appium从PC端过来的命令发送给UiAutomator来执行处理。
这个定义说明了bootstrap在appium和uiautomator中究竟处于一个什么样的角色:
首先,它是一个uiautomator的测试脚本,它的入口类Bootstrap继承于UiAutomatorTestCase,所以UiAututomator可以正常运行它,它也可以正常的使用uiautomator的方法,这个就是appium的命令可以转换成uiautomator的命令的关键
其次,它是一个socket服务器,它专门监听4724端口过来的appium的连接和命令数据,并把appium的命令转换成uiautomator的命令来让uiautomator进行处理
最后,它处理的是appium从pc端过来的命令,而非一个文件。这在初次接触appium的朋友是很容易困惑的,以为appium是整个脚本文件发送到目标机器再由bootstrap进行分析处理的,事实并非如此。

接着客户端就会发送执行请求(如定位元素)给bootstrap,然后bootstrap执行之后的结果返回给客户端:
在这里插入图片描述

结束阶段

这一阶段主要是执行完appium的指令后,清理环境,关闭basedriver、androiddriver、AndroidBootstrap、uiautomator。
在这里插入图片描述

inspector

inspector有什么用?

inspector是appium自带的一款模拟手机操作并辅助测试的一款工具,相当于浏览器中的F12。在自动化测试当中,我们一般用来进行元素定位。

如何打开一个应用?

点击appium server的右上角第一个图标:
在这里插入图片描述
打开之后,可以看到有一栏熟悉的名字:Desired Capabilites:
在这里插入图片描述
没错,与代码中的desired_capabilities参数是对应起来的,只要把里面的参数全部填到界面上即可。
在这里插入图片描述
另外,为了下次使用方便,还可以保存配置好的Desired Capabilities。

界面介绍

输入完Desired Capabilities并点击start session后,就会打开新的界面:
在这里插入图片描述
这个界面跟浏览器中的F12非常地相似,分为4个部分:

  • 红色部分:界面;
  • 黄色部分:xml树,相当于F12的element中的dom。这里可以看出app的元素是用xml标记的,而pc端的web是用html标记的;
  • 蓝色部分:元素属性。定位到的某个元素的具体属性。在app中,元素的属性与html的元素属性是不一样的。html中的元素可以有某个属性也可以没有,且一些特殊的元素还有特殊的属性(如a标签的href属性);但app中,每个元素的属性都是相同的,都有21个属性,只是属性的值不一样罢了;
  • 绿色部分:操作栏。可以对红色部分的界面做出操作,然后xml数及元素属性会根据操作作出对应的展示。从左往右按钮依次是:
    • Select Element:选择元素。相当于浏览器中的选择元素:
      在这里插入图片描述

    • Swipe By Coordinates:选择滑动的起始和结束位置。当app上需要左右滑动切换页面时就可以用到这个

    • Tap By Coordinates:使得手机界面变换可操作状态,可以点击界面的元素

    • Back:模拟Android的返回键

    • Refresh Source & Screenshot:刷新页面,用来重新获取手机当前界面。有时真机/模拟器上的画面与inspector中的画面不同步,就可以通过刷新同步画面

    • Start Recording:录制操作。录制在界面上的操作,然后可以转换成自动化脚本

    • Search for element:校验定位表达式。输入元素表达式,看下能找出多少个元素

    • Copy XML Source to Clipboard:复制XML树

    • Quit Session & Close Inspector:退出当前Session
      这里比较常用的操作是:选择元素、校验定位表达式。

appium官方文档

学appium最好的方式就是去看appium官网中的相关文档:
http://appium.io/
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值