Spectatio : cadre de test automobile

Spectatio est un framework de test open source développé pour tester le système d'exploitation Android Automotive (AAOS) sur des appareils réels et virtuels. Spectatio fournit des API pour tester des applications sur un appareil automobile et constitue une solution extensible et évolutive utilisée pour vérifier la capacité et les performances d'AAOS et de ses applications.

Conception de haut niveau

Le framework Spectatio est adaptable et extensible pour diverses implémentations d'interface utilisateur AAOS. Il est utilisé pour tester la capacité et les performances d'AAOS sur le matériel des appareils, les émulateurs et les environnements virtualisés.

La figure suivante explique la conception de haut niveau du framework Spectatio.

Conception de haut niveau du framework Spectatio

Figure 1. Conception de haut niveau du cadre Spectatio.

Construit sur UI Automator , le framework Spectatio fournit un ensemble d'API pour créer des tests d'interface utilisateur qui interagissent avec les applications utilisateur et système sur 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 divers appareils, s'ils sont pris en charge.

La figure 1 montre que le framework Spectatio est modularisé sur la base d'applications de référence telles que Dialer, Medicenter et Settings à l'aide d'interfaces et d'assistants spécifiques aux applications, ce qui le rend facilement extensible pour de nouvelles applications. Le framework Spectatio réutilise les classes d'assistance standard et utilitaires communes. La classe d'assistance standard est la classe parent de toutes les fonctions d'assistance d'application et fournit des fonctions standard spécifiques à l'appareil ou applicables dans toutes les applications. Les classes d'assistance utilitaire fournissent des utilitaires tels que la lecture ou l'écriture de fichiers à partir du périphérique.

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 aux applications 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 la mise en œuvre des API pour tester une application.

Architecture de haut niveau du framework Spectatio

Figure 2. Architecture de haut niveau du framework Spectatio.

L'interface de l'assistant d'application fournit un modèle pour la mise en œuvre d'un assistant d'application. Il se compose de diverses fonctions d'assistance nécessaires pour tester les applications. Chaque application possède sa propre interface, telle que IAutoSettingHelper et IAutoDialHelper . Pour plus d’informations et une liste des fonctions d’interface, consultez les fonctions d’interface d’assistance d’application sur AOSP.

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

Les classes d'assistance utilitaire sont utilisées par le framework. Par exemple, AutoJsonUtility.java est une classe d'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 d'aide à l'application 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 nécessaires pour tester les applications sur un appareil automobile. Chaque application possède sa propre implémentation, telle que SettingHelperImpl et DialHelperImpl , utilisée par les tests Automotive pour tester les applications. Pour plus d'informations et une liste des implémentations, consultez les fonctions d'implémentation de l'assistant d'application sur AOSP.

Automotive Tests utilise les fonctions d'implémentation de l'assistant d'application pour tester diverses 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 application
    autoApplicationHelper.open();
  }

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

  @Test
  public void testApplicationFeature() {
    // Test
    // For example - Test if application 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 dotés d'interfaces utilisateur et de matériel variés. Pour atteindre cette évolutivité, Spectatio utilise des configurations de périphérique par défaut basées sur le périphérique de référence. Pour prendre en charge les configurations d'appareil autres que celles 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 prend en charge les éléments de l'interface utilisateur tels que TEXT , DESCRIPTION et RESOURCE_ID , ainsi que les paramètres path et doit contenir uniquement les informations sur les modifications de l'interface utilisateur pour le DUT. Le reste des éléments de l'interface utilisateur utilise les valeurs de configuration par défaut fournies dans le framework.

Configurations de périphérique par défaut

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

Configurations d'appareils alternatives

L'exemple de code suivant montre un exemple de fichier de configuration JSON dans lequel 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 le DUT.

  • Les paramètres de date et d'heure sont disponibles dans Paramètres > Date et heure pour les appareils de référence et dans Paramètres > Système > Date et heure pour le 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"
    },
    ....
}

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 : ID de série du DUT. Ce paramètre n'est pas obligatoire si un seul périphérique est connecté à l'hôte.

  • PATH-TO-JSON-FILE : Chemin du fichier JSON sur la machine hôte.

Format de configuration

Il existe cinq objets de niveau supérieur dans la configuration, avec les clés et valeurs suivantes :

Objet Description
PACKAGES Objet décrivant le package principal de diverses applications, utilisé pour déterminer quand cette application est au premier plan.
ACTIONS Un objet indiquant les types d'actions et les paramètres de diverses actions. Par exemple, s'il faut utiliser des boutons ou un geste pour faire défiler.
COMMANDS Un objet spécifiant des commandes qui effectuent diverses actions.
UI_ELEMENTS Un objet utilisé pour construire `BySelectors` d'UI Automator qui sélectionne les éléments d'interface utilisateur (décrits en détail ci-dessous).
WORKFLOWS Séquences d'actions qui accomplissent des tâches de haut niveau (décrites en détail ci-dessous).

Éléments de l'interface utilisateur

Chaque élément d'interface utilisateur a un TYPE qui spécifie ce que UI Automator recherchera pour identifier l'élément (tel que 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 en utilisant cette configuration, il obtient exactement un é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 écrite de manière suffisamment spécifique pour se limiter à un é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 la VALUE spécifiée doit seulement apparaître quelque part dans le texte de l'élément à mettre en correspondance.

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

DESCRIPTION

Identifiez l'élément par son attribut de description de contenu, nécessitant une correspondance exacte.

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

RESOURCE_ID

Identifiez l'élément par son ID de ressource, en vérifiant éventuellement également le composant de package de cet ID. La clé PACKAGE est facultative ; en cas d'omission, n'importe quel package correspondra et seule la partie de l'ID suivant :id/ sera prise en compte.

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

CLIQUABLE, DÉFILABLE

Identifiez l'élément selon qu'il est (ou non) cliquable ou défilable. Il s'agit de types d'éléments très larges et ne doivent généralement être utilisés que dans un MULTIPLE pour aider à affiner un autre type d'élément. La clé FLAG est facultative et la valeur par défaut est true .

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

CLASSE

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 la hiérarchie des widgets chez ses ancêtres. La clé ANCESTOR contient un objet qui identifie l'ancêtre. La clé DEPTH spécifie jusqu'où chercher dans la hiérarchie. DEPTH est facultatif et a une valeur par défaut de 1 .

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

HAS_DESCENDANT

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

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

PLUSIEURS

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 a un descendant en profondeur 2 , qui a le texte Permission manager .

Flux de travail

Un flux de travail 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 dans la configuration que dans le 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 flux de travail est une paire clé-valeur où la clé est le nom du flux de travail et la valeur est un tableau d'actions à effectuer. Chaque action a un NAME , un TYPE , (généralement) un CONFIG et (parfois) un SWIPE_CONFIG ou SCROLL_CONFIG . Pour la plupart des TYPES, le CONFIG est un objet avec une clé UI_ELEMENT dont la valeur prend la même forme qu'une entrée d'élément UI (voir ci-dessus). Ces TYPES sont :

PRESSE
APPUI LONG
CLIQUEZ SUR
LONG_CLICK
CLICK_IF_EXIST
HAS_UI_ELEMENT_IN_FOREGROUND
SCROLL_TO_FIND_AND_CLICK
SCROLL_TO_FIND_AND_CLICK_IF_EXIST
SWIPE_TO_FIND_AND_CLICK
SWIPE_TO_FIND_AND_CLICK_IF_EXIST

Pour les autres TYPEs, les détails de configuration sont :

Objet Description
COMMAND Un objet avec une valeur TEXT contenant la commande à exécuter.
HAS_PACKAGE_IN_FOREGROUND Un objet avec une valeur TEXT contenant le package.
SWIPE Omettez la CONFIG key pour une action SWIPE . Cela utilise uniquement SWIPE_CONFIG
WAIT_MS Un objet avec une valeur TEXT contenant le nombre de millisecondes à attendre.

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

SCROLL_CONFIG

Objet Description
SCROLL_ACTION Soit USE_GESTURE , soit USE_BUTTON
SCROLL_DIRECTION Soit HORIZONTAL , soit VERTICAL
SCROLL_ELEMENT Un objet indiquant le conteneur à faire défiler, en utilisant le même formulaire qu'une configuration d'élément d'interface utilisateur (voir ci-dessus).
SCROLL_FORWARD , SCROLL_BACKWARD Les boutons de défilement avant et arrière (obligatoires lorsque SCROLL_ACTION est USE_BUTTON ).
SCROLL_MARGIN Si SCROLL_ACTION vaut USE_GESTURE , la distance depuis le bord du conteneur pour démarrer et arrêter le glissement qui sera utilisé pour effectuer le défilement ( Facultatif, par défaut = 10).
SCROLL_WAIT_TIME Si SCROLL_ACTION est USE_GESTURE , le temps d'attente en millisecondes entre les gestes de défilement lors de la recherche d'un objet sur lequel cliquer. ( Facultatif, par défaut = 1).

SWIPE_CONFIG

Objet Description
SWIPE_DIRECTION Soit TOP_TO_BOTTOM , BOTTOM_TO_TOP , LEFT_TO_RIGHT ou RIGHT_TO_LEFT
SWIPE_FRACTION

L'un des éléments suivants :

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

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

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

Construire et exécuter

Le framework Spectatio est automatiquement construit dans le cadre de l'APK de test. Pour créer l'APK de test, la base de code AOSP doit résider sur le poste de travail local. Une fois l’APK de test créé, l’utilisateur doit installer l’APK sur l’appareil et exécuter le test.

L'exemple de code suivant montre la création, l'installation et l'exécution d'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 : Le nom de l'application à tester. Par exemple, définissez TEST-APK-NAME sur AndroidAutomotiveSettingsTests pour tester les paramètres Wi-Fi tels que spécifiés dans le fichier Android.bp . Le nom de l'APK se trouve dans le fichier Android.bp correspondant pour le test Automotive .

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

  • config-file-path : paramètre facultatif requis uniquement pour fournir des configurations d'interface utilisateur de périphérique autres que celles par défaut, telles que spécifiées dans le fichier de configuration JSON . Si elles ne sont pas fournies, le framework utilise des valeurs par défaut pour exécuter les tests.

  • PATH-FOR-BUILT-TEST-APK : Le chemin où l'APK de test est construit lorsque la commande make est exécutée.

  • TEST-PACKAGE : Le nom du package de test.

  • TEST-CLASSNAME : Le nom de la classe de test. Par exemple, pour le test des paramètres Wifi , le package de test est android.platform.tests et le nom de la classe de test est WifiSettingTest .

Bibliothèque d'extraits automobiles

La bibliothèque d'extraits automobiles est un ensemble de bibliothèques de tests Android pour le projet Android Open Source (AOSP) conçu 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) depuis une machine hôte (test) vers un appareil Android.

Commencer

Avant de commencer, consultez ces sections.

Conditions préalables

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

Compilation

Pour compiler les différents extraits fournis par Automotive Snippet Library, vous pouvez utiliser le fichier android.bp fourni. Suivez les commandes de la section précédente pour compiler l’APK.

Déploiement

Après avoir compilé avec succès les bibliothèques d'extraits de code, déployez les APK résultants sur le périphérique 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 invoquées via le framework Mobly depuis la machine hôte. En supposant que l'environnement de test Mobly soit configuré, vous pouvez utiliser le script snippet_shell.py pour ouvrir un shell Python interactif, dans lequel vous pouvez appeler manuellement les méthodes RPC sur l'appareil. Exemple d'invocation :

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 de code automobile comprend les bibliothèques d'extraits de code et les assistants 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 matérielles du véhicule et l'interaction avec le centre multimédia.

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

L'extrait Automotive et le PhoneSnippet partagent une logique commune. Plus précisément, vous pouvez envahir les appels RCP liés à Bluetooth pour coupler une voiture et un appareil téléphonique. Ce bt_discovery_test montre comment.