Spectatio: framework de test pour l'automobile

Spectatio est un framework de test Open Source développé pour tester Android Automotive OS (AAOS) sur des appareils réels et virtuels. Spectatio fournit des API pour tester des applications sur un appareil automobile. Il s'agit d'une solution extensible et évolutive utilisée pour vérifier les fonctionnalités et les performances de l'AAOS et de ses applications.

Conception de haut niveau

Le framework Spectatio est adaptable et extensible à diverses implémentations d'UI AAOS. Il est utilisé pour tester les capacités et les performances d'AAOS sur le matériel de l'appareil, les émulateurs et les environnements virtualisés.

La figure suivante explique la conception générale du framework Spectatio.

Conception de haut niveau du framework Spectatio

Figure 1 : Conception de haut niveau du framework Spectatio.

Basé sur UI Automator, le framework Spectatio fournit un ensemble d'API permettant de créer des tests d'interface utilisateur qui interagissent avec les applications utilisateur et système sous AAOS. Les tests automobiles utilisent les API fournies par le framework Spectatio pour les tests, ce qui rend ces tests indépendants de l'appareil testé (DUT) et évolutifs pour tester différents appareils, le cas échéant.

La figure 1 montre que le framework Spectatio est modularisé en fonction d'applications de référence telles que Dialer, Medicenter et Settings, à l'aide d'interfaces et d'assistants spécifiques à l'application, ce qui le rend facilement extensible pour les nouvelles applications. Le framework Spectatio réutilise les classes d'aide standard et utilitaires courantes. La classe d'assistance standard est la classe parente de toutes les fonctions d'assistance de l'application. Elle fournit des fonctions standards spécifiques à l'appareil ou applicables à toutes les applications. Les classes d'utilitaires d'aide fournissent des utilitaires tels que la lecture ou l'écriture de fichiers à partir de l'appareil.

Architecture

Pour fournir un ensemble d'API permettant de créer des tests d'interface utilisateur, le framework Spectatio implémente des interfaces et des assistants spécifiques à l'application, tout en étendant la classe d'assistance standard existante et en important les classes d'assistance utilitaires.

La figure 2 illustre l'architecture de haut niveau du framework Spectatio et toutes les entités impliquées dans l'implémentation d'API pour tester une application.

Architecture de haut niveau du framework Spectatio

Figure 2. Architecture de haut niveau du framework Spectatio

L'interface d'assistance d'application fournit un plan d'implémentation d'un assistant d'application. Il se compose de diverses fonctions d'assistance nécessaires pour tester les applications. Chaque application dispose de son propre interface, comme IAutoSettingHelper et IAutoDialHelper. Pour en savoir plus et obtenir la liste des fonctions d'interface, consultez les fonctions d'interface de l'assistant d'application sur AOSP.

La classe d'assistance standard se compose d'attributs et de fonctions standards requis pour la configuration de l'appareil, mais qui ne sont pas spécifiques à une application, comme pressHome et scroll. La classe d'assistance standard est définie dans AbstractAutoStandardAppHelper.java.

Le framework utilise les classes utilitaires d'assistance. Par exemple, AutoJsonUtility.java est une classe utilitaire qui charge le fichier de configuration JSON de l'appareil donné et met à jour les configurations du framework au moment de l'exécution.

Le module d'implémentation de l'application d'assistance est au cœur du framework Spectatio. Il contient l'implémentation des fonctions d'assistance définies dans l'interface d'assistance de l'application, qui sont requises pour tester des applications sur un appareil automobile. Chaque application a sa propre implémentation, comme SettingHelperImpl et DialHelperImpl, qui sont utilisées par les tests Automotive pour tester les applications. Pour en savoir plus et obtenir la liste des implémentations, consultez les fonctions d'implémentation de l'assistant d'application sur AOSP.

Les tests automobiles utilisent les fonctions d'implémentation de l'assistant d'application pour tester différentes opérations liées à l'application. Utilisez la classe HelperAccessor pour accéder aux fonctions d'implémentation de l'assistant d'application.

Le code suivant montre la configuration, le nettoyage et l'exécution d'un exemple de test automobile.

@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());
  }
}

Personnalisation

Le framework Spectatio est indépendant de l'interface utilisateur de l'appareil. Il est donc évolutif pour tester des appareils avec des interfaces utilisateur et du matériel variés. Pour assurer cette évolutivité, Spectatio utilise des configurations d'appareil par défaut basées sur l'appareil de référence. Pour prendre en charge les configurations d'appareil non par défaut, le framework utilise un fichier de configuration JSON au moment de l'exécution pour définir les modifications d'interface utilisateur souhaitées pour l'appareil. Un fichier de configuration JSON est compatible avec des éléments d'interface utilisateur tels que TEXT, DESCRIPTION et RESOURCE_ID, ainsi qu'avec les paramètres path. Il ne doit contenir que les informations sur les modifications de l'UI pour l'appareil testé. Les autres éléments de l'interface utilisateur utilisent les valeurs de configuration par défaut fournies dans le framework.

Configurations par défaut des appareils

L'exemple de fichier de configuration JSON suivant montre les configurations d'appareil disponibles et leurs valeurs par défaut.

Cliquez ici pour afficher un exemple de fichier de configuration JSON

    {
        "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"
                        }
                }
        }
}
  

Autres configurations de l'appareil

L'exemple de code suivant montre un exemple de fichier de configuration JSON où les paramètres par défaut sont remplacés par les paramètres du DUT. Dans cet exemple :

  • Les paramètres Internet sont nommés Réseau et Internet sur les appareils de référence et Connectivité sur l'appareil testé.

  • Les paramètres de date et d'heure sont disponibles sous Paramètres > Date et heure pour les appareils de référence et sous Paramètres > Système > Date et heure pour l'appareil testé.

// 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"
    },
    ....
}

Lorsque le fichier de configuration JSON est prêt, il est fourni au moment de l'exécution, comme indiqué dans le bloc de code suivant:

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

Dans cette commande :

  • DEVICE-SERIAL: numéro de série de l'appareil testé. Ce paramètre n'est pas obligatoire si un seul appareil est connecté à l'hôte.

  • PATH-TO-JSON-FILE: chemin d'accès du fichier JSON sur la machine hôte.

Format de configuration

La configuration contient cinq objets de premier niveau, avec les clés et valeurs suivantes:

Objet Description
PACKAGES Objet décrivant le package principal de diverses applications, qui sont utilisées pour déterminer quand cette application est au premier plan.
ACTIONS Objet indiquant les types et les paramètres d'action pour différentes actions. Par exemple, si vous souhaitez utiliser des boutons ou un geste pour faire défiler l'écran.
COMMANDS Objet spécifiant des commandes qui effectuent diverses actions.
UI_ELEMENTS Objet utilisé pour créer des "BySelectors" d'UI Automator qui sélectionnent des éléments d'interface utilisateur (décrits en détail ci-dessous).
WORKFLOWS Séquences d'actions qui effectuent des tâches de haut niveau (décrites en détail ci-dessous).

Éléments d'interface utilisateur

Chaque élément d'interface utilisateur possède un TYPE qui spécifie ce que l'UI Automator recherchera pour identifier l'élément (comme l'ID de ressource, le texte et la description) et les valeurs de configuration associées à ce type. En général, chaque fois qu'un assistant identifie un élément à l'écran à l'aide de cette configuration, il obtient exactement un seul élément. Si plusieurs éléments correspondent à la configuration, un élément arbitraire est utilisé dans le test. Par conséquent, la configuration doit (généralement) être suffisamment spécifique pour se réduire à un seul élément dans le contexte pertinent.

TEXTE

Il s'agit du type d'élément d'interface utilisateur le plus simple. L'élément d'interface utilisateur est identifié par son texte et nécessite une correspondance exacte.

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

TEXT_CONTAINS

Identique à TEXT, sauf que le VALUE spécifié ne doit apparaître que dans le texte de l'élément à faire correspondre.

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

DESCRIPTION

Identifiez l'élément par son attribut "description du contenu", qui nécessite une correspondance exacte.

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

RESOURCE_ID

Identifiez l'élément par son ID de ressource, et vérifiez également le composant de package de cet ID. La clé PACKAGE est facultative. Si elle est omise, n'importe quel package correspondra, et seule la partie de l'ID qui suit :id/ sera prise en compte.

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

CLIQUABLE, DÉROULANT

Identifiez l'élément en fonction de son cliquabilité ou de sa possibilité de défilement. Il s'agit de types d'éléments très généraux et qui ne doivent généralement être utilisés que dans un élément MULTIPLE pour affiner un autre type d'élément. La clé FLAG est facultative et est définie par défaut sur true.

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

CLASS

Identifiez l'élément en fonction de sa classe.

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

HAS_ANCESTOR

Identifiez l'élément en recherchant ses ancêtres dans la hiérarchie des widgets. La clé ANCESTOR contient un objet qui identifie l'ancêtre. La clé DEPTH spécifie jusqu'où remonter dans la hiérarchie. DEPTH est facultatif et sa valeur par défaut est 1.

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

HAS_DESCENDANT

Identifiez l'élément en examinant ses enfants dans la hiérarchie. La clé DESCENDANT contient un objet qui spécifie l'enfant à rechercher. La clé DEPTH spécifie jusqu'où remonter dans la hiérarchie. DEPTH est facultatif et a la valeur par défaut 1.

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

MULTIPLE

Identifiez l'élément en fonction de plusieurs conditions simultanées, qui doivent toutes être remplies.

      "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"
          }
        }
      ]
    }

Dans cet exemple, la configuration identifie un RelativeLayout qui possède un descendant à la profondeur 2, qui contient le texte Permission manager.

Workflows

Un workflow représente une séquence d'actions utilisées pour accomplir une tâche particulière, qui peut différer suffisamment d'un type d'appareil à l'autre et est plus flexible à représenter en configuration qu'en code.

    "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"
          }
        }
      }
    ]
  }

Chaque workflow est une paire clé-valeur, où la clé est le nom du workflow et la valeur est un tableau d'actions à effectuer. Chaque action comporte un NAME, un TYPE, (généralement) un CONFIG et (parfois) un SWIPE_CONFIG ou un SCROLL_CONFIG. Pour la plupart des TYPES, CONFIG est un objet avec une clé UI_ELEMENT dont la valeur prend la même forme qu'une entrée d'élément d'interface utilisateur (voir ci-dessus). Ces TYPES sont les suivants:

APPUYER
APPUYER_LONGTEMPS
CLIQUER
CLIQUER_LONGTEMPS
CLIQUER_SI_EXISTE
HAS_UI_ELEMENT_IN_FOREGROUND
SCROLL_TO_FIND_AND_CLICK
SCROLL_TO_FIND_AND_CLICK_IF_EXIST
BALAYER_TO_FIND_AND_CLICK
GLISSER_TO_FIND_ET_CLICK_IF_EXIST

Pour les autres TYPES, les détails de configuration sont les suivants:

Objet Description
COMMAND Objet avec une valeur TEXT contenant la commande à exécuter.
HAS_PACKAGE_IN_FOREGROUND Objet avec une valeur TEXT contenant le package.
SWIPE Omettre CONFIG key pour une action SWIPE. Cette méthode n'utilise que SWIPE_CONFIG.
WAIT_MS Un objet avec une valeur TEXT contenant le nombre de millisecondes d'attente.

Les actions liées au défilement et au balayage nécessitent une configuration supplémentaire, comme suit:

SCROLL_CONFIG

Objet Description
SCROLL_ACTION USE_GESTURE ou USE_BUTTON
SCROLL_DIRECTION HORIZONTAL ou VERTICAL
SCROLL_ELEMENT Objet indiquant le conteneur à faire défiler, utilisant la même forme qu'une configuration d'élément d'interface utilisateur (voir ci-dessus).
SCROLL_FORWARD, SCROLL_BACKWARD Boutons de défilement avant et arrière (obligatoire lorsque SCROLL_ACTION est USE_BUTTON).
SCROLL_MARGIN Si SCROLL_ACTION est USE_GESTURE, distance par rapport au bord du conteneur pour démarrer et arrêter le glissement qui sera utilisé pour effectuer le défilement (facultatif,valeur par défaut = 10).
SCROLL_WAIT_TIME Si SCROLL_ACTION est USE_GESTURE, durée en millisecondes d'attente entre les gestes de défilement lors de la recherche d'un objet à cliquer. (facultatif,valeur par défaut : 1)

SWIPE_CONFIG

Objet Description
SWIPE_DIRECTION TOP_TO_BOTTOM, BOTTOM_TO_TOP, LEFT_TO_RIGHT ou RIGHT_TO_LEFT
SWIPE_FRACTION

L'une des options suivantes:

  • FULL: geste de balayage d'un bord à l'autre de l'écran

    OU
  • DEFAULT: bord à bord de l'écran, avec un tampon de cinq (5) pixels de chaque côté.

    OU,
  • THREE_QUARTER, HALF ou QUARTER: le geste de balayage se termine à cinq (5) pixels du bord de l'écran et commence à un point tel qu'il couvre la distance indiquée sur l'écran.
NUMBER_OF_STEPS Nombre d'étapes à effectuer pour effectuer le balayage. Consultez la segmentSteps.

Créer et exécuter

Le framework Spectatio est compilé automatiquement dans l'APK de test. Pour créer l'APK de test, le codebase AOSP doit se trouver sur la station de travail locale. Une fois l'APK de test créé, l'utilisateur doit l'installer sur l'appareil et exécuter le test.

L'exemple de code suivant montre comment compiler, installer et exécuter un APK de test.

# 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

Dans ces commandes:

  • TEST-APK-NAME: nom de l'application à tester. Par exemple, définissez TEST-APK-NAME sur AndroidAutomotiveSettingsTests pour tester les paramètres Wi-Fi tels qu'ils sont spécifiés dans le fichier Android.bp. Le nom de l'APK se trouve dans le fichier Android.bp correspondant pour le test automobile.

  • DEVICE-SERIAL: numéro de série de l'appareil testé. Ce paramètre n'est pas obligatoire si un seul appareil est connecté à l'hôte.

  • config-file-path: paramètre facultatif qui n'est requis que pour fournir des configurations d'interface utilisateur d'appareil non par défaut, comme spécifié dans le fichier de configuration JSON. Si aucune valeur n'est fournie, le framework utilise les valeurs par défaut pour exécuter les tests.

  • PATH-FOR-BUILT-TEST-APK: chemin d'accès à l'emplacement où l'APK de test est créé lorsque la commande make est exécutée.

  • TEST-PACKAGE: nom du package de test.

  • TEST-CLASSNAME: nom de la classe de test. Par exemple, pour le test Wifi Settings (Paramètres Wi-Fi), le package de test est android.platform.tests et le nom de la classe de test est WifiSettingTest.

Bibliothèque d'extraits pour l'automobile

La bibliothèque d'extraits automobiles est un ensemble de bibliothèques Android Test conçues pour le projet Android Open Source (AOSP) et conçues pour interagir avec les applications et services automobiles. Il exploite Spectatio avec un mécanisme pratique pour exécuter des appels de procédure à distance (RPC) à partir d'une machine hôte (de test) vers un appareil Android.

Premiers pas

Avant de commencer, passez en revue ces sections.

Prérequis

  • Python 3.x installé sur la machine hôte
  • Configuration de l'environnement AOSP avec les outils de compilation nécessaires.
  • Un appareil Android Auto (émulateur ou appareil physique) avec accès adb.

Compilation

Pour compiler les différents extraits fournis par la bibliothèque d'extraits pour l'automobile, vous pouvez utiliser le fichier android.bp fourni. Les commandes suivantes de la section précédente pour compiler l'APK.

Déploiement

Une fois les bibliothèques d'extraits compilées, déployez les APK générés sur l'appareil cible à l'aide de la commande adb install mentionnée dans la section précédente.

Exécuter des tests

Les bibliothèques d'extraits exposent plusieurs méthodes RPC pour interagir avec le système automobile. Ces méthodes peuvent être appelées via le framework Mobly à partir de la machine hôte. Si vous avez configuré l'environnement de test Mobly, vous pouvez utiliser le script snippet_shell.py pour ouvrir un shell Python interactif, dans lequel vous pouvez appeler manuellement des méthodes RPC sur l'appareil. Exemple d'appel:

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

Remplacez <serial> par le numéro de série de l'appareil, que vous pouvez obtenir avec les appareils adb si plusieurs appareils sont connectés.

Bibliothèques incluses

La bibliothèque d'extraits pour l'automobile inclut les bibliothèques et les outils d'extraits suivants:

  • AutomotiveSnippet: fournit des API liées aux opérations du véhicule, telles que la numérotation, le contrôle du volume, les touches physiques du véhicule et l'interaction avec le centre multimédia.

  • PhoneSnippet: fournit des API liées à la téléphonie, y compris la gestion des appels, la navigation dans les contacts et les opérations SMS.

L'extrait Automotive et PhoneSnippet partagent une logique commune. Plus précisément, vous pouvez attaquer les appels RCP liés au Bluetooth pour associer un appareil automobile et un appareil téléphonique. Cet bt_discovery_test vous montre comment procéder.