appium 原理
appium分为三个端 ,脚本叫客户端,appium启动服务叫服务端,设备叫终端或设备端
脚本和服务端连接的端口号4723,设备和服务端建立连接的端口号是4724,支持语言多的原因是 http协议建立连接。在安卓设备上如何驱动操作的,大于4.2安卓版本调用的是uiautomator(谷歌出的,只能操作安卓),小于4.2调用selendroid(selenium团队出的)。执行appium
在执行appium的时候,会往安卓设备上安装appiumBootstrap.jar,在创建session后会启动这个包,这个包用来接收服务端的命令,告诉设备操作的命令。IOS这边调用的是底层的工具uiautomation,以js语法写的,xcode自带的,
appium操作手机浏览器,用的是一个chromedriver
重要参数的含义
<!--是否支持unicode输入设置为true可以输入中文字符 -->
<parameter name="unicodeKeyboard" value="true" />,把appium设置为手机默认输入法
<!-- 重置键盘输入法 --><parameter name="resetKeyboard" value="true" /> 在执行完测试之后,将输入法重置为手机原有的
这两个是成对出现的。
安卓4.2以下,用selendroid,automationName,默认是以appium来执行的,执行引擎,
<parameter name="automationName" value="Appium" />
<parameter name="platformName" value="Android" />在安卓这边可以不用写
<parameter name="platformVersion" value="7.1.2" />在安卓这边可以不写
<!-- 设备名字,可随意起名字,但是要有意义 -->
<parameter name="deviceName" value="appium-test-avd" />
<!-- android app路径 -->
<parameter name="androidAppPath" value="res/app/android/yyc_android_2.2.1__beta_null.apk" /> 安装apk包路径,
执行手机web测试时,浏览器的名称,在做app测试时这项参数可以不写
browserName
<!--app的包 -->
<parameter name="appPackage" value="" />
<parameter name="appActivity" value="splash.SplashActivity" />
session 默认超时时间是一分钟,
appium 会自动安装三个包, unlock,代表自动解锁,
appiumsetting 会设置输入法
appium日志分析
//前三行是 服务端的启动情况,显示了appium服务端的版本号,以及服务端地址,
[36minfo[39m: Welcome to Appium v1.4.16 (REV ae6877eff263066b26328d457bd285c0cc62430d)
[36minfo[39m: Appium REST http interface listener started on 0.0.0.0:4723
[36minfo[39m: Console LogLevel: debug
//显示请求以及参数,参数作为一个json串传递,里面包含了各项值。
[36minfo[39m: [37m-->[39m [37mPOST[39m [37m/wd/hub/session[39m [90m{"desiredCapabilities":{"app":"D:\\n\\code\\appiumcombat-master\\res\\app\\android\\yyc_android_2.2.1__beta_null.apk","appPackage":"com..yyc","appActivity":"com.wu.yyc.splash.SplashActivity","platformVersion":"7.1.2","automationName":"Appium","sessionOverride":true,"unicodeKeyboard":true,"platformName":"Android","udid":"","deviceName":"appium-test-avd","resetKeyboard":true}}[39m
//显示的是httpclient 的版本
[36minfo[39m: Client User-Agent string: Apache-HttpClient/4.5.2 (Java/1.8.0_112)
// 没有被appium识别
[36minfo[39m: [debug] The following desired capabilities were provided, but not recognized by appium. They will be passed on to any other services running on this server. : sessionOverride
//使用本地的包
[36minfo[39m: [debug] Using local app from desired caps: D:\njl\code\appiumcombat-master\res\app\android\yyc_android_2.2.1__beta_null.apk
//创建一个session sessionID 是a6046e8b-f3f1-46f0-b39c-faf86f148168
[36minfo[39m: [debug] Creating new appium session a6046e8b-f3f1-46f0-b39c-faf86f148168
[36minfo[39m: Starting android appium
[36minfo[39m: [debug] Getting Java version
[36minfo[39m: Java version is: 1.8.0_112
//检查adb
[36minfo[39m: [debug] Checking whether adb is present
[36minfo[39m: [debug] Using adb from D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe
[36minfo[39m: [debug] Using fast reset? true
[36minfo[39m: [debug] Preparing device for session
//检查包是否实际存在
[36minfo[39m: [debug] Checking whether app is actually present
[36minfo[39m: Retrieving device
[36minfo[39m: [debug] Trying to find a connected android device
[36minfo[39m: [debug] Getting connected devices...
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe devices
[36minfo[39m: [debug] 1 device(s) connected
[36minfo[39m: Found device 3JU4C18104003318
[36minfo[39m: [debug] Setting device id to 3JU4C18104003318
//等待设备,通过shell命令响应
[36minfo[39m: [debug] Waiting for device to be ready and to respond to shell commands (timeout = 5)
// -s 针对某一台设备的
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 wait-for-device
//相当于adb shell
echo “ready”
时间是5s,如果超过5秒没回,会报错
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 shell "echo 'ready'"
[36minfo[39m: [debug] Starting logcat capture
[36minfo[39m: [debug] Getting device API level
//api 等级如果小于17的话 还没指定selenroid 会报错,
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 shell "getprop ro.build.version.sdk"
[36minfo[39m: [debug] Device is at API Level 26
[36minfo[39m: Device API level is: 26
[36minfo[39m: [debug] Extracting strings for language: default
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 shell "getprop persist.sys.language"
[36minfo[39m: [debug] Current device persist.sys.language:
[36minfo[39m: [debug] java -jar "D:\njl\Appium\node_modules\appium\node_modules\appium-adb\jars\appium_apk_tools.jar" "stringsFromApk" "D:\njl\code\appiumcombat-master\res\app\android\yyc_android_2.2.1_wu_beta_null.apk" "C:\Users\NIUJIN~1\AppData\Local\Temp\com.wu.yyc"
[36minfo[39m: [debug] Reading strings from converted strings.json
[36minfo[39m: [debug] Setting language to default
// 把应用 或文件 放到tmp 目录下,这目录不用root权限可以操作
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 push "C:\\Users\\NIUJIN~1\\AppData\\Local\\Temp\\com.wu.yyc\\strings.json" /data/local/tmp
//检查aapt 命令
[36minfo[39m: [debug] Checking whether aapt is present
[36minfo[39m: [debug] Using aapt from D:\njl\adt-bundle-windows\sdk\build-tools\build-tools-21.1.2\aapt.exe
[36minfo[39m: [debug] Retrieving process from manifest.
//用aapt dump 解析这个包
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\build-tools\build-tools-21.1.2\aapt.exe dump xmltree D:\njl\code\appiumcombat-master\res\app\android\yyc_android_2.2.1_wu_beta_null.apk AndroidManifest.xml
获取包名
[36minfo[39m: [debug] Set app process to: com.wu.yyc
[36minfo[39m: [debug] Not uninstalling app since server not started with --full-reset
[36minfo[39m: [debug] Checking app cert for D:\njl\code\appiumcombat-master\res\app\android\yyc_android_2.2.1_wu_beta_null.apk.
[36minfo[39m: [debug] executing cmd: java -jar D:\njl\Appium\node_modules\appium\node_modules\appium-adb\jars\verify.jar D:\njl\code\appiumcombat-master\res\app\android\yyc_android_2.2.1_wu_beta_null.apk
[36minfo[39m: [debug] App already signed.
[36minfo[39m: [debug] Zip-aligning D:\njl\code\appiumcombat-master\res\app\android\yyc_android_2.2.1_wu_beta_null.apk
[36minfo[39m: [debug] Checking whether zipalign is present
[36minfo[39m: [debug] Using zipalign from D:\njl\adt-bundle-windows\sdk\build-tools\build-tools-21.1.2\zipalign.exe
[36minfo[39m: [debug] Zip-aligning apk.
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\build-tools\build-tools-21.1.2\zipalign.exe -f 4 D:\njl\code\appiumcombat-master\res\app\android\yyc_android_2.2.1_wu_beta_null.apk C:\Users\NIUJIN~1\AppData\Local\Temp\118419-4576-g2u58h.4pxx7jh5mi\appium.tmp
//对app 用md5转换 重新命名,放到了tmp目录下
[36minfo[39m: [debug] MD5 for app is 2f3ab920b7967e26515c0a207273f0b4
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 shell "ls /data/local/tmp/2f3ab920b7967e26515c0a207273f0b4.apk"
[36minfo[39m: [debug] Getting install status for com.wu.yyc
[36minfo[39m: [debug] Getting device API level
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 shell "getprop ro.build.version.sdk"
[36minfo[39m: [debug] Device is at API Level 26
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 shell "pm list packages -3 com.wu.yyc"
[36minfo[39m: [debug] App is installed
[36minfo[39m: App is already installed, resetting app
[36minfo[39m: [debug] Running fast reset (stop and clear)
//强制停止app
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 shell "am force-stop com.wu.yyc"
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 shell "pm clear com.wu.yyc"
//占用两个端口,将电脑的4724,和设备的4724进行绑定,服务端和设备进行通信的端口
[36minfo[39m: [debug] Forwarding system:4724 to device:4724
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 forward tcp:4724 tcp:4724
[36minfo[39m: [debug] Pushing appium bootstrap to device...
// AppiumBootstrap.jar 安卓设备端 接收服务端 命令的一个包,接口命令后,这个包来执行测试的
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 push "D:\\njl\\Appium\\node_modules\\appium\\build\\android_bootstrap\\AppiumBootstrap.jar" /data/local/tmp/
[36minfo[39m: Starting App
大于4.2系统, 调用uiautomator 这个框架的,先杀掉之前的进程
[36minfo[39m: [debug] Attempting to kill all 'uiautomator' processes
[36minfo[39m: [debug] Getting all processes with 'uiautomator'
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 shell "ps"| grep uiautomator
[36minfo[39m: [debug] No matching processes found
//运行bootstrap, 启动bootstrap jar包,最后面是监听
[36minfo[39m: [debug] Running bootstrap
[36minfo[39m: [debug] spawning: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 shell uiautomator runtest AppiumBootstrap.jar -c io.appium.android.bootstrap.Bootstrap -e pkg com.wu.yyc -e disableAndroidWatchers false
[36minfo[39m: [debug] [90m[UIAUTOMATOR STDOUT] Warning: This version of UI Automator is deprecated. New tests should be written using[39m
[36minfo[39m: [debug] [90m[UIAUTOMATOR STDOUT] UI Automator 2.0 which is available as part of the Android Testing Support Library.[39m
[36minfo[39m: [debug] [90m[UIAUTOMATOR STDOUT] See https://developer.android.com/training/testing/ui-testing/uiautomator-testing.html[39m
[36minfo[39m: [debug] [90m[UIAUTOMATOR STDOUT] for more details.[39m
[36minfo[39m: [debug] [90m[UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: numtests=1[39m
[36minfo[39m: [debug] [90m[UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: stream=[39m
[36minfo[39m: [debug] [90m[UIAUTOMATOR STDOUT] io.appium.android.bootstrap.Bootstrap:[39m
[36minfo[39m: [debug] [90m[UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: id=UiAutomatorTestRunner[39m
[36minfo[39m: [debug] [90m[UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: test=testRunServer[39m
[36minfo[39m: [debug] [90m[UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: class=io.appium.android.bootstrap.Bootstrap[39m
[36minfo[39m: [debug] [90m[UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: current=1[39m
[36minfo[39m: [debug] [90m[UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS_CODE: 1[39m
//socket 设备端口打开了 4724,设备和服务端是通过socket 协议通信的, 服务端和脚本是通过httprest协议通信的
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Socket opened on port 4724
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Appium Socket Server Ready
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Loading json...
[36minfo[39m: [debug] [BOOTSTRAP] [debug] json loading complete.
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Registered crash watchers.
[36minfo[39m: [debug] Waking up device if it's not alive
[36minfo[39m: [debug] Pushing command to appium work queue: ["wake",{}]
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Client connected
[36minfo[39m: [debug] Pushing command to appium work queue: ["getDataDir",{}]
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"wake","params":{}}
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
//唤醒设备
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Got command action: wake
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Returning result: {"status":0,"value":true}
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"getDataDir","params":{}}
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
[36minfo[39m: [debug] dataDir set to: /data/local/tmp
[36minfo[39m: [debug] Pushing command to appium work queue: ["compressedLayoutHierarchy",{"compressLayout":false}]
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Got command action: getDataDir
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Returning result: {"status":0,"value":"\/data\/local\/tmp"}
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"compressedLayoutHierarchy","params":{"compressLayout":false}}
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Got command action: compressedLayoutHierarchy
[36minfo[39m: [debug] [BOOTSTRAP] [debug] Returning result: {"status":0,"value":false}
[36minfo[39m: [debug] Getting device API level
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 shell "getprop ro.build.version.sdk"
[36minfo[39m: [debug] Device is at API Level 26
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 shell "am start -S -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000 -n com.wu.yyc/com.wu.yyc.splash.SplashActivity"
//appium会拿起始activity 和启动后当前页面的activity做对比,如果不一致会报错,这时候用 appwaitactivity(“启动后当前页面的activity”,“会拿这个参数和启动后做对比”)
[36minfo[39m: [debug] Waiting for pkg "com.wu.yyc" and activity "com.wu.yyc.splash.SplashActivity" to be focused
[36minfo[39m: [debug] Getting focused package and activity
//获取当前窗口的activity dumpsys
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 shell "dumpsys window windows"
[36minfo[39m: [debug] executing cmd: D:\njl\adt-bundle-windows\sdk\platform-tools\adb.exe -s 3JU4C18104003318 shell "getprop ro.build.version.release"
[36minfo[39m: [debug] Device is at release version 8.0.0
[36minfo[39m: [debug] Device launched! Ready for commands
//超时时间60s
[36minfo[39m: [debug] Setting command timeout to the default of 60 secs
[36minfo[39m: [debug] Appium session started with sessionId a6046e8b-f3f1-46f0-b39c-faf86f148168
[36minfo[39m: [37m<-- POST /wd/hub/session [39m[36m303[39m[90m 16708.100 ms - 74[39m [90m[39m
[36minfo[39m: [37m-->[39m [37mGET[39m [37m/wd/hub/session/a6046e8b-f3f1-46f0-b39c-faf86f148168[39m [90m{}[39m
[36minfo[39m: [debug] Responding to client with success: {"status":0,"value":{"platform":"LINUX","browserName":"Android","platformVersion":"8.0.0","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"app":"D:\\njl\\code\\appiumcombat-master\\res\\app\\android\\yyc_android_2.2.1_wu_beta_null.apk","appPackage":"com.wu.yyc","appActivity":"com.wu.yyc.splash.SplashActivity","platformVersion":"7.1.2","automationName":"Appium","sessionOverride":true,"unicodeKeyboard":true,"platformName":"Android","udid":"","deviceName":"appium-test-avd","resetKeyboard":true},"app":"D:\\njl\\code\\appiumcombat-master\\res\\app\\android\\yyc_android_2.2.1_wu_beta_null.apk","appPackage":"com.wu.yyc","appActivity":"com.wu.yyc.splash.SplashActivity","automationName":"Appium","sessionOverride":true,"unicodeKeyboard":true,"platformName":"Android","udid":"","deviceName":"3JU4C18104003318","resetKeyboard":true},"sessionId":"a6046e8b-f3f1-46f0-b39c-faf86f148168"}
[36minfo[39m: [37m<-- GET /wd/hub/session/a6046e8b-f3f1-46f0-b39c-faf86f148168 [39m[32m200[39m[90m 3.545 ms - 1020[39m [90m{"status":0,"value":{"platform":"LINUX","browserName":"Android","platformVersion":"8.0.0","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"app":"D:\\njl\\code\\appiumcombat-master\\res\\app\\android\\yyc_android_2.2.1_wu_beta_null.apk","appPackage":"com.wu.yyc","appActivity":"com.wu.yyc.splash.SplashActivity","platformVersion":"7.1.2","automationName":"Appium","sessionOverride":true,"unicodeKeyboard":true,"platformName":"Android","udid":"","deviceName":"appium-test-avd","resetKeyboard":true},"app":"D:\\njl\\code\\appiumcombat-master\\res\\app\\android\\yyc_android_2.2.1_wu_beta_null.apk","appPackage":"com.wu.yyc","appActivity":"com.wu.yyc.splash.SplashActivity","automationName":"Appium","sessionOverride":true,"unicodeKeyboard":true,"platformName":"Android","udid":"","deviceName":"3JU4C18104003318","resetKeyboard":true},"sessionId":"a6046e8b-f3f1-46f0-b39c-faf86f148168"}[39m
[36minfo[39m: [37m-->[39m [37mPOST[39m [37m/wd/hub/session/a6046e8b-f3f1-46f0-b39c-faf86f148168/timeouts[39m [90m{"type":"implicit","ms":15000}[39m
[36minfo[39m: [debug] Set Android implicit wait to 15000ms
[36minfo[39m: [debug] Responding to client with success: {"status":0,"value":null,"sessionId":"a6046e8b-f3f1-46f0-b39c-faf86f148168"}
[36minfo[39m: [37m<-- POST /wd/hub/session/a6046e8b-f3f1-46f0-b39c-faf86f148168/timeouts [39m[32m200[39m[90m 5.109 ms - 76[39m [90m{"status":0,"value":null,"sessionId":"a6046e8b-f3f1-46f0-b39c-faf86f148168"}[39m
[36minfo[39m: [37m-->[39m [37mPOST[39m [37m/wd/hub/session/a6046e8b-f3f1-46f0-b39c-faf86f148168/touch/perform[39m [90m{"actions":[{"action":"press","options":{"x":800,"y":500}},{"action":"moveTo","options":{"x":100,"y":500}},{"action":"release","options":{}}]}[39m
// 关闭session 第一步 pressing HOME button
用的的是 adb sehll 命令