美文网首页
Appium UiAutomator2驱动:被测应用(APP)能

Appium UiAutomator2驱动:被测应用(APP)能

作者: Domibaba | 来源:发表于2023-08-04 12:36 被阅读0次

    Appium服务端会提供的一系列能力集合,Appium客户端通过构造键值对集合并发送给Appium服务端,以此来告诉服务器需要提供什么样的能力(例如建立与何种设备的通信,是Android还是ios设备、建链的超时时间等),也可以在运行过程中对服务端的行为进行修改。

    Appium提供的能力跟Driver相关,不同的Driver对应不同的测试对象,提供的能力以及所需要传入的参数都不一样,本文描述的是UiAutomator2 Driver提供的能力集合,它提供对Android设备的自动化测试支持。按照官方文档的定义,分为通用能力、Driver/Server能力等方面,本文介绍UiAutomator2提供的与被测应用相关的力能力集。

    本文所有测试代码的前提是已经安装Appium和相关环境(例如JDKAndroid SDKAVD模拟器),可以参考Appium环境搭建

    一、被测应用(APP)能力

    如下参数主要是用于操作被测设备上对被测应用。

    能力名称 具体描述
    appium:app 可选,表示被测应用的全路径(必须和运行的Appium服务端在同一个机器上)。可以支持apkapks两种扩展,以及通过URL指定的远程位置。如果appium:appappium:appPackagebrowserName三个参数均未提供,那么UiAutomator2驱动会从Dashboard开始启动,需要测试脚本去指定下一步动作。注意:appium:appbrowserName不能同时提供。
    browserName 可选,运行测试的浏览器,如果提供了该参数,UiAutomator2 Driver会默认在Web上下文模式中启动测试(默认是原生模式),通常可以设置为chrome
    appium:appPackage 可选,被测应用程序的包标识符,如果该参数未提供,则UiAutomator2 Driver会从appium:app参数中尝试自动获取。
    appium:appActivity 可选,主应用活动标识符,如果未提供,UiAutomator2 Driver会从appium:app参数中尝试自动获取。appium:appPackageappium:appActivity的获取方式可以参考这里
    appium:appWaitActivity 可选,等待启动的第一个活动标识符,如果该参数未设置,则等价于appium:appActivity
    appium:appWaitPackage 可选,等待启动的第一个应用程序标识符,如果该参数未提供,则等价于appium:appPackage
    appium:appWaitDuration 可选,被测应用启动的最大等待时间(应用活动的控制前返回到调用者),单位是毫秒,默认值是20000
    appium:androidInstallTimeout 可选,被测应用安装的最大等待时间,单位是毫秒,默认是90000
    appium:appWaitForLaunch 可选,应用活动被Activity Manger启(am命令)动之后,在控制权返到调用者(测试脚本)之前,调用者是否要阻塞并等待。默认是true(如果设置为false,调用者侧的测试会继续执行,而不会阻塞等待)。
    appium:intentCategory 可选,通过Activity Manger启动活动时,通过该参数指定的intent类别(categories),默认为android.intent.category.LAUNCHER。没有设置显式值的话请使用mobile:startActivity。备注:intent在此处是一个有专门含义的词,在Android中用于启动活动(activity),intent可以附加一些选项来启动活动,本参数就是其中的选项之一,可以参考本文第二部分对activityintent的介绍了解更多。
    appium:intentAction 可选,通过Activity Manger启动活动时,通过该参数指定的intent动作(action),默认为android.intent.action.MAIN。若没有设置显式值请使用mobile:startActivity
    appium:intentFlags 可选,通过Activity Manger启动活动时,通过该参数指定的intent标记,默认为0x10200000 (FLAG_ACTIVITY_NEW_TASK)`。
    appium:optionalIntentArguments 可选,通过Activity Manger启动活动时,通过该参数指定的intent参数。
    appium:dontStopAppOnReset 可选,当设置为true,可以避免正在运行的被测应用被重启。当appium:noReset被设置为false,那么被测应用在如下两种情况下会被重启:1)当该参数设置为false,或2)appium:forceAppLaunch被设置为true。该参数默认为false
    appium:forceAppLaunch 可选,当设置为true,被测应用在每次会话启动的时候都会被强制重启(即使appium:noReset被设置为true且被测应用也正在运行)。当appium:noReset被设置为false,那么被测应用在如下两种情况下会被重启:1)appium:dontStopAppOnReset被设置为false(默认值),或2)本参数被设置为true。本参数默认为falseUiAutomator2驱动2.12版本开始支持。
    appium:shouldTerminateApp 可选,当设置为true,被测应用在会话结束时会被关闭(即使appium:noReset的值是true)。当appium:noResetappium:dontStopAppOnReset均被设置为false时,被测应用会被关闭。该值默认为false
    appium:autoLaunch 可选,当设置为true时在测试开始时候自动启动被测应用,该值默认是true
    appium:autoGrantPermissions 可选,当设置为true时,在测试开始时自动授予全部请求的应用程序权限。要保证这一点,对版本的要求如下:1)被测应用manifest中的targetSdkVersion必须大于等于23,2)被测设备的Android版本必须大于等于Android 6(API level 23)。被测应用的targetSdkVersion若低于23,则需要重新安装,例如对于Android 6+设备将appium:fullReset设置为true。如果被测应用需要特定的权限,例如对通知和媒体记录的访问,考虑用appops目标的mobile: changePermissions扩展。
    appium:otherApps 可选,允许设置一个或多个逗号分隔Android安装包路径,这些包会跟被测应用程序一起安装。当被测应用程序对其他程序有依赖,需要设置这个参数。
    appium:uninstallOtherPackages 可选,允许设置一个或多个逗号分隔包标识符,这些包会在测试运行前从被测设备中卸载。
    appium:allowTestPackages 可选,如果设置为true,则能在自动化测试中使用以测试标志构建的包(通过使用adb install -t命令)。该值默认是false
    appium:remoteAppsCacheLimit 可选,测试过程中可以缓存到被测设备上的应用安装包最大数量。对于那些不支持流式安装的设备(Android 7及以下),ADB必须把包先推送到设备然后才能安装,因此需要消耗一些时间,需要配置该参数。可以通过设置该参数为0来禁止应用包缓存功能,该参数的默认值是10
    appium:enforceAppInstall 可选,如果设置为true,即使设备上的被测应用是更新的版本,该应用也会被强制重新安装。当appium:noReset参数设置为true时,本参数会不起作用。本参数默认值是false

    APP本地化能力集

    能力名称 具体描述
    appium:localeScript 可选,被测应用的规范化本地名称,例如zh-Hans-CN中的Hans。更多细节可以参考https://developer.android.com/reference/java/util/Locale.html
    appium:language 可选,指定提取被测应用字符串的语言名称,默认情况下,使用当前系统语言提取被测应用字符串。更多细节参考https://developer.android.com/reference/java/util/Locale.html
    appium:locale 可选,为被测应用设置区域。如果设置了本参数,那么同时也需要提供appium:language参数。

    二、能力解析

    • 关于Androidactivityintent的概念

      activity : activityAndroid应用程序的核心和基础概念,这里翻译成活动。可以把Android应用看成是一系列活动组成的,每个活动都可以进入和退出。活动可以简单类比成当前呈现出来的"屏幕",在当前屏幕中呈现出来的各种界面元素共同组成一个活动。要从当前屏幕呈现的界面切换到下一个,需要启动一个新的活动。从当前活动切换到下一个活动,并不局限只能在一个应用中,切换活动后,造成的结果可能是启动了一个新的应用。活动概念被设计出来主要是方便应用之间传递信息或复用。比如摄像机拍摄活动可以被各种应用启动,而不需要每个应用在需要改功能的时候单独去写一个摄像机拍摄的功能。如果已经连接上Android设备,可以使用adb提供的am命令(Activity Manger的缩写)来启动一个活动(-n参数指定名称),例如启动联系人列表:

      adb shell am start -n com.google.android.dialer/.extensions.GoogleDialtactsActivity

      intent:活动都是通过intent来启动的,这里翻译成意图,意图有两种类型:显式意图和隐式意图。显式意图是通过应用的名称和活动的名称(在应用的manifest文件中申明)来启动一个活动;隐式意图用于在单个应用内进行活动的切换。

      显式意图是直接指定应用的名称和活动的名称来启动一个活动;隐式意图则是通过已定义好用户意图来启动活动,例如指定启动活动的意图是android.intent.action.SET_WALLPAPER,那么Android系统会在设备上查找所有应用的所有活动,找到申请支持该意图的活动,然后启动该活动。如果找到支持意图的活动只有一个,那直接启动该活动即可,如果找到支持该意图的活动有多个呢?Android会所有支持该意图的活动弹出来让用户进行选择。在本文使用的模拟器设备上,执行adb shell am start -a android.intent.action.SET_WALLPAPER(-a参数表明这是一个动作意图)会出现3个支持该意图的活动供选择。

      更多细节可以参考文章What Appium Users Need to Know about Android Activities and Intents

      关于意图的更多参数介绍请参考这里

    • 通过设置appium:appPackageappium:appActivity启动一个指定应用

        # -*- coding: utf-8 -*-
        
        import pytest
        
        from appium import webdriver
        from appium.options.android import UiAutomator2Options
        from appium.webdriver.appium_service import AppiumService
        
        import time
        import datetime
        
        # 开启服务端
        APPIUM_HOST = '127.0.0.1'
        APPIUM_PORT = 4723
        @pytest.fixture(scope="session")
        def start_appium_service():
         server = AppiumService()
         server.start(args=['--address', APPIUM_HOST, '-p', str(APPIUM_PORT)], timeout_ms=60000)
         yield server
         server.stop()
        
        # 创建客户端到服务端的会话
        def create_appium_session_by_api(custom_opts = None):
         options = UiAutomator2Options()
         if custom_opts is not None:
         options.load_capabilities(custom_opts)
         return webdriver.Remote(f'http://{AP_intentPIUM_HOST}:{APPIUM_PORT}', options=options)
        
        def test_app_capability_explicit_intent(start_appium_service):
         driver = create_appium_session_by_api()
         driver.start_activity("com.google.android.dialer", ".extensions.GoogleDialtactsActivity")
    
    • 通过appium:appWaitActivityappium:appWaitPackage等待第一个被启动的应用和活动

      下面的代码会等待消息发送应用和活动打开,如果一直未等到该界面打开,那么会提示超时异常(超时时间通过appium:appWaitDuration指定,默认是20S),因此在启动下面的测试后,在超时时间之内,需要在命令行执行adb shell am start -n com.google.android.apps.messaging/.ui.ConversationListActivity以保证用例通过:

      def test_app_capability_appWaitActivity(start_appium_service):
         custom_opts = {
         "appium:appWaitPackage": "com.google.android.apps.messaging",
         "appium:appWaitActivity": ".ui.ConversationListActivity",
         }
         driver = create_appium_session_by_api(custom_opts)
         assert driver.current_activity == custom_opts["appium:appWaitActivity"]
    

      实际上,appium:appWaitActivityappium:appWaitPackage支持通配符处理。

    • 强制关闭被测应用
      def test_app_capability_closeAppAfterSession(start_appium_service):
         custom_opts = {
         "appium:noReset": True,
         "appium:appPackage": "com.google.android.apps.messaging",
         "appium:appActivity": ".ui.ConversationListActivity",
        
         "appium:shouldTerminateApp": True
         }
         driver = create_appium_session_by_api(custom_opts)
         assert driver.current_activity == custom_opts["appium:appActivity"]
         driver.quit()
        
         # 被测应用在上一步会话退出时已经被关闭了
         driver = create_appium_session_by_api({"appium:noReset": True})
         assert driver.current_activity != custom_opts["appium:appActivity"]
    

    相关文章

      网友评论

          本文标题:Appium UiAutomator2驱动:被测应用(APP)能

          本文链接:https://www.haomeiwen.com/subject/lpvvpdtx.html