Spectatio: framework de prueba para Automotive

Spectatio es un framework de prueba de código abierto desarrollado para probar Android Automotive OS (AAOS) en dispositivos reales y virtuales Spectatio proporciona APIs para pruebas de apps en un dispositivo de la industria automotriz y es una solución extensible y escalable que se utiliza para verificar la capacidad y el rendimiento de AAOS y sus aplicaciones.

Diseño de alto nivel

El framework Spectatio es adaptable y expandible para varias IU de AAOS. de Google Cloud. Se usa para probar la capacidad y el rendimiento de AAOS en hardware del dispositivo, emuladores y entornos virtualizados.

En la siguiente figura, se explica el diseño de alto nivel del framework Spectatio.

Framework de Spectatio con diseño de alto nivel

Figura 1: Diseño de alto nivel del framework de Spectatio.

El framework de Spectatio se basa en UI Automator y proporciona un conjunto de APIs. para compilar pruebas de IU que interactúen con apps de usuarios y sistemas en AAOS. Automotriz las pruebas usan las APIs proporcionadas por el framework Spectatio para realizar pruebas, lo que facilita estas pruebas independientemente del dispositivo que se está probando (DUT) y escalables para probar diversos dispositivos, si son compatibles.

En la Figura 1, se muestra que el framework de Spectatio está modularizado según las referencias apps como Teléfono, Medicenter y Configuración usando apps específicas interfaces de usuario y asistentes, lo que facilita su adaptación a apps nuevas. El espectáculo reutilice las clases auxiliares estándar y de utilidad comunes. La clase auxiliar estándar es la clase superior de todas las funciones auxiliares de la app y proporciona funciones estándar que son específicas del dispositivo o aplicables a todas las apps. El las clases de ayuda de utilidades ofrecen utilidades como leer o escribir archivos desde el dispositivo.

Arquitectura

A fin de proporcionar un conjunto de APIs para compilar pruebas de IU, el framework de Spectatio implementa interfaces y asistentes específicos de la app, a la vez que amplías el asistente estándar existente e importar las clases auxiliares de utilidad.

En la Figura 2, se ilustra la arquitectura de alto nivel del framework de Spectatio. todas las entidades involucradas en la implementación de APIs para probar una app.

Arquitectura de alto nivel del framework de Spectatio

Figura 2: Arquitectura de alto nivel del framework de Spectatio.

La interfaz de ayuda de la app proporciona un modelo para la implementación de un asistente de aplicaciones. Consta de varias funciones auxiliares necesarias para probar apps. Cada app tiene su propia interfaz, como IAutoSettingHelper. y IAutoDialHelper. Para obtener más información y una lista de funciones de la interfaz, consulta las funciones de interfaz auxiliares de la app en AOSP.

La clase auxiliar estándar consta de atributos y funciones estándares que se se requieren para la configuración del dispositivo, pero no son específicos para ninguna app, como pressHome y scroll. La clase auxiliar estándar se define en AbstractAutoStandardAppHelper.java.

El framework usa las clases auxiliares de utilidad. Para Por ejemplo, AutoJsonUtility.java es un clase de utilidad que carga el archivo de configuración JSON del dispositivo determinado y las actualizaciones los parámetros de configuración del framework en el entorno de ejecución.

El módulo de implementación auxiliar de la app es el núcleo de Spectatio en un framework de nube. Contiene la implementación de las funciones auxiliares definidas en la interfaz de ayuda de la app, que se requieren para probar apps en un de un dispositivo de automóviles. Cada app tiene su propia implementación, como SettingHelperImpl. y DialHelperImpl, utilizado por las pruebas de Automotive para probar las apps. Para obtener más información y una lista de consulta las funciones de implementación auxiliares de la app en AOSP.

Pruebas de vehículos Usar las funciones de implementación auxiliares de la app para probar varias operaciones relacionadas con la app. Usa la clase HelperAccessor para obtener acceso a las funciones de implementación auxiliares de la app.

En el siguiente código, se muestran la configuración, la limpieza y la ejecución de una muestra para pruebas de automóviles.

@RunWith(AndroidJUnit4.class)
public class AutoApplicationTest {
  static HelperAccessor<IAutoApplicationHelper> autoApplicationHelper =
          new HelperAccessor<>(IAutoApplicationHelper.class);

  public AutoApplicationTest() {
    // constructor
    // Initialize any attributes that are required for the test execution
  }

  @Before
  public void beforeTest() {
    // Initial setup before each test
    // For example - open the app
    autoApplicationHelper.open();
  }

  @After
  public void afterTest() {
    // Cleanup after each test.
    // For example - exit the app
    autoApplicationHelper.exit();
  }

  @Test
  public void testApplicationFeature() {
    // Test
    // For example - Test if app is open
    assertTrue("Application is not open.", autoApplicationHelper.isOpen());
  }
}

Personalización

El framework de Spectatio es independiente de la IU del dispositivo, por lo que es escalable para dispositivos de prueba con diversas IUs y hardware. Para lograr esta escalabilidad, Spectatio usa configuraciones de dispositivos predeterminadas según el dispositivo de referencia. Para admiten configuraciones de dispositivos no predeterminadas, el framework usa un archivo en el entorno de ejecución para establecer los cambios deseados en la IU del dispositivo. R El archivo de configuración JSON admite elementos de la IU como TEXT, DESCRIPTION y RESOURCE_ID, junto con la configuración de path, y debe contener solo la información sobre los cambios en la IU del DUT. El resto de los elementos de la IU usan la configuración de configuración proporcionados en el framework.

Parámetros de configuración predeterminados de los dispositivos

En el siguiente ejemplo de archivo de configuración JSON, se muestra el dispositivo disponible parámetros de configuración y sus valores predeterminados.

Haz clic aquí para mostrar un JSON de muestra archivo de configuración

    {
        "SETTINGS": {
                "APPLICATION_CONFIG": {
                        "SETTINGS_TITLE_TEXT": "Settings",
                        "SETTINGS_PACKAGE": "com.android.car.settings",
                        "SETTINGS_RRO_PACKAGE": "com.android.car.settings.googlecarui.rro",
                        "OPEN_SETTINGS_COMMAND": "am start -a android.settings.SETTINGS",
                        "OPEN_QUICK_SETTINGS_COMMAND": "am start -n com.android.car.settings/com.android.car.settings.common.CarSettingActivity"
                },
                "QUICK_SETTINGS": {
                        "OPEN_MORE_SETTINGS": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "toolbar_menu_item_1",
                                "PACKAGE": "com.android.car.settings"
                        },
                        "NIGHT_MODE": {
                                "TYPE": "TEXT",
                                "VALUE": "Night mode"
                        }
                },
                "DISPLAY": {
                        "PATH": "Settings > Display",
                        "OPTIONS": [
                                "Brightness level"
                        ],
                        "BRIGHTNESS_LEVEL": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "seekbar",
                                "PACKAGE": "com.android.car.settings"
                        }
                },
                "SOUND": {
                        "PATH": "Settings > Sound",
                        "OPTIONS": [
                                "Media volume",
                                "Alarm volume"
                        ]
                },
                "NETWORK_AND_INTERNET": {
                        "PATH": "Settings > Network & internet",
                        "OPTIONS": [
                        ],
                        "TOGGLE_WIFI": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "master_switch",
                                "PACKAGE": "com.android.car.settings"
                        }
                },
                "BLUETOOTH": {
                        "PATH": "Settings > Bluetooth",
                        "OPTIONS": [
                        ],
                        "TOGGLE_BLUETOOTH": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "car_ui_toolbar_menu_item_switch",
                                "PACKAGE": "com.android.car.settings"
                        }
                },
                "APPS_AND_NOTIFICATIONS": {
                        "PATH": "Settings > Apps & notifications",
                        "OPTIONS": [
                        ],
                        "SHOW_ALL_APPS": {
                                "TYPE": "TEXT",
                                "VALUE": "Show all apps"
                        },
                        "ENABLE_DISABLE_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "car_ui_toolbar_menu_item_text",
                                "PACKAGE": "com.android.car.settings"
                        },
                        "DISABLE_BUTTON_TEXT": {
                                "TYPE": "TEXT",
                                "VALUE": "Disable"
                        },
                        "ENABLE_BUTTON_TEXT": {
                                "TYPE": "TEXT",
                                "VALUE": "Enable"
                        },
                        "DISABLE_APP_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "DISABLE APP"
                        },
                        "FORCE_STOP_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Force stop"
                        },
                        "OK_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "OK"
                        },
                        "PERMISSIONS_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "Permissions"
                        },
                        "ALLOW_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Allow"
                        },
                        "DENY_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Deny"
                        },
                        "DENY_ANYWAY_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Deny anyway"
                        }
                },
                "DATE_AND_TIME": {
                        "PATH": "Settings > Date & time",
                        "OPTIONS": [
                                "Automatic date & time",
                "Automatic time zone"
                        ],
                        "AUTOMATIC_DATE_AND_TIME": {
                                "TYPE": "TEXT",
                                "VALUE": "Automatic date & time"
                        },
                        "AUTOMATIC_TIME_ZONE": {
                                "TYPE": "TEXT",
                                "VALUE": "Automatic time zone"
                        },
                        "SET_DATE": {
                                "TYPE": "TEXT",
                                "VALUE": "Set date"
                        },
                        "SET_TIME": {
                                "TYPE": "TEXT",
                                "VALUE": "Set time"
                        },
                        "SELECT_TIME_ZONE": {
                                "TYPE": "TEXT",
                                "VALUE": "Select time zone"
                        },
                        "USE_24_HOUR_FORMAT": {
                                "TYPE": "TEXT",
                                "VALUE": "Use 24-hour format"
                        },
                        "OK_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "toolbar_menu_item_0",
                                "PACKAGE": "com.android.car.settings"
                        },
                        "NUMBER_PICKER_WIDGET": {
                                "TYPE": "CLASS",
                                "VALUE": "android.widget.NumberPicker"
                        },
                        "EDIT_TEXT_WIDGET": {
                                "TYPE": "CLASS",
                                "VALUE": "android.widget.EditText"
                        }
                },
                "USERS": {
                        "PATH": "Settings > Users",
                        "OPTIONS": [
                                "Guest"
                        ]
                },
                "ACCOUNTS": {
                        "PATH": "Settings > Accounts",
                        "OPTIONS": [
                                "Automatically sync data"
                        ],
                        "ADD_ACCOUNT": {
                                "TYPE": "TEXT",
                                "VALUE": "ADD ACCOUNT"
                        },
                        "ADD_GOOGLE_ACCOUNT": {
                                "TYPE": "TEXT",
                                "VALUE": "Google"
                        },
                        "SIGN_IN_ON_CAR_SCREEN": {
                                "TYPE": "TEXT",
                                "VALUE": "Sign in on car screen"
                        },
                        "GOOGLE_SIGN_IN_SCREEN": {
                                "TYPE": "TEXT",
                                "VALUE": "Sign in to your Google Account"
                        },
                        "ENTER_EMAIL": {
                                "TYPE": "CLASS",
                                "VALUE": "android.widget.EditText"
                        },
                        "ENTER_PASSWORD": {
                                "TYPE": "CLASS",
                                "VALUE": "android.widget.EditText"
                        },
                        "NEXT_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Next"
                        },
                        "DONE_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Done"
                        },
                        "REMOVE_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Remove"
                        },
                        "REMOVE_ACCOUNT_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Remove Account"
                        }
                },
                "SYSTEM": {
                        "PATH": "Settings > System",
                        "OPTIONS": [
                                "About", "Legal information"
                        ],
                        "ABOUT_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "About"
                        },
                        "RESET_OPTIONS_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "Reset options"
                        },
                        "LANGUAGES_AND_INPUT_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "Languages & input"
                        },
                        "DEVICE_MODEL": {
                                "TYPE": "TEXT",
                                "VALUE": "Model"
                        },
                        "ANDROID_VERSION": {
                                "TYPE": "TEXT",
                                "VALUE": "Android version"
                        },
                        "ANDROID_SECURITY_PATCH_LEVEL": {
                                "TYPE": "TEXT",
                                "VALUE": "Android security patch level"
                        },
                        "KERNEL_VERSION": {
                                "TYPE": "TEXT",
                                "VALUE": "Kernel version"
                        },
                        "BUILD_NUMBER": {
                                "TYPE": "TEXT",
                                "VALUE": "Build number"
                        },
                        "RECYCLER_VIEW_WIDGET": {
                                "TYPE": "CLASS",
                                "VALUE": "androidx.recyclerview.widget.RecyclerView"
                        },
                        "RESET_NETWORK": {
                                "TYPE": "TEXT",
                                "VALUE": "Reset network"
                        },
                        "RESET_SETTINGS": {
                                "TYPE": "TEXT",
                                "VALUE": "RESET SETTINGS"
                        },
                        "RESET_APP_PREFERENCES": {
                                "TYPE": "TEXT",
                                "VALUE": "Reset app preferences"
                        },
                        "RESET_APPS": {
                                "TYPE": "TEXT",
                                "VALUE": "RESET APPS"
                        },
                        "LANGUAGES_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "Languages"
                        },
                        "LANGUAGES_MENU_IN_SELECTED_LANGUAGE": {
                                "TYPE": "TEXT",
                                "VALUE": "Idiomas"
                        }
                },
                "SECURITY": {
                        "PATH": "Settings > Security",
                        "OPTIONS": [
                        ],
                        "TITLE": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "car_ui_toolbar_title",
                                "PACKAGE": "com.android.car.settings.googlecarui.rro"
                        },
                        "CHOOSE_LOCK_TYPE": {
                                "TYPE": "TEXT",
                                "VALUE": "Choose a lock type"
                        },
                        "LOCK_TYPE_PASSWORD": {
                                "TYPE": "TEXT",
                                "VALUE": "Password"
                        },
                        "LOCK_TYPE_PIN": {
                                "TYPE": "TEXT",
                                "VALUE": "PIN"
                        },
                        "LOCK_TYPE_NONE": {
                                "TYPE": "TEXT",
                                "VALUE": "None"
                        },
                        "CONTINUE_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Continue"
                        },
                        "CONFIRM_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Confirm"
                        },
                        "ENTER_PASSWORD": {
                                "TYPE": "CLASS",
                                "VALUE": "android.widget.EditText"
                        },
                        "PIN_PAD": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "pin_pad",
                                "PACKAGE": "com.android.car.settings"
                        },
                        "ENTER_PIN_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "key_enter",
                                "PACKAGE": "com.android.car.settings"
                        },
                        "REMOVE_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Remove"
                        }
                }
        },
        "PHONE": {
                "APPLICATION_CONFIG": {
                        "DIAL_PACKAGE": "com.android.car.dialer",
                        "PHONE_ACTIVITY": "com.android.car.dialer/.ui.TelecomActivity",
                        "OPEN_DIAL_PAD_COMMAND": "am start -a android.intent.action.DIAL"
                },
                "IN_CALL_VIEW": {
                        "DIALED_CONTACT_TITLE": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "user_profile_title",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "DIALED_CONTACT_NUMBER": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "user_profile_phone_number",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "END_CALL": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "end_call_button",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "MUTE_CALL": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "mute_button",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "SWITCH_TO_DIAL_PAD": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "toggle_dialpad_button",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "CHANGE_VOICE_CHANNEL": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "voice_channel_view",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "VOICE_CHANNEL_CAR": {
                                "TYPE": "TEXT",
                                "VALUE": "Car speakers"
                        },
                        "VOICE_CHANNEL_PHONE": {
                                "TYPE": "TEXT",
                                "VALUE": "Phone"
                        }
                },
                "DIAL_PAD_VIEW": {
                        "DIAL_PAD_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "Dial Pad"
                        },
                        "DIAL_PAD_FRAGMENT": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "dialpad_fragment",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "DIALED_NUMBER": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "title",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "MAKE_CALL": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "call_button",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "DELETE_NUMBER": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "delete_button",
                                "PACKAGE": "com.android.car.dialer"
                        }
                },
                "CONTACTS_VIEW": {
                        "CONTACTS_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "Contacts"
                        },
                        "CONTACT_INFO": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "call_action_id",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "CONTACT_NAME": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "title",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "CONTACT_DETAIL": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "show_contact_detail_id",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "ADD_CONTACT_TO_FAVORITE": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "contact_details_favorite_button",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "SEARCH_CONTACT": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "menu_item_search",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "CONTACT_SEARCH_BAR": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "car_ui_toolbar_search_bar",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "SEARCH_RESULT": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "contact_name",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "CONTACT_SETTINGS": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "menu_item_setting",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "CONTACT_ORDER": {
                                "TYPE": "TEXT",
                                "VALUE": "Contact order"
                        },
                        "SORT_BY_FIRST_NAME": {
                                "TYPE": "TEXT",
                                "VALUE": "First name"
                        },
                        "SORT_BY_LAST_NAME": {
                                "TYPE": "TEXT",
                                "VALUE": "Last Name"
                        },
                        "CONTACT_TYPE_WORK": {
                                "TYPE": "TEXT",
                                "VALUE": "Work"
                        },
                        "CONTACT_TYPE_MOBILE": {
                                "TYPE": "TEXT",
                                "VALUE": "Mobile"
                        },
                        "CONTACT_TYPE_HOME": {
                                "TYPE": "TEXT",
                                "VALUE": "Home"
                        }
                },
                "CALL_HISTORY_VIEW": {
                        "CALL_HISTORY_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "Recents"
                        },
                        "CALL_HISTORY_INFO": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "call_action_id",
                                "PACKAGE": "com.android.car.dialer"
                        }
                },
                "FAVORITES_VIEW": {
                        "FAVORITES_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "Favorites"
                        }
                }
        },
        "NOTIFICATIONS": {
                "APPLICATION_CONFIG": {
                        "OPEN_NOTIFICATIONS_COMMAND": "service call statusbar 1"
                },
                "EXPANDED_NOTIFICATIONS_SCREEN": {
                        "NOTIFICATION_VIEW": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "notification_view",
                                "PACKAGE": "com.android.systemui"
                        },
                        "CLEAR_ALL_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "clear_all_button",
                                "PACKAGE": "com.android.systemui"
                        },
                        "STATUS_BAR": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "car_top_navigation_bar_container",
                                "PACKAGE": "com.android.systemui"
                        },
                        "APP_ICON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "app_icon",
                                "PACKAGE": "com.android.systemui"
                        },
                        "APP_NAME": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "header_text",
                                "PACKAGE": "com.android.systemui"
                        },
                        "NOTIFICATION_TITLE": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "notification_body_title",
                                "PACKAGE": "com.android.systemui"
                        },
                        "NOTIFICATION_BODY": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "notification_body_content",
                                "PACKAGE": "com.android.systemui"
                        },
                        "CARD_VIEW": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "card_view",
                                "PACKAGE": "com.android.systemui"
                        }
                }
        },
        "MEDIA_CENTER": {
                "APPLICATION_CONFIG": {
                        "MEDIA_CENTER_PACKAGE": "com.android.car.media",
                        "MEDIA_ACTIVITY": "com.android.bluetooth/com.android.bluetooth.avrcpcontroller.BluetoothMediaBrowserService"
                },
                "MEDIA_CENTER_SCREEN": {
                        "PLAY_PAUSE_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "play_pause_stop",
                                "PACKAGE": "com.android.car.media"
                        },
                        "NEXT_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "skip_next",
                                "PACKAGE": "com.android.car.media"
                        },
                        "PREVIOUS_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "skip_prev",
                                "PACKAGE": "com.android.car.media"
                        },
                        "SHUFFLE_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "overflow_on",
                                "PACKAGE": "com.android.car.media"
                        },
                        "PLAY_QUEUE_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "play_queue",
                                "PACKAGE": "com.android.car.media"
                        },
                        "MINIMIZED_MEDIA_CONTROLS": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "minimized_playback_controls",
                                "PACKAGE": "com.android.car.media"
                        },
                        "TRACK_NAME": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "title",
                                "PACKAGE": "com.android.car.media"
                        },
                        "TRACK_NAME_MINIMIZED_CONTROL": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "minimized_control_bar_title",
                                "PACKAGE": "com.android.car.media"
                        },
                        "BACK_BUTTON": {
                                "TYPE": "DESCRIPTION",
                                "VALUE": "Back"
                        }
                },
                "MEDIA_CENTER_ON_HOME_SCREEN": {
                        "PLAY_PAUSE_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "play_pause_stop",
                                "PACKAGE": "com.android.car.carlauncher"
                        },
                        "NEXT_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "skip_next",
                                "PACKAGE": "com.android.car.carlauncher"
                        },
                        "PREVIOUS_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "skip_prev",
                                "PACKAGE": "com.android.car.carlauncher"
                        },
                        "TRACK_NAME": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "title",
                                "PACKAGE": "com.android.car.carlauncher"
                        }
                }
        }
}
  

Configuraciones alternativas de dispositivos

En la siguiente muestra de código, se muestra un ejemplo del archivo de configuración JSON en el que la configuración predeterminada se anula con la del DUT. En este ejemplo:

  • La configuración de Internet se denomina Red & Internet en dispositivos de referencia y Conectividad en el DUT.

  • La configuración de fecha y hora está disponible en Configuración > Fecha y hora de dispositivos de referencia y en Configuración > Sistema > Fecha y hora del DUT

// Default configuration file
{
    ....
    "SECURITY_SETTINGS_SCROLL_ELEMENT": {
      "TYPE": "RESOURCE_ID",
      "VALUE": "fragment_container",
    },
    ....
}

// JSON configuration file for non-reference device
{
    ....
    "SECURITY_SETTINGS_SCROLL_ELEMENT": {
      "TYPE": "RESOURCE_ID",
      "VALUE": "car_ui_recycler_view"
    },
    ....
}

Cuando el archivo de configuración JSON está listo, se proporciona en el entorno de ejecución, como se muestra en el siguiente bloque de código:

# Push The JSON configuration file to the device
adb -s DEVICE-SERIAL push PATH-OF-JSON-FILE /data/local/tmp/runtimeSpectatioConfig.json

En este comando:

  • DEVICE-SERIAL: Es el ID de serie del DUT. Este parámetro no es se requiere si solo hay un dispositivo conectado al host.

  • PATH-TO-JSON-FILE: Es la ruta de acceso al archivo JSON en la máquina anfitrión.

Formato de configuración

Hay cinco objetos de nivel superior en la configuración, con las siguientes claves y sus valores:

Objeto Descripción
PACKAGES Un objeto que describe el paquete principal de varias apps, que se usa para determinar cuándo la app está en primer plano.
ACTIONS Un objeto que indica tipos de acciones y parámetros para varias acciones. Por ejemplo, si se deben usar botones o un gesto para desplazarse.
COMMANDS Un objeto que especifica comandos que realizan varias acciones.
UI_ELEMENTS Un objeto que se usa para construir "BySelectors" de UI Automator que seleccionan IU Elementos (que se describen en detalle a continuación).
WORKFLOWS Secuencias de acciones que realizan tareas de alto nivel (descritas en a continuación).

Elementos de la IU

Cada elemento de la IU tiene un TYPE que especifica lo que UI Automator buscará para identificar el elemento (como el ID del recurso, el texto y la descripción) de configuración asociados con ese tipo. En general, siempre que un asistente identifica un elemento en la pantalla mediante esta configuración, obtiene un elemento. Si varios elementos coinciden con la configuración, se asigna uno arbitrario que se usó en la prueba. Por lo tanto, la configuración (generalmente) se debe escribir lo suficientemente específico como para que se limite a un elemento en el contexto relevante.

TEXTO

Este es el tipo de elemento de IU más simple. El elemento de la IU se identifica por su texto, y requiere una concordancia exacta.

    "CALL_HISTORY_MENU": {
      "TYPE": "TEXT",
      "VALUE": "Recents"
    }

TEXT_CONTIENE

Es igual que TEXT, con la excepción de que el VALUE especificado solo debe aparecer en algún lugar de el texto del elemento con el que se buscarán coincidencias.

    "PRIVACY_CALENDAR": {
      "TYPE": "TEXT_CONTAINS",
      "VALUE": "Calendar"
    }

DESCRIPCIÓN

Identificar el elemento por su atributo de descripción de contenido, y se requiere una indicación la coincidencia.

    "APP_GRID_SCROLL_BACKWARD_BUTTON": {
      "TYPE": "DESCRIPTION",
      "VALUE": "Scroll up"
    }

ID_RECURSO

Identifica el elemento por su ID de recurso y, opcionalmente, también puedes verificar el paquete de ese ID. La clave PACKAGE es opcional. si se omite, cualquier paquete coincidirá y solo se considerará la parte del ID posterior a :id/.

    "APP_LIST_SCROLL_ELEMENT": {
      "TYPE": "RESOURCE_ID",
      "VALUE": "apps_grid",
      "PACKAGE": "com.android.car.carlauncher"
    }

SE PUEDE HACER CLIC Y DESACTIVAR

Identifica el elemento según si se puede hacer clic (o no) o si se puede desplazar. Estos son tipos de elementos muy amplios y, por lo general, solo deben usarse en un MULTIPLE para ayudar a acotar otro tipo de elemento. La clave FLAG es opcional. y la configuración predeterminada es true.

    "SAMPLE_ELEMENT": {
      "TYPE": "CLICKABLE",
      "FLAG": false
    }

CLASE

Identifica el elemento según su clase.

    "SECURITY_SETTINGS_ENTER_PASSWORD": {
      "TYPE": "CLASS",
      "VALUE": "android.widget.EditText"
    }

HAS_ANCESTOR

Identifica el elemento buscando la jerarquía de widgets en sus principales. El La clave ANCESTOR contiene un objeto que identifica al principal. La tecla DEPTH especifica cuán arriba en la jerarquía se debe ver. DEPTH es opcional y tiene un valor predeterminado de 1.

      "SAMPLE_ELEMENT": {
      "TYPE": "HAS_ANCESTOR",
      "DEPTH": 2,
      "ANCESTOR": {
        "TYPE": "CLASS",
        "VALUE": "android.view.ViewGroup"
      }
    }

HAS_DESCENDANT

Identifica el elemento mirando hacia abajo en la jerarquía, en sus elementos secundarios. El La clave DESCENDANT contiene un objeto que especifica el elemento secundario que se debe buscar. El La clave DEPTH especifica qué tan arriba en la jerarquía debe verse. DEPTH es opcional y tiene un valor predeterminado de 1.

      "SAMPLE_ELEMENT": {
      "TYPE": "HAS_DESCENDANT",
      "DEPTH": 2,
      "DESCENDANT": {
        "TYPE": "CLASS",
        "VALUE": "android.view.ViewGroup"
      }
    }

VARIOS

Identificar el elemento en función de múltiples condiciones simultáneas, las cuales se deben cumplir.

      "APP_INFO_SETTINGS_PERMISSION_MANAGER": {
      "TYPE": "MULTIPLE",
      "SPECIFIERS": [
        {
          "TYPE": "CLASS",
          "VALUE": "android.widget.RelativeLayout"
        },
        {
          "TYPE": "HAS_DESCENDANT",
          "MAX_DEPTH": 2,
          "DESCENDANT": {
            "TYPE": "TEXT",
            "VALUE": "Permission manager"
          }
        }
      ]
    }

En este ejemplo, la configuración identifica un RelativeLayout que tiene un subordinado con 2 de profundidad, que tiene el texto Permission manager.

Workflows

Un flujo de trabajo representa una secuencia de acciones utilizadas para lograr un tarea, que puede diferir lo suficiente de un tipo de dispositivo a otro y es más más flexibles para representar en la configuración que en el código.

    "WORKFLOWS": {
    "OPEN_SOUND_SETTINGS_WORKFLOW": [
      {
        "NAME": "Go to Home",
        "TYPE": "PRESS",
        "CONFIG": {
          "TEXT": "HOME"
        }
      },
      {
        "NAME": "Open Settings",
        "TYPE": "COMMAND",
        "CONFIG": {
          "TEXT": "am start -a android.settings.SETTINGS"
        }
      },
      {
        "NAME": "Open Sound Settings",
        "TYPE": "SCROLL_TO_FIND_AND_CLICK",
        "CONFIG": {
          "UI_ELEMENT": {
            "TYPE": "TEXT",
            "VALUE": "Sound"
          }
        },
        "SCROLL_CONFIG": {
          "SCROLL_ACTION": "USE_GESTURE",
          "SCROLL_DIRECTION": "VERTICAL",
          "SCROLL_ELEMENT": {
            "TYPE": "RESOURCE_ID",
            "VALUE": "car_ui_recycler_view"
          }
        }
      }
    ]
  }

Cada flujo de trabajo es un par clave-valor en el que la clave es el nombre del flujo de trabajo y el valor es un array de acciones para realizar. Cada acción tiene un NAME, un TYPE, (por lo general) un CONFIG y (a veces) un SWIPE_CONFIG o SCROLL_CONFIG. Para la mayoría de los TYPEs, el CONFIG es un objeto con una clave UI_ELEMENT cuyo valor toma de la misma forma que una entrada de elemento de la IU (ver arriba). Estos TYPE son:

PRESS
LONG_PRESS
CLIC
LONG_CLIC
CLIC_IF_EXIST
HAS_UI_ELEMENT_IN_FOREGROUND
DESPLAZAMIENTO_PARA_ENCONTRAR_Y_CLIC
SCROLL_TO_FIND_AND_CLIC_IF_EXIST
SWIPE_TO_FIND_AND_CLIC
SWIPE_TO_FIND_AND_CLIC_IF_EXISTE

Para los otros TIPOS, los detalles de configuración son:

Objeto Descripción
COMMAND Un objeto con un valor TEXT que contiene el comando que se ejecutará.
HAS_PACKAGE_IN_FOREGROUND Un objeto con un valor TEXT que contiene el paquete.
SWIPE Omite CONFIG key para una acción SWIPE. Esta solo usa SWIPE_CONFIG
WAIT_MS Un objeto con un valor TEXT que contiene la cantidad de milisegundos que esperar.

Las acciones relacionadas con el desplazamiento y el deslizamiento requieren una configuración adicional, como se indica a continuación:

DESPLAZAMIENTO_CONFIGURACIÓN

Objeto Descripción
SCROLL_ACTION USE_GESTURE o USE_BUTTON
SCROLL_DIRECTION HORIZONTAL o VERTICAL
SCROLL_ELEMENT Un objeto que indica el contenedor que se debe desplazar, con el mismo formato que una IU Configuración del elemento (ver arriba).
SCROLL_FORWARD, SCROLL_BACKWARD Los botones de desplazamiento hacia adelante y hacia atrás (necesarios cuando SCROLL_ACTION es USE_BUTTON).
SCROLL_MARGIN Si SCROLL_ACTION es USE_GESTURE, la distancia desde el borde del contenedor para iniciar y detener el arrastre que se usará para realizar el desplazamiento (opcional, predeterminado = 10).
SCROLL_WAIT_TIME Si SCROLL_ACTION es USE_GESTURE, la hora en milisegundos para esperar entre los gestos de desplazamiento cuando se busca un objeto y o hacer clic. (Opcional, valor predeterminado = 1).

SWIPE_CONFIGURA

Objeto Descripción
SWIPE_DIRECTION TOP_TO_BOTTOM, BOTTOM_TO_TOP, LEFT_TO_RIGHT o RIGHT_TO_LEFT
SWIPE_FRACTION

Una de las siguientes opciones:

  • FULL: Desliza el gesto de un borde a otro de la pantalla

    O
  • DEFAULT: De borde a pantalla, con un cinco (5) de píxeles a cada lado.

    O BIEN:
  • THREE_QUARTER, HALF o QUARTER: El gesto de deslizamiento finaliza cinco (5) píxeles desde el borde de la pantalla y comienza en el punto que cubre la distancia indicada de la pantalla.
NUMBER_OF_STEPS La cantidad de pasos que se deben seguir para realizar el deslizamiento. Consulta los segmentSteps.

Compila y ejecuta

El framework de Spectatio se compila automáticamente como parte del APK de prueba. Para compilar el APK de prueba, la base de código AOSP debe residir en la estación de trabajo local. Después del de prueba se compila el APK de prueba, el usuario debe instalarlo en el dispositivo y ejecutar la la prueba.

En el siguiente ejemplo de código, se muestra la compilación, la instalación y la ejecución de un APK de prueba.

# Build Test APK
make TEST-APK-NAME
# Install Test APK
adb -s DEVICE-SERIAL install -r PATH-FOR-BUILT-TEST-APK
# Execute Test with the JSON file
adb -s DEVICE-SERIAL shell am instrument -w -r -e debug false -e config-file-path /data/local/tmp/jsonFile.json -e class TEST-PACKAGE.TEST-CLASSNAME TEST-PACKAGE/androidx.test.runner.AndroidJUnitRunner

En estos comandos:

  • TEST-APK-NAME: Es el nombre de la app que se probará. Por ejemplo, establece TEST-APK-NAME a AndroidAutomotiveSettingsTests para probar la configuración de Wi-Fi como se especifica en Android.bp . El nombre del APK se puede encontrar en el archivo Android.bp respectivo de la prueba de Automotive.

  • DEVICE-SERIAL: Es el ID de serie del DUT. Este parámetro no es se requiere si solo hay un dispositivo conectado al host.

  • config-file-path: Parámetro opcional que solo se requiere para proporcionar parámetros de configuración de la IU del dispositivo no predeterminados, como se especifica en la sección de configuración de JSON archivo. Si no se proporciona, el usa valores predeterminados para ejecutar las pruebas.

  • PATH-FOR-BUILT-TEST-APK: Es la ruta de acceso en la que se compila el APK de prueba. Cuando se ejecuta el comando make.

  • TEST-PACKAGE: Es el nombre del paquete de prueba.

  • TEST-CLASSNAME: Es el nombre de la clase de prueba. Por ejemplo, para la Wi-Fi Settings, el paquete de prueba es android.platform.tests y el el nombre de la clase de prueba es WifiSettingTest.

Biblioteca de fragmentos de Automotive

La Biblioteca de fragmentos de Automotive es un conjunto de bibliotecas de Android Test para el Proyecto de código abierto de Android (AOSP) diseñado para interactuar con la industria automotriz y servicios de Google. Aprovecha Spectatio con un mecanismo conveniente para ejecutar llamadas de procedimiento remoto (RPC) desde una máquina host (de prueba) a un Dispositivo con Android.

Comenzar

Antes de comenzar, revisa estas secciones.

Requisitos previos

  • Python 3.x instalado en la máquina anfitrión.
  • Configuración del entorno de AOSP con las herramientas de compilación necesarias.
  • Un dispositivo Android Automotive (emulador o dispositivo físico) con acceso a adb

Compilación

Para compilar los distintos fragmentos que proporciona la Biblioteca de fragmentos de Automotive, puedes hacer lo siguiente: puedes usar el archivo android.bp proporcionado. Si sigues los comandos en la clase anterior para compilar el APK.

Implementación

Luego de compilar correctamente las bibliotecas de fragmentos, implementa los APK resultantes en el dispositivo de destino con el comando adb install que se mencionó antes sección.

Cómo ejecutar pruebas

Las bibliotecas de fragmentos exponen varios métodos de RPC para interactuar con la industria automotriz en un sistema de archivos. Estos métodos pueden invocarse mediante el framework de Mobly desde el host máquina. Suponiendo que tienes configurado el entorno de pruebas de Mobly, puedes utilizar el Secuencia de comandos snippet_shell.py para abrir una shell interactiva de Python, en la que puedes invocar manualmente métodos de RPC en el dispositivo. Ejemplo de invocación:

python3 snippet_shell.py com.google.android.mobly.snippet.bundled -s <serial>

Reemplaza <serial> por el número de serie del dispositivo, que puedes obtener con Dispositivos adb si hay varios dispositivos conectados.

Bibliotecas incluidas

La Biblioteca de fragmentos de Automotive incluye las siguientes bibliotecas de fragmentos y auxiliares:

  • AutomotiveFragment: Proporciona APIs relacionadas con las operaciones de vehículos, como las siguientes: marcado, control de volumen, teclas físicas del vehículo e interacción con el centro multimedia.

  • PhoneFragment: Proporciona APIs relacionadas con la telefonía, incluidos el manejo de llamadas, navegación de contactos y operaciones de SMS.

El fragmento de Automotive y el Phonesnippet comparten una lógica en común. Específicamente, puedes invadir las llamadas de RCP relacionadas con Bluetooth para vincular un automóvil y un teléfono. En bt_discovery_test, se muestra cómo hacerlo.