• APP自动化测试-12.Appium日志分析(原理)


    APP自动化测试-12.Appium日志分析



    前言

    以Android原生应用为例,记录使用appium进行自动化测试的过程日志,包含启动,元素的定位操作等。


    提示:以下是本篇文章正文内容,下面案例可供参考

    一、应用启动

    • 测试脚本:
    from time import sleep
    
    import pytest as pytest
    from appium import webdriver
    from appium.webdriver.common.appiumby import AppiumBy
    
    
    class TestTouch:
    
        def setup(self):
            desired_caps = {
                "platformName": "android",
                "appium:deviceName": "b1f37e8e",
                "appium:appPackage": "com.jianshu.haruki",
                "appium:appActivity": "com.baiji.jianshu.ui.splash.SplashScreenActivity",
                # 添加noReset后,会记录该应用之前的操作
                "noReset": True,
                # 设置dontStopAppOnReset后,如果应用已打开,则不会关闭应用重新打开
                # "dontStopAppOnReset": True,
                # 跳过安装及权限设置操作,提升执行速度
                "skipDeviceInitialization": True
            }
            self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
            # 设置隐式等待
            self.driver.implicitly_wait(3)
    
        def teardown(self):
            self.driver.quit()
    
        def test_toast(self):
            self.driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,
                                     'new UiSelector().resourceId("com.jianshu.haruki:id/iv_mine")').click()
            element = self.driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("点击登录")')
            assert '登录' in element.text
            assert int(element.size['width']) > 1
            assert int(element.size['height']) > 1
            element.click()
            self.driver.find_element(AppiumBy.ID, 'com.jianshu.haruki:id/et_account').send_keys('13000000000')
            self.driver.find_element(AppiumBy.ID, 'com.jianshu.haruki:id/et_verification_code_or_password').send_keys(
                '112345')
            self.driver.find_element(AppiumBy.ID, 'com.jianshu.haruki:id/tv_user_cb').click()
            self.driver.find_element(AppiumBy.ID, 'com.jianshu.haruki:id/tv_login').click()
            # 打印当前页面的dom树
            print(self.driver.page_source)
            # 通过classname进行定位
            print(self.driver.find_element(AppiumBy.XPATH, "//*[@class='android.widget.Toast']").text)
            # 通过text进行定位
            print(self.driver.find_element(AppiumBy.XPATH, "//*[contains(@text, '验证码无效')]").text)
            sleep(3)
    
        if __name__ == 'main':
            pytest.main()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 日志分析
    1. 启动appium服务,端口默认是4723,脚本的Remote地址即为appium所在服务器的IP地址,启动日志如下:
    2022-08-16 11:14:43:500 [Appium] Welcome to Appium v1.22.3
    2022-08-16 11:14:43:501 [Appium] Non-default server args:
    2022-08-16 11:14:43:501 [Appium]   logFile: appium1.log
    2022-08-16 11:14:43:516 [Appium] Appium REST http interface listener started on 0.0.0.0:4723
    
    • 1
    • 2
    • 3
    • 4
    1. 根据客户端传入的capabilities信息,创建session,供后面所有的请求使用,日志如下:
    2022-08-16 11:23:50:377 [HTTP] --> POST /wd/hub/session
    2022-08-16 11:23:50:377 [HTTP] {"capabilities":{"firstMatch":[{}],"alwaysMatch":{"platformName":"android","appium:deviceName":"b1f37e8e","appium:appPackage":"com.jianshu.haruki","appium:appActivity":"com.baiji.jianshu.ui.splash.SplashScreenActivity","appium:noReset":true,"appium:skipDeviceInitialization":true}}}
    2022-08-16 11:23:50:379 [W3C] Calling AppiumDriver.createSession() with args: [null,null,{"firstMatch":[{}],"alwaysMatch":{"platformName":"android","appium:deviceName":"b1f37e8e","appium:appPackage":"com.jianshu.haruki","appium:appActivity":"com.baiji.jianshu.ui.splash.SplashScreenActivity","appium:noReset":true,"appium:skipDeviceInitialization":true}}]
    2022-08-16 11:23:50:380 [BaseDriver] Event 'newSessionRequested' logged at 1660649030379 (19:23:50 GMT+0800 (中国标准时间))
    2022-08-16 11:23:50:387 [Appium] 
    2022-08-16 11:23:50:387 [Appium] ======================================================================
    # 这部分是Android的uiautomator的提示信息
    2022-08-16 11:23:50:387 [Appium]   DEPRECATION WARNING:
    2022-08-16 11:23:50:388 [Appium] 
    2022-08-16 11:23:50:388 [Appium]   The 'automationName' capability was not provided in the desired 
    2022-08-16 11:23:50:388 [Appium]   capabilities for this Android session
    2022-08-16 11:23:50:388 [Appium] 
    2022-08-16 11:23:50:389 [Appium]   Setting 'automationName=UiAutomator2' by default and using the 
    2022-08-16 11:23:50:389 [Appium]   UiAutomator2 Driver
    2022-08-16 11:23:50:389 [Appium] 
    2022-08-16 11:23:50:389 [Appium]   The next major version of Appium (2.x) will **require** the 
    2022-08-16 11:23:50:389 [Appium]   'automationName' capability to be set for all sessions on all 
    2022-08-16 11:23:50:389 [Appium]   platforms
    2022-08-16 11:23:50:390 [Appium] 
    2022-08-16 11:23:50:390 [Appium]   In previous versions (Appium <= 1.13.x), the default was 
    2022-08-16 11:23:50:390 [Appium]   'automationName=UiAutomator1'
    2022-08-16 11:23:50:390 [Appium] 
    2022-08-16 11:23:50:390 [Appium]   If you wish to use that automation instead of UiAutomator2, please 
    2022-08-16 11:23:50:390 [Appium]   add 'automationName=UiAutomator1' to your desired capabilities
    2022-08-16 11:23:50:390 [Appium] 
    2022-08-16 11:23:50:390 [Appium]   For more information about drivers, please visit 
    2022-08-16 11:23:50:390 [Appium]   http://appium.io/docs/en/about-appium/intro/ and explore the 
    2022-08-16 11:23:50:390 [Appium]   'Drivers' menu
    2022-08-16 11:23:50:391 [Appium] 
    2022-08-16 11:23:50:391 [Appium] ======================================================================
    2022-08-16 11:23:50:391 [Appium] 
    2022-08-16 11:23:50:661 [Appium] Appium v1.22.3 creating new AndroidUiautomator2Driver (v1.70.1) session
    2022-08-16 11:23:50:663 [BaseDriver] Creating session with W3C capabilities: {
    2022-08-16 11:23:50:663 [BaseDriver]   "alwaysMatch": {
    2022-08-16 11:23:50:663 [BaseDriver]     "platformName": "android",
    2022-08-16 11:23:50:663 [BaseDriver]     "appium:deviceName": "b1f37e8e",
    2022-08-16 11:23:50:664 [BaseDriver]     "appium:appPackage": "com.jianshu.haruki",
    2022-08-16 11:23:50:664 [BaseDriver]     "appium:appActivity": "com.baiji.jianshu.ui.splash.SplashScreenActivity",
    2022-08-16 11:23:50:664 [BaseDriver]     "appium:noReset": true,
    2022-08-16 11:23:50:664 [BaseDriver]     "appium:skipDeviceInitialization": true
    2022-08-16 11:23:50:664 [BaseDriver]   },
    2022-08-16 11:23:50:664 [BaseDriver]   "firstMatch": [
    2022-08-16 11:23:50:664 [BaseDriver]     {}
    2022-08-16 11:23:50:664 [BaseDriver]   ]
    2022-08-16 11:23:50:664 [BaseDriver] }
    # 根据capabilities,创建session,获得session_id,后续请求可以直接使用
    2022-08-16 11:23:50:674 [BaseDriver] Session created with session id: a335e892-b061-48a4-8bf7-23e97c6a006e
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    1. 准备开始启动被测应用
    2022-08-16 11:23:50:674 [UiAutomator2] Starting 'com.jianshu.haruki' directly on the device
    
    • 1
    1. 根据配置的adb环境变量,执行设备的相关初始化操作(主要是uiautomator2的初始化操作)
    # 根据配置的路径,查找build-tools
    2022-08-16 11:23:50:692 [ADB] Found 2 'build-tools' folders under '/Users/test/Library/Android/sdk' (newest first):
    2022-08-16 11:23:50:692 [ADB]     /Users/test/Library/Android/sdk/build-tools/30.0.3
    2022-08-16 11:23:50:692 [ADB]     /Users/test/Library/Android/sdk/build-tools/29.0.3
    2022-08-16 11:23:50:693 [ADB] Using 'adb' from '/Users/gaozeyu/Library/Android/sdk/platform-tools/adb'
    # 启动adb服务,adb -P 5037 start-server
    2022-08-16 11:23:50:693 [ADB] Running '/Users/gaozeyu/Library/Android/sdk/platform-tools/adb -P 5037 start-server'
    
    # 获取设备列表,默认取第一个设备
    2022-08-16 11:23:50:719 [AndroidDriver] Retrieving device list
    2022-08-16 11:23:50:720 [ADB] Trying to find a connected android device
    2022-08-16 11:23:50:720 [ADB] Getting connected devices
    
    # 连接指定设备
    2022-08-16 11:23:50:738 [ADB] Connected devices: [{"udid":"b1f37e8e","state":"device"}]
    2022-08-16 11:23:50:738 [AndroidDriver] Using device: b1f37e8e
    2022-08-16 11:23:50:739 [ADB] Using 'adb' from '/Users/test/Library/Android/sdk/platform-tools/adb'
    2022-08-16 11:23:50:739 [ADB] Running '/Users/test/Library/Android/sdk/platform-tools/adb -P 5037 start-server'
    
    # 设置device为指定的设备
    2022-08-16 11:23:50:757 [ADB] Setting device id to b1f37e8e
    
    # 获取设备sdk版本号,30
    2022-08-16 11:23:50:758 [ADB] Running '/Users/test/Library/Android/sdk/platform-tools/adb -P 5037 -s b1f37e8e shell getprop ro.build.version.sdk'
    2022-08-16 11:23:50:829 [ADB] Current device property 'ro.build.version.sdk': 30
    
    # 获取设备系统版本号,11
    2022-08-16 11:23:50:830 [ADB] Getting device platform version
    2022-08-16 11:23:50:830 [ADB] Running '/Users/test/Library/Android/sdk/platform-tools/adb -P 5037 -s b1f37e8e shell getprop ro.build.version.release'
    2022-08-16 11:23:50:893 [ADB] Current device property 'ro.build.version.release': 11
    2022-08-16 11:23:50:894 [ADB] Device API level: 30
    
    # 使用adb 命令更改 API 强制策略来启用对开发设备上的非 SDK 接口的访问
    2022-08-16 11:23:50:894 [UiAutomator2] Relaxing hidden api policy
    2022-08-16 11:23:50:894 [ADB] Running '/Users/test/Library/Android/sdk/platform-tools/adb -P 5037 -s b1f37e8e shell 'settings put global hidden_api_policy_pre_p_apps 1;settings put global hidden_api_policy_p_apps 1;settings put global hidden_api_policy 1''
    
    
    2022-08-16 11:23:51:059 [AndroidDriver] No app sent in, not parsing package/activity
    
    # 脚本中skipDeviceInitialization配置,所以跳过设备初始化
    2022-08-16 11:23:51:059 [AndroidDriver] 'skipDeviceInitialization' is set. Skipping device initialization.
    
    # appops命令设置io.appium.settings包的android:mock_location模式为allow
    2022-08-16 11:23:51:060 [ADB] Running '/Users/test/Library/Android/sdk/platform-tools/adb -P 5037 -s b1f37e8e shell appops set io.appium.settings android:mock_location allow'
    
    # 设置日志的输出
    2022-08-16 11:23:51:151 [Logcat] Starting logs capture with command: /Users/test/Library/Android/sdk/platform-tools/adb -P 5037 -s b1f37e8e logcat -v threadtime
    
    # 使用forward映射端口,将PC端的8200端口映射到手机端的6790端口
    2022-08-16 11:23:51:220 [UiAutomator2] Forwarding UiAutomator2 Server port 6790 to local port 8200
    2022-08-16 11:23:51:222 [ADB] Forwarding system: 8200 to device: 6790
    2022-08-16 11:23:51:222 [ADB] Running '/Users/test/Library/Android/sdk/platform-tools/adb -P 5037 -s b1f37e8e forward tcp:8200 tcp:6790'
    
    # 获取appium-uiautomator2-server包地址
    2022-08-16 11:23:51:245 [UiAutomator2] Server package at '/usr/local/lib/node_modules/appium/node_modules/appium-uiautomator2-server/apks/appium-uiautomator2-server-v4.27.0.apk' is not writeable. Will copy it into the temporary location at '/var/folders/gt/11h823ss2mx7gh4zf_1t7zlm0000gn/T/2022716-41846-1ron9fv.k6ex' as a workaround. Consider making this file writeable manually in order to improve the performance of session startup.
    
    # 获取appium-uiautomator2-server-debug-androidTest包地址
    2022-08-16 11:23:51:245 [UiAutomator2] Server package at '/usr/local/lib/node_modules/appium/node_modules/appium-uiautomator2-server/apks/appium-uiautomator2-server-debug-androidTest.apk' is not writeable. Will copy it into the temporary location at '/var/folders/gt/11h823ss2mx7gh4zf_1t7zlm0000gn/T/2022716-41846-1ron9fv.k6ex' as a workaround. Consider making this file writeable manually in order to improve the performance of session startup.
    
    # 获取uiautomator-server的安装状态
    2022-08-16 11:23:51:274 [ADB] Getting install status for io.appium.uiautomator2.server
    2022-08-16 11:23:51:274 [ADB] Running '/Users/test/Library/Android/sdk/platform-tools/adb -P 5037 -s b1f37e8e shell dumpsys package io.appium.uiautomator2.server'
    2022-08-16 11:23:51:391 [ADB] 'io.appium.uiautomator2.server' is installed
    
    # 获取uiautomator2-server的版本信息
    2022-08-16 11:23:51:391 [ADB] Getting package info for 'io.appium.uiautomator2.server'
    2022-08-16 11:23:51:391 [ADB] Running '/Users/test/Library/Android/sdk/platform-tools/adb -P 5037 -s b1f37e8e shell dumpsys package io.appium.uiautomator2.server'
    2022-08-16 11:23:51:610 [ADB] The version name of the installed 'io.appium.uiautomator2.server' is greater or equal to the application version name ('4.27.0' >= '4.27.0')
    2022-08-16 11:23:51:610 [UiAutomator2] io.appium.uiautomator2.server installation state: sameVersionInstalled
    
    # 检查uiautomator-server证书,并进行重新签名
    2022-08-16 11:23:51:610 [ADB] Checking app cert for /var/folders/gt/11h823ss2mx7gh4zf_1t7zlm0000gn/T/2022716-41846-1ron9fv.k6ex/appium-uiautomator2-server-v4.27.0.apk
    2022-08-16 11:23:51:631 [ADB] Using 'apksigner.jar' from '/Users/test/Library/Android/sdk/build-tools/30.0.3/lib/apksigner.jar'
    2022-08-16 11:23:51:632 [ADB] Starting apksigner: /Library/Java/JavaVirtualMachines/jdk1.8.0_333.jdk/Contents/Home/bin/java -Xmx1024M -Xss1m -jar /Users/gaozeyu/Library/Android/sdk/build-tools/30.0.3/lib/apksigner.jar verify --print-certs /var/folders/gt/11h823ss2mx7gh4zf_1t7zlm0000gn/T/2022716-41846-1ron9fv.k6ex/appium-uiautomator2-server-v4.27.0.apk
    2022-08-16 11:23:52:551 [ADB] apksigner stdout: Signer #1 certificate DN: EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
    2022-08-16 11:23:52:551 [ADB] Signer #1 certificate SHA-256 digest: a40da80a59d170caa950cf15c18c454d47a39b26989d8b640ecd745ba71bf5dc
    2022-08-16 11:23:52:551 [ADB] Signer #1 certificate SHA-1 digest: 61ed377e85d386a8dfee6b864bd85b0bfaa5af81
    2022-08-16 11:23:52:551 [ADB] Signer #1 certificate MD5 digest: e89b158e4bcf988ebd09eb83f5378e87
    2022-08-16 11:23:52:551 [ADB] 
    2022-08-16 11:23:52:551 [ADB] sha256 hash did match for 'appium-uiautomator2-server-v4.27.0.apk'
    2022-08-16 11:23:52:552 [ADB] '/var/folders/gt/11h823ss2mx7gh4zf_1t7zlm0000gn/T/2022716-41846-1ron9fv.k6ex/appium-uiautomator2-server-v4.27.0.apk' is signed with the default certificate
    
    # 检查uiautomator-server-test的安装状态
    2022-08-16 11:23:52:552 [ADB] Getting install status for io.appium.uiautomator2.server.test
    2022-08-16 11:23:52:552 [ADB] Running '/Users/test/Library/Android/sdk/platform-tools/adb -P 5037 -s b1f37e8e shell dumpsys package io.appium.uiautomator2.server.test'
    2022-08-16 11:23:52:623 [ADB] 'io.appium.uiautomator2.server.test' is installed
    
    # 检查uiautomator-server-test的证书,并进行重新签名
    2022-08-16 11:23:52:623 [ADB] Checking app cert for /var/folders/gt/11h823ss2mx7gh4zf_1t7zlm0000gn/T/2022716-41846-1ron9fv.k6ex/appium-uiautomator2-server-debug-androidTest.apk
    2022-08-16 11:23:52:626 [ADB] Starting apksigner: /Library/Java/JavaVirtualMachines/jdk1.8.0_333.jdk/Contents/Home/bin/java -Xmx1024M -Xss1m -jar /Users/gaozeyu/Library/Android/sdk/build-tools/30.0.3/lib/apksigner.jar verify --print-certs /var/folders/gt/11h823ss2mx7gh4zf_1t7zlm0000gn/T/2022716-41846-1ron9fv.k6ex/appium-uiautomator2-server-debug-androidTest.apk
    2022-08-16 11:23:52:930 [ADB] apksigner stdout: Signer #1 certificate DN: EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
    2022-08-16 11:23:52:930 [ADB] Signer #1 certificate SHA-256 digest: a40da80a59d170caa950cf15c18c454d47a39b26989d8b640ecd745ba71bf5dc
    2022-08-16 11:23:52:930 [ADB] Signer #1 certificate SHA-1 digest: 61ed377e85d386a8dfee6b864bd85b0bfaa5af81
    2022-08-16 11:23:52:930 [ADB] Signer #1 certificate MD5 digest: e89b158e4bcf988ebd09eb83f5378e87
    2022-08-16 11:23:52:930 [ADB] 
    2022-08-16 11:23:52:931 [ADB] sha256 hash did match for 'appium-uiautomator2-server-debug-androidTest.apk'
    2022-08-16 11:23:52:931 [ADB] '/var/folders/gt/11h823ss2mx7gh4zf_1t7zlm0000gn/T/2022716-41846-1ron9fv.k6ex/appium-uiautomator2-server-debug-androidTest.apk' is signed with the default certificate
    
    # 初始化uiautomator2并获取状态直至成功
    2022-08-16 11:23:52:931 [UiAutomator2] Server packages are not going to be (re)installed
    2022-08-16 11:23:52:934 [UiAutomator2] Waiting up to 30000ms for services to be available
    2022-08-16 11:23:52:934 [ADB] Running '/Users/gaozeyu/Library/Android/sdk/platform-tools/adb -P 5037 -s b1f37e8e shell pm list instrumentation'
    2022-08-16 11:23:53:010 [UiAutomator2] Instrumentation target 'io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner' is available
    2022-08-16 11:23:53:013 [ADB] Adding packages ["io.appium.settings","io.appium.uiautomator2.server","io.appium.uiautomator2.server.test"] to Doze whitelist
    2022-08-16 11:23:53:013 [ADB] Got the following command chunks to execute: [["dumpsys","deviceidle","whitelist","+io.appium.settings",";","dumpsys","deviceidle","whitelist","+io.appium.uiautomator2.server",";","dumpsys","deviceidle","whitelist","+io.appium.uiautomator2.server.test",";"]]
    2022-08-16 11:23:53:013 [ADB] Running '/Users/gaozeyu/Library/Android/sdk/platform-tools/adb -P 5037 -s b1f37e8e shell dumpsys deviceidle whitelist +io.appium.settings ; dumpsys deviceidle whitelist +io.appium.uiautomator2.server ; dumpsys deviceidle whitelist +io.appium.uiautomator2.server.test ;'
    2022-08-16 11:23:53:126 [UiAutomator2] No app capability. Assuming it is already on the device
    2022-08-16 11:23:53:127 [UiAutomator2] Performing shallow cleanup of automation leftovers
    2022-08-16 11:23:53:141 [UiAutomator2] No obsolete sessions have been detected (socket hang up)
    2022-08-16 11:23:53:141 [ADB] Running '/Users/gaozeyu/Library/Android/sdk/platform-tools/adb -P 5037 -s b1f37e8e shell am force-stop io.appium.uiautomator2.server.test'
    2022-08-16 11:23:53:202 [UiAutomator2] Starting UIAutomator2 server 4.27.0
    2022-08-16 11:23:53:202 [UiAutomator2] Using UIAutomator2 server from '/usr/local/lib/node_modules/appium/node_modules/appium-uiautomator2-server/apks/appium-uiautomator2-server-v4.27.0.apk' and test from '/usr/local/lib/node_modules/appium/node_modules/appium-uiautomator2-server/apks/appium-uiautomator2-server-debug-androidTest.apk'
    2022-08-16 11:23:53:202 [UiAutomator2] Waiting up to 30000ms for UiAutomator2 to be online...
    2022-08-16 11:23:53:202 [ADB] Creating ADB subprocess with args: ["-P",5037,"-s","b1f37e8e","shell","am","instrument","-w","-e","disableAnalytics",true,"io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner"]
    2022-08-16 11:23:53:209 [WD Proxy] Matched '/status' to command name 'getStatus'
    2022-08-16 11:23:53:210 [WD Proxy] Proxying [GET /status] to [GET http://127.0.0.1:8200/wd/hub/status] with no body
    2022-08-16 11:23:53:215 [WD Proxy] socket hang up
    2022-08-16 11:23:53:978 [Instrumentation] io.appium.uiautomator2.server.test.AppiumUiAutomator2Server:
    2022-08-16 11:23:54:217 [WD Proxy] Matched '/status' to command name 'getStatus'
    2022-08-16 11:23:54:218 [WD Proxy] Proxying [GET /status] to [GET http://127.0.0.1:8200/wd/hub/status] with no body
    2022-08-16 11:23:54:229 [WD Proxy] socket hang up
    2022-08-16 11:23:55:230 [WD Proxy] Matched '/status' to command name 'getStatus'
    2022-08-16 11:23:55:231 [WD Proxy] Proxying [GET /status] to [GET http://127.0.0.1:8200/wd/hub/status] with no body
    2022-08-16 11:23:55:307 [WD Proxy] Got response with status 200: {"sessionId":"None","value":{"message":"UiAutomator2 Server is ready to accept commands","ready":true}}
    2022-08-16 11:23:55:308 [UiAutomator2] The initialization of the instrumentation process took 2106ms
    
    # 到这里uiautomator2启动完成,用时2.106秒
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    1. 创建session,启动被测试应用
    2022-08-16 11:23:55:308 [WD Proxy] Proxying [POST /session] to [POST http://127.0.0.1:8200/wd/hub/session] with body: {"capabilities":{"firstMatch":[{"platform":"LINUX","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"platformName":"android","deviceName":"b1f37e8e","appPackage":"com.jianshu.haruki","appActivity":"com.baiji.jianshu.ui.splash.SplashScreenActivity","noReset":true,"skipDeviceInitialization":true},"platformName":"android","deviceName":"b1f37e8e","appPackage":"com.jianshu.haruki","appActivity":"com.baiji.jianshu.ui.splash.SplashScreenActivity","noReset":true,"skipDeviceInitialization":true,"deviceUDID":"b1f37e8e"}],"alwaysMatch":{}}}
    2022-08-16 11:23:55:328 [WD Proxy] Got response with status 200: {"sessionId":"494dfb5e-42b3-4174-9365-ea4ede1a7f08","value":{"capabilities":{"firstMatch":[{"platform":"LINUX","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"platformName":"android","deviceName":"b1f37e8e","appPackage":"com.jianshu.haruki","appActivity":"com.baiji.jianshu.ui.splash.SplashScreenActivity","noReset":true,"skipDeviceInitialization":true},"platformName":"android","deviceName":"b1f37e8e","appPackage":"com.jianshu.haruki","appActivity":"com.baiji.jianshu.ui.splash.SplashScreenActivity","noReset":true,"skipDeviceInitialization":true,"deviceUDID":"b1f37e8e"}],"alwaysMatch":{}},"sessionId":"494dfb5e-42b3-4174-9365-ea4ede1a7f08"}}
    2022-08-16 11:23:55:329 [WD Proxy] Determined the downstream protocol as 'W3C'
    2022-08-16 11:23:55:339 [WD Proxy] Proxying [GET /appium/device/info] to [GET http://127.0.0.1:8200/wd/hub/session/494dfb5e-42b3-4174-9365-ea4ede1a7f08/appium/device/info] with no body
    2022-08-16 11:23:55:380 [WD Proxy] Got response with status 200: {"sessionId":"494dfb5e-42b3-4174-9365-ea4ede1a7f08","value":{"androidId":"a8c3179c8696566a","apiVersion":"30","bluetooth":{"state":"ON"},"brand":"Redmi","carrierName":"","displayDensity":440,"locale":"zh_CN","manufacturer":"Xiaomi","model":"Redmi K30 5G","networks":[{"capabilities":{"SSID":null,"linkDownBandwidthKbps":352000,"linkUpstreamBandwidthKbps":352000,"networkCapabilities":"NET_CAPABILITY_NOT_METERED,NET_CAPABILITY_INTERNET,NET_CAPABILITY_NOT_RESTRICTED,NET_CAPABILITY_TRUSTED,NET_CAPABILITY_NOT_VPN,NET_CAPABILITY_VALIDATED,NET_CAPABILITY_NOT_ROAMING,NET_CAPABILITY_FOREGROUND,NET_CAPABILITY_NOT_CONGESTED,NET_CAPABILITY_NOT_SUSPENDED","signalStrength":-44,"transportTypes":"TRANSPORT_WIFI"},"detailedState":"CONNECTED","extraInfo":"","isAvailable":true,"isConnected":true,"isFailover":false,"isRoaming":false,"state":"CONNECTED","subtype":0,"subtypeName":"","type":1,"typeName":"WIFI"}],"platformVersion":"11","realDisplaySize":"1080x2400","timeZone":"Asia/Shanghai"}}
    2022-08-16 11:23:55:381 [ADB] Running '/Users/gaozeyu/Library/Android/sdk/platform-tools/adb -P 5037 -s b1f37e8e shell dumpsys window'
    2022-08-16 11:23:55:511 [AndroidDriver] Screen already unlocked, doing nothing
    2022-08-16 11:23:55:511 [UiAutomator2] Starting 'com.jianshu.haruki/com.baiji.jianshu.ui.splash.SplashScreenActivity and waiting for  com.jianshu.haruki/com.baiji.jianshu.ui.splash.SplashScreenActivity\'
    
    # 启动被测试应用,adb -P 5037 -s b1f37e8e shell am start -W -n com.jianshu.haruki/com.baiji.jianshu.ui.splash.SplashScreenActivity -S -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000
    2022-08-16 11:23:55:512 [ADB] Running '/Users/test/Library/Android/sdk/platform-tools/adb -P 5037 -s b1f37e8e shell am start -W -n com.jianshu.haruki/com.baiji.jianshu.ui.splash.SplashScreenActivity -S -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000'
    2022-08-16 11:23:56:644 [WD Proxy] Proxying [GET /appium/device/pixel_ratio] to [GET http://127.0.0.1:8200/wd/hub/session/494dfb5e-42b3-4174-9365-ea4ede1a7f08/appium/device/pixel_ratio] with no body
    2022-08-16 11:23:56:654 [WD Proxy] Got response with status 200: {"sessionId":"494dfb5e-42b3-4174-9365-ea4ede1a7f08","value":2.75}
    2022-08-16 11:23:56:655 [WD Proxy] Matched '/appium/device/system_bars' to command name 'getSystemBars'
    2022-08-16 11:23:56:655 [WD Proxy] Proxying [GET /appium/device/system_bars] to [GET http://127.0.0.1:8200/wd/hub/session/494dfb5e-42b3-4174-9365-ea4ede1a7f08/appium/device/system_bars] with no body
    2022-08-16 11:23:56:677 [WD Proxy] Got response with status 200: {"sessionId":"494dfb5e-42b3-4174-9365-ea4ede1a7f08","value":{"statusBar":95}}
    2022-08-16 11:23:56:678 [WD Proxy] Matched '/window/current/size' to command name 'getWindowSize'
    2022-08-16 11:23:56:678 [WD Proxy] Proxying [GET /window/current/size] to [GET http://127.0.0.1:8200/wd/hub/session/494dfb5e-42b3-4174-9365-ea4ede1a7f08/window/current/size] with no body
    2022-08-16 11:23:56:684 [WD Proxy] Got response with status 200: {"sessionId":"494dfb5e-42b3-4174-9365-ea4ede1a7f08","value":{"height":2261,"width":1080}}
    
    # uiautomator driver session创建成功
    2022-08-16 11:23:56:685 [Appium] New AndroidUiautomator2Driver session created successfully, session a335e892-b061-48a4-8bf7-23e97c6a006e added to master session list
    2022-08-16 11:23:56:685 [BaseDriver] Event 'newSessionStarted' logged at 1660649036685 (19:23:56 GMT+0800 (中国标准时间))
    2022-08-16 11:23:56:686 [W3C (a335e892)] Cached the protocol value 'W3C' for the new session a335e892-b061-48a4-8bf7-23e97c6a006e
    2022-08-16 11:23:56:686 [W3C (a335e892)] Responding to client with driver.createSession() result: {"capabilities":{"platform":"LINUX","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"platformName":"android","deviceName":"b1f37e8e","appPackage":"com.jianshu.haruki","appActivity":"com.baiji.jianshu.ui.splash.SplashScreenActivity","noReset":true,"skipDeviceInitialization":true},"platformName":"android","deviceName":"b1f37e8e","appPackage":"com.jianshu.haruki","appActivity":"com.baiji.jianshu.ui.splash.SplashScreenActivity","noReset":true,"skipDeviceInitialization":true,"deviceUDID":"b1f37e8e","deviceApiLevel":30,"platformVersion":"11","deviceScreenSize":"1080x2400","deviceScreenDensity":440,"deviceModel":"Redmi K30 5G","deviceManufacturer":"Xiaomi","pixelRatio":2.75,"statBarHeight":95,"viewportRect":{"left":0,"top":95,"width":1080,"height":2166}}}
    2022-08-16 11:23:56:689 [HTTP] <-- POST /wd/hub/session 200 6312 ms - 957
    # 截止这里初始化完成,被测应用成功启动
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    二、元素定位与操作

    1. 定义隐式等待时间,日志如下:
    # /session后跟的ID即为初始化时生成的,后续所有请求都会携带该ID
    2022-08-16 11:23:56:691 [HTTP] --> POST /wd/hub/session/a335e892-b061-48a4-8bf7-23e97c6a006e/timeouts
    2022-08-16 11:23:56:691 [HTTP] {"implicit":3000}
    2022-08-16 11:23:56:693 [W3C (a335e892)] Calling AppiumDriver.timeouts() with args: [null,null,null,null,3000,"a335e892-b061-48a4-8bf7-23e97c6a006e"]
    2022-08-16 11:23:56:693 [BaseDriver] W3C timeout argument: {"implicit":3000}}
    2022-08-16 11:23:56:693 [BaseDriver] Set implicit wait to 3000ms
    2022-08-16 11:23:56:694 [W3C (a335e892)] Responding to client with driver.timeouts() result: null
    2022-08-16 11:23:56:694 [HTTP] <-- POST /wd/hub/session/a335e892-b061-48a4-8bf7-23e97c6a006e/timeouts 200 3 ms - 14
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 发送定位元素的请求
    # 发起元素定位请求,参数中using为定位方法,value为定位表达式
    2022-08-16 11:23:56:696 [HTTP] --> POST /wd/hub/session/a335e892-b061-48a4-8bf7-23e97c6a006e/element
    2022-08-16 11:23:56:696 [HTTP] {"using":"-android uiautomator","value":"new UiSelector().resourceId(\"com.jianshu.haruki:id/iv_mine\")"}
    
    2022-08-16 11:23:56:699 [W3C (a335e892)] Calling AppiumDriver.findElement() with args: ["-android uiautomator","new UiSelector().resourceId(\"com.jianshu.haruki:id/iv_mine\")","a335e892-b061-48a4-8bf7-23e97c6a006e"]
    
    # 列出有效的定位方式
    2022-08-16 11:23:56:699 [BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, css selector, -android uiautomator
    2022-08-16 11:23:56:699 [BaseDriver] Waiting up to 3000 ms for condition
    2022-08-16 11:23:56:700 [WD Proxy] Matched '/element' to command name 'findElement'
    
    # 将请求转发给8200端口,通过8200端口forward给手机端的6790端口
    2022-08-16 11:23:56:700 [WD Proxy] Proxying [POST /element] to [POST http://127.0.0.1:8200/wd/hub/session/494dfb5e-42b3-4174-9365-ea4ede1a7f08/element] with body: {"strategy":"-android uiautomator","selector":"new UiSelector().resourceId(\"com.jianshu.haruki:id/iv_mine\")","context":"","multiple":false}
    
    # 获取手机端的返回,没有找到元素
    2022-08-16 11:23:57:216 [WD Proxy] Got response with status 404: {"sessionId":"494dfb5e-42b3-4174-9365-ea4ede1a7f08","value":{"error":"no such element","message":"An element could not be located on the page using the given search parameters","stacktrace":"io.appium.uiautomator2.common.exceptions.ElementNotFoundException: An element could not be located on the page using the given search parameters\n\tat io.appium.uiautomator2.handler.FindElement.safeHandle(FindElement.java:70)\n\tat io.appium.uiautomator2.handler.request.SafeRequestHandler.handle(SafeRequestHandler.java:59)\n\tat io.appium.uiautomator2.server.AppiumServlet.handleRequest(AppiumServlet.java:266)\n\tat io.appium.uiautomator2.server.AppiumServlet.handleHttpRequest(AppiumServlet.java:260)\n\tat io.appium.uiautomator2.http.ServerHandler.channelRead(ServerHandler.java:68)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)\n\tat io.netty.chann..."
    
    # 提示无元素
    2022-08-16 11:23:57:216 [W3C] Matched W3C error code 'no such element' to NoSuchElementError
    2022-08-16 11:23:57:217 [BaseDriver] Waited for 518 ms so far
    
    # 由于有隐式等待,所以继续发起请求查找元素
    2022-08-16 11:23:57:718 [WD Proxy] Matched '/element' to command name 'findElement'
    2022-08-16 11:23:57:719 [WD Proxy] Proxying [POST /element] to [POST http://127.0.0.1:8200/wd/hub/session/494dfb5e-42b3-4174-9365-ea4ede1a7f08/element] with body: {"strategy":"-android uiautomator","selector":"new UiSelector().resourceId(\"com.jianshu.haruki:id/iv_mine\")","context":"","multiple":false}
    
    # 返回200,成功查到元素
    2022-08-16 11:24:01:099 [WD Proxy] Got response with status 200: {"sessionId":"494dfb5e-42b3-4174-9365-ea4ede1a7f08","value":{"ELEMENT":"00000000-0000-003d-ffff-ffff0000003f","element-6066-11e4-a52e-4f735466cecf":"00000000-0000-003d-ffff-ffff0000003f"}}
    
    # appium-server把结果返回给客户端(script端),包含元素的描述符,后续元素操作会用到该描述符
    2022-08-16 11:24:01:099 [W3C (a335e892)] Responding to client with driver.findElement() result: {"element-6066-11e4-a52e-4f735466cecf":"00000000-0000-003d-ffff-ffff0000003f","ELEMENT":"00000000-0000-003d-ffff-ffff0000003f"}
    2022-08-16 11:24:01:100 [HTTP] <-- POST /wd/hub/session/a335e892-b061-48a4-8bf7-23e97c6a006e/element 200 4403 ms - 137
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    1. 元素查找成功后,执行元素操作的请求
    # 根据sessionid和获取element,执行click操作
    2022-08-16 11:24:01:102 [HTTP] --> POST /wd/hub/session/a335e892-b061-48a4-8bf7-23e97c6a006e/element/00000000-0000-003d-ffff-ffff0000003f/click
    2022-08-16 11:24:01:102 [HTTP] {"id":"00000000-0000-003d-ffff-ffff0000003f"}
    2022-08-16 11:24:01:104 [W3C (a335e892)] Calling AppiumDriver.click() with args: ["00000000-0000-003d-ffff-ffff0000003f","a335e892-b061-48a4-8bf7-23e97c6a006e"]
    2022-08-16 11:24:01:108 [WD Proxy] Matched '/element/00000000-0000-003d-ffff-ffff0000003f/click' to command name 'click'
    
    # 代理click请求给8200端口,通过8200端口forward给手机端的6790端口
    2022-08-16 11:24:01:108 [WD Proxy] Proxying [POST /element/00000000-0000-003d-ffff-ffff0000003f/click] to [POST http://127.0.0.1:8200/wd/hub/session/494dfb5e-42b3-4174-9365-ea4ede1a7f08/element/00000000-0000-003d-ffff-ffff0000003f/click] with body: {"element":"00000000-0000-003d-ffff-ffff0000003f"}
    
    # 操作成功,返回200
    2022-08-16 11:24:02:808 [WD Proxy] Got response with status 200: {"sessionId":"494dfb5e-42b3-4174-9365-ea4ede1a7f08","value":null}
    
    # appium-server返回结果给客户端
    2022-08-16 11:24:02:809 [W3C (a335e892)] Responding to client with driver.click() result: null
    2022-08-16 11:24:02:809 [HTTP] <-- POST /wd/hub/session/a335e892-b061-48a4-8bf7-23e97c6a006e/element/00000000-0000-003d-ffff-ffff0000003f/click 200 1707 ms - 14
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    总结

    appium原理:

    1. 启动appium-server服务,监听默认4723端口
    2. 定义desired_capabilities,实例化driver,通过/wd/hub/session请求appium-server
    3. 使用adb命令安装辅助工具appium-setting到手机设备上
    4. 使用adb命令安装辅助工具uiautomator2.server和uiautomator2.server.test到手机设备上
      • uiautomator2.server一个是驱动模块,负责创建会话session
      • uiautomator2.server.test是服务器模块,当驱动模块初始化完成,监听appium服务发送的请求,将请求发送给真正底层的UiAutomator2
    5. 端口映射,forward tcp:8200 tcp:6790,即当电脑上的8200端口收到请求会转发到手机的6790端口,8200是appium在电脑上占用的端口,主要为了和手机做端口映射,6790是手机设备上启动uiautomator2占用的端口
    6. 启动手机上的uiautomator2.server.test,会创建一个netty server,该netty server端口号就是6790,用来操作待测app
  • 相关阅读:
    进阶高级,接口+接口自动化测试疑难解答,一篇带你策底打通...
    DT Paint Effects工具(一)
    三种类的免费SSL证书
    使用腾讯云服务器安装宝塔Linux面板教程_图文全流程
    【numpy】numpy.where的使用
    攻克视频技术
    MyBatis-Plus之DQL编程控制
    sqlserver存储过程报错:当前事务无法提交,而且无法支持写入日志文件的操作。请回滚该事务。
    如何借助cpolar内网穿透连接本地树莓派(2)
    关于富文本编辑器wangeditor在vue3中的使用
  • 原文地址:https://blog.csdn.net/weixin_42517691/article/details/126372563