Spectatio: marco de pruebas automotrices

Spectatio es un marco de prueba de código abierto desarrollado para probar el sistema operativo Android Automotive (AAOS) en dispositivos reales y virtuales. Spectatio proporciona API para probar aplicaciones en un dispositivo 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 marco Spectatio es adaptable y ampliable para varias implementaciones de UI de AAOS. Se utiliza para probar la capacidad y el rendimiento de AAOS en el hardware del dispositivo, emuladores y entornos virtualizados.

La siguiente figura explica el diseño de alto nivel del marco Spectatio.

Diseño de alto nivel del marco Spectatio

Figura 1. Diseño de alto nivel del marco Spectatio.

Construido sobre UI Automator , el marco Spectatio proporciona un conjunto de API para crear pruebas de UI que interactúan con las aplicaciones del usuario y del sistema en AAOS. Las pruebas automotrices utilizan las API proporcionadas por el marco Spectatio para las pruebas, lo que hace que estas pruebas sean independientes del dispositivo bajo prueba (DUT) y escalables para probar varios dispositivos, si son compatibles.

La Figura 1 muestra que el marco Spectatio está modularizado en función de aplicaciones de referencia como Dialer, Medicenter y Settings utilizando interfaces y ayudantes específicos de la aplicación, lo que lo hace fácilmente extensible para nuevas aplicaciones. El marco Spectatio reutiliza las clases auxiliares estándar y de utilidad comunes. La clase auxiliar estándar es la clase principal para todas las funciones auxiliares de la aplicación y proporciona funciones estándar que son específicas del dispositivo o aplicables a todas las aplicaciones. Las clases de ayuda de utilidades proporcionan utilidades como leer o escribir archivos desde el dispositivo.

Arquitectura

Para proporcionar un conjunto de API para crear pruebas de UI, el marco Spectatio implementa interfaces y asistentes específicos de la aplicación mientras extiende la clase auxiliar estándar existente e importa las clases auxiliares de utilidad.

La Figura 2 ilustra la arquitectura de alto nivel del marco Spectatio y todas las entidades involucradas en la implementación de API para probar una aplicación.

Arquitectura de alto nivel del marco Spectatio

Figura 2. Arquitectura de alto nivel del marco Spectatio.

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

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

El marco utiliza las clases auxiliares de utilidad . Por ejemplo, AutoJsonUtility.java es una clase de utilidad que carga el archivo de configuración JSON del dispositivo determinado y actualiza las configuraciones del marco en tiempo de ejecución.

El módulo de implementación de la aplicación auxiliar es el núcleo del marco Spectatio. Contiene la implementación de las funciones auxiliares definidas en la interfaz auxiliar de la aplicación, que son necesarias para probar aplicaciones en un dispositivo automotriz. Cada aplicación tiene su propia implementación, como SettingHelperImpl y DialHelperImpl , utilizadas por las pruebas de Automoción para probar las aplicaciones. Para obtener más información y una lista de implementaciones, consulte las funciones de implementación de la aplicación auxiliar en AOSP.

Las pruebas automotrices utilizan las funciones de implementación auxiliares de la aplicación para probar varias operaciones relacionadas con la aplicación. Utilice la clase HelperAccessor para obtener acceso a las funciones de implementación del asistente de la aplicación.

El siguiente código muestra la configuración, limpieza y ejecución de una prueba automotriz de muestra.

@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 marco Spectatio es independiente de la interfaz de usuario del dispositivo, por lo que es escalable para probar dispositivos con diversas interfaces de usuario y hardware. Para lograr esta escalabilidad, Spectatio utiliza configuraciones de dispositivo predeterminadas basadas en el dispositivo de referencia. Para admitir configuraciones de dispositivos no predeterminadas, el marco utiliza un archivo de configuración JSON en tiempo de ejecución para establecer los cambios de UI deseados para el dispositivo. Un archivo de configuración JSON admite elementos de la interfaz de usuario como TEXT , DESCRIPTION y RESOURCE_ID , junto con configuraciones path y debe contener solo información sobre los cambios de la interfaz de usuario para el DUT. El resto de los elementos de la interfaz de usuario utilizan los valores de configuración predeterminados proporcionados en el marco.

Configuraciones de dispositivo predeterminadas

El siguiente archivo de configuración JSON de muestra muestra las configuraciones de dispositivos disponibles y sus valores predeterminados.

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

    {
        "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 de dispositivos alternativas

El siguiente ejemplo de código muestra un ejemplo del archivo de configuración JSON donde la configuración del DUT anula la configuración predeterminada. En este ejemplo:

  • Las configuraciones de Internet se denominan Red e Internet en los dispositivos de referencia y Conectividad en el DUT.

  • La configuración de fecha y hora está disponible en Configuración > Fecha y hora para dispositivos de referencia y en Configuración > Sistema > Fecha y hora para el 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 tiempo 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 : ID de serie del DUT. Este parámetro no es necesario si solo hay un dispositivo conectado al host.

  • PATH-TO-JSON-FILE : Ruta del archivo JSON en la máquina host.

Formato de configuración

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

Objeto Descripción
PACKAGES Un objeto que describe el paquete principal de varias aplicaciones, que se utilizan para determinar cuándo esa aplicación está en primer plano.
ACTIONS Un objeto que indica tipos de acción y parámetros para varias acciones. Por ejemplo, si utilizar botones o un gesto para desplazarse.
COMMANDS Un objeto que especifica comandos que realizan varias acciones.
UI_ELEMENTS Un objeto utilizado para construir UI Automator `BySelectors` que selecciona elementos de UI (descrito en detalle a continuación).
WORKFLOWS Secuencias de acciones que logran tareas de alto nivel (descritas en detalle a continuación).

elementos de la interfaz de usuario

Cada elemento de la interfaz de usuario tiene un TYPE que especifica qué buscará UI Automator para identificar el elemento (como ID de recurso, texto y descripción) y los valores de configuración asociados con ese tipo. En general, cada vez que un asistente identifica un elemento en la pantalla usando esta configuración, obtiene exactamente un elemento. Si varios elementos coinciden con la configuración, se utiliza uno arbitrario en la prueba. Por lo tanto, la configuración debe (generalmente) escribirse de manera lo suficientemente específica como para limitarse a un elemento en el contexto relevante.

TEXTO

Este es el tipo de elemento de interfaz de usuario más simple. El elemento de la interfaz de usuario se identifica por su texto y requiere una coincidencia exacta.

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

TEXTO_CONTIENE

Igual que TEXT , excepto que el VALUE especificado solo necesita aparecer en algún lugar del texto del elemento que se va a comparar.

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

DESCRIPCIÓN

Identifique el elemento por su atributo de descripción de contenido, lo que requiere una coincidencia exacta.

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

RECURSO_ID

Identifique el elemento por su ID de recurso y, opcionalmente, también verifique el componente del paquete de ese ID. La clave PACKAGE es opcional; si se omite, cualquier paquete coincidirá y solo se considerará la parte del ID que sigue a :id/ .

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

CLICABLE, DESPLAZABLE

Identifique el elemento en función de si se puede hacer clic o desplazarse (o no). Estos son tipos de elementos muy amplios y, por lo general, solo deben usarse en MULTIPLE para ayudar a delimitar otro tipo de elemento. La clave FLAG es opcional y su valor predeterminado es true .

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

CLASE

Identificar el elemento según su clase.

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

TIENE_ANCESTOR

Identifique el elemento buscando en la jerarquía de widgets sus antepasados. La clave ANCESTOR contiene un objeto que identifica al antepasado. La clave DEPTH especifica hasta qué punto se debe buscar en la jerarquía. 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_DESCENDANTE

Identifique el elemento mirando hacia abajo en la jerarquía a sus hijos. La clave DESCENDANT contiene un objeto que especifica el niño a buscar. La clave DEPTH especifica hasta qué punto se debe buscar en la jerarquía. DEPTH es opcional y tiene un valor predeterminado de 1 .

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

MÚLTIPLE

Identificar el elemento basándose en múltiples condiciones simultáneas, todas las cuales deben cumplirse.

      "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 descendiente en la profundidad 2 , que tiene el texto Permission manager .

Flujos de trabajo

Un flujo de trabajo representa una secuencia de acciones utilizadas para realizar una tarea particular, que puede diferir bastante de un tipo de dispositivo a otro y es más flexible de 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 donde la clave es el nombre del flujo de trabajo y el valor es una serie de acciones a realizar. Cada acción tiene un NAME , un TYPE , (normalmente) un CONFIG y (a veces) un SWIPE_CONFIG o SCROLL_CONFIG . Para la mayoría de los TYPE, CONFIG es un objeto con una clave UI_ELEMENT cuyo valor toma la misma forma que una entrada de elemento UI (ver arriba). Esos TIPOS son:

PRENSA
PULSACIÓN LARGA
HACER CLIC
CLIC LARGO
HAGA CLIC_SI_EXISTE
HAS_UI_ELEMENT_IN_FOREGROUND
SCROLL_TO_FIND_AND_CLICK
SCROLL_TO_FIND_AND_CLICK_IF_EXIST
DESLIZA_PARA_BUSCAR_Y_CLIC
DESLIZAR_TO_FIND_AND_CLICK_IF_EXIST

Para los demás TIPOS, los detalles de configuración son:

Objeto Descripción
COMMAND Un objeto con un valor TEXT que contiene el comando a ejecutar.
HAS_PACKAGE_IN_FOREGROUND Un objeto con un valor TEXT que contiene el paquete.
SWIPE Omita la CONFIG key para una acción SWIPE . Esto usa solo SWIPE_CONFIG
WAIT_MS Un objeto con un valor TEXT que contiene el número de milisegundos a esperar.

Las acciones relacionadas con desplazarse y deslizar requieren una configuración adicional, como se muestra a continuación:

SCROLL_CONFIG

Objeto Descripción
SCROLL_ACTION Ya sea USE_GESTURE o USE_BUTTON
SCROLL_DIRECTION Ya sea HORIZONTAL o VERTICAL
SCROLL_ELEMENT Un objeto que indica el contenedor para desplazarse, utilizando el mismo formulario que una configuración de elemento de interfaz de usuario (ver arriba).
SCROLL_FORWARD , SCROLL_BACKWARD Los botones de desplazamiento hacia adelante y hacia atrás (obligatorios 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 utilizará para realizar el desplazamiento ( opcional, predeterminado = 10).
SCROLL_WAIT_TIME Si SCROLL_ACTION es USE_GESTURE , el tiempo en milisegundos que se debe esperar entre los gestos de desplazamiento al buscar un objeto en el que hacer clic. ( Opcional, predeterminado = 1).

DESLIZAR_CONFIG

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

Uno de los siguientes:

  • FULL : gesto de deslizar de borde a borde de la pantalla

    O,
  • DEFAULT : Pantalla de borde a borde de pantalla, con un búfer de cinco (5) píxeles en cada lado.

    O,
  • THREE_QUARTER , HALF o QUARTER : el gesto de deslizar termina cinco (5) píxeles desde el borde de la pantalla y comienza en el punto tal que cubre la distancia indicada de la pantalla.
NUMBER_OF_STEPS El número de pasos que se utilizarán para realizar el deslizamiento. Consulte segmentSteps .

Construir y ejecutar

El marco Spectatio se crea automáticamente como parte del APK de prueba. Para crear el APK de prueba, el código base de AOSP debe residir en la estación de trabajo local. Una vez creado el APK de prueba, el usuario debe instalarlo en el dispositivo y ejecutar la prueba.

El siguiente ejemplo de código muestra la creación, instalación y 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 : el nombre de la aplicación que se va a probar. Por ejemplo, configure TEST-APK-NAME en AndroidAutomotiveSettingsTests para probar la configuración de Wi-Fi como se especifica en el archivo Android.bp . El nombre del APK se puede encontrar en el archivo Android.bp correspondiente a la prueba Automotive .

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

  • config-file-path : parámetro opcional que solo se requiere para proporcionar configuraciones de IU del dispositivo no predeterminadas, como se especifica en el archivo de configuración JSON . Si no se proporcionan, el marco utiliza valores predeterminados para ejecutar las pruebas.

  • PATH-FOR-BUILT-TEST-APK : la ruta donde se crea el APK de prueba cuando se ejecuta el comando make .

  • TEST-PACKAGE : El nombre del paquete de prueba.

  • TEST-CLASSNAME : el nombre de la clase de prueba. Por ejemplo, para la prueba de configuración de Wifi , el paquete de prueba es android.platform.tests y el nombre de la clase de prueba es WifiSettingTest .

Biblioteca de fragmentos de automoción

La biblioteca de fragmentos de automoción es un conjunto de bibliotecas de prueba de Android para el proyecto de código abierto de Android (AOSP) diseñadas para interactuar con aplicaciones y servicios de automoción. Aprovecha Spectatio con un mecanismo conveniente para ejecutar llamadas a procedimientos remotos (RPC) desde una máquina host (de prueba) a un dispositivo con Android.

Empezar

Antes de comenzar, revise estas secciones.

Requisitos previos

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

Compilacion

Para compilar los distintos fragmentos proporcionados por la biblioteca de fragmentos de automoción, puede utilizar el archivo android.bp proporcionado. Siguiendo los comandos de la sección anterior para compilar el APK.

Despliegue

Después de compilar con éxito las bibliotecas de fragmentos, implemente los APK resultantes en el dispositivo de destino utilizando el comando adb install mencionado en la sección anterior.

Ejecutar pruebas

Las bibliotecas de fragmentos exponen varios métodos RPC para interactuar con el sistema automotriz. Estos métodos se pueden invocar a través del marco Mobly desde la máquina host. Suponiendo que tiene configurado el entorno de prueba de Mobly, puede usar el script snippet_shell.py para abrir un shell de Python interactivo, donde puede invocar manualmente los métodos RPC en el dispositivo. Ejemplo de invocación:

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

Reemplace <serial> con el número de serie del dispositivo, que puede obtener con dispositivos adb si hay varios dispositivos conectados.

Bibliotecas incluidas

La biblioteca de fragmentos de automoción incluye las siguientes bibliotecas de fragmentos y ayudas:

  • AutomotiveSnippet: proporciona API relacionadas con las operaciones del vehículo, como marcación, control de volumen, teclas físicas del vehículo e interacción con el centro multimedia.

  • PhoneSnippet: proporciona API relacionadas con la telefonía, incluido el manejo de llamadas, la exploración de contactos y las operaciones de SMS.

El fragmento Automotive y el PhoneSnippet comparten una lógica común. Específicamente, puede invadir llamadas RCP relacionadas con Bluetooth para emparejar un automóvil y un dispositivo telefónico. Este bt_discovery_test muestra cómo.