Spectatio: framework di test automobilistici

Spectatio è un framework di test open source sviluppato per testare Android Automotive OS (AAOS) su dispositivi reali e virtuali. Spectatio fornisce API per testare le app su un dispositivo auto e rappresenta una soluzione estensibile e scalabile utilizzata per verificare la funzionalità e le prestazioni di AAOS e delle sue app.

Design di alto livello

Il framework Spectatio è adattabile ed espandibile per varie implementazioni dell'interfaccia utente di AAOS. Viene utilizzato per testare le funzionalità e le prestazioni di AAOS su hardware del dispositivo, emulatori e ambienti virtualizzati.

La figura seguente illustra il design di alto livello del framework Spectatio.

Progettazione di alto livello del framework Spectatio

Figura 1. Progettazione di alto livello del framework Spectatio.

Basato su UI Automator, il framework Spectatio fornisce un insieme di API per creare test UI che interagiscono con le app utente e di sistema su AAOS. I test per il settore auto e motori utilizzano le API fornite dal framework Spectatio per i test, il che li rende indipendenti dal dispositivo in prova (DUT) e scalabili per testare vari dispositivi, se supportati.

La Figura 1 mostra che il framework Spectatio è modularizzato in base ad app di riferimento come Telefono, Medicenter e Impostazioni che utilizzano interfacce e helper specifici per l'app, il che lo rende facilmente estensibile per le nuove app. Il framework Spectatio riutilizza le classi di utilità e standard comuni. La classe di helper standard è la classe principale di tutte le funzioni di helper dell'app e fornisce funzioni standard specifiche per il dispositivo o applicabili a più app. Le classi di utility forniscono utilità come la lettura o la scrittura di file dal dispositivo.

Architettura

Per fornire un insieme di API per creare test di UI, il framework Spectatio implementa interfacce e helper specifici per l'app, estendendo la classe helper standard esistente e importando le classi helper di utilità.

La Figura 2 illustra l'architettura di alto livello del framework Spectatio e tutte le entità coinvolte nell'implementazione delle API per il test di un'app.

Architettura di alto livello del framework Spectatio

Figura 2. Architettura di alto livello del framework Spectatio.

L'interfaccia di App Helpers fornisce un modello per l'implementazione di un App Helper. È costituito da varie funzioni di supporto necessarie per testare le app. Ogni app ha la propria interfaccia, ad esempio IAutoSettingHelper e IAutoDialHelper. Per ulteriori informazioni e un elenco di funzioni di interfaccia di assistenza per le app, consulta le funzioni di interfaccia di assistenza per le app su AOSP.

La classe di helper standard è composta da funzioni e attributi standard obbligatori per la configurazione del dispositivo, ma non specifici per nessuna app, ad esempio pressHome e scroll. La classe di assistenza standard è definita in AbstractAutoStandardAppHelper.java.

Le classi di utilità vengono utilizzate dal framework. Ad esempio, AutoJsonUtility.java è una classe di utilità che carica il file di configurazione JSON del dispositivo specificato e aggiorna le configurazioni del framework in fase di esecuzione.

Il modulo di implementazione dell'helper dell'app è il nucleo del framework Spectatio. Contiene l'implementazione delle funzioni di assistenza definite nell'interfaccia dell'app helper, necessarie per testare le app su un dispositivo auto e motori. Ogni app ha la propria implementazione, ad esempio SettingHelperImpl e DialHelperImpl, utilizzata dai test per auto e motori per testare le app. Per ulteriori informazioni e un elenco di implementazioni, consulta le funzioni di implementazione di app helper su AOSP.

I test per auto e motori utilizzano le funzioni di implementazione dell'app helper per testare varie operazioni relative all'app. Utilizza la classe HelperAccessor per accedere alle funzioni di implementazione dell'app helper.

Il seguente codice mostra la configurazione, la pulizia e l'esecuzione di un test auto e motori di esempio.

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

Personalizzazione

Il framework Spectatio è indipendente dall'interfaccia utente del dispositivo, quindi è scalabile per il test di dispositivi con hardware e interfacce utente diversi. Per ottenere questa scalabilità, Spectatio utilizza le configurazioni dei dispositivi predefinite in base al dispositivo di riferimento. Per supportare le configurazioni dei dispositivi non predefinite, il framework utilizza un file di configurazione JSON in fase di esecuzione per impostare le modifiche all'interfaccia utente desiderate per il dispositivo. Un file di configurazione JSON supporta elementi dell'interfaccia utente come TEXT, DESCRIPTION e RESOURCE_ID, oltre alle impostazioni path e deve contenere solo le informazioni sulle modifiche dell'interfaccia utente per il DUT. Gli altri elementi dell'interfaccia utente utilizzano i valori di configurazione predefiniti forniti nel framework.

Configurazioni predefinite del dispositivo

Il seguente file di configurazione JSON di esempio mostra le configurazioni del dispositivo disponibili e i relativi valori predefiniti.

Fai clic qui per visualizzare un file di configurazione JSON di esempio

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

Configurazioni dei dispositivi alternative

Il seguente esempio di codice mostra un esempio del file di configurazione JSON in cui le impostazioni predefinite vengono sostituite da quelle sul DUT. In questo esempio:

  • Le impostazioni di internet si chiamano Rete e internet sui dispositivi di riferimento e Connettività sul DUT.

  • Le impostazioni di data e ora sono disponibili in Impostazioni > Data e ora per i dispositivi di riferimento e in Impostazioni > Sistema > Data e ora per il 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"
    },
    ....
}

Quando il file di configurazione JSON è pronto, viene fornito in fase di esecuzione come mostrato nel seguente blocco di codice:

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

In questo comando:

  • DEVICE-SERIAL: ID di serie del DUT. Questo parametro non è obbligatorio se è collegato un solo dispositivo all'host.

  • PATH-TO-JSON-FILE: percorso del file JSON sulla macchina host.

Formato di configurazione

Nella configurazione sono presenti cinque oggetti di primo livello con le seguenti chiavi e valori:

Oggetto Descrizione
PACKAGES Un oggetto che descrive il pacchetto principale di varie app, utilizzato per determinare quando l'app è in primo piano.
ACTIONS Un oggetto che indica i tipi di azioni e i relativi parametri. Ad esempio, se usare i pulsanti o un gesto per scorrere.
COMMANDS Un oggetto che specifica i comandi che eseguono varie azioni.
UI_ELEMENTS Un oggetto utilizzato per creare "BySelectors" di UI Automator che selezionano elementi UI (descritti in dettaglio di seguito).
WORKFLOWS Sequenze di azioni che completano attività di alto livello (descritte nel dettaglio di seguito).

Elementi dell'interfaccia utente

Ogni elemento dell'interfaccia utente ha un TYPE che specifica cosa cercherà UI Automator per identificare l'elemento (ad esempio ID risorsa, testo e descrizione) e i valori di configurazione associati a quel tipo. In generale, ogni volta che un helper identifica un elemento sullo schermo utilizzando questa configurazione, ottiene esattamente un elemento. Se più elementi corrispondono alla configurazione, nel test viene utilizzato uno arbitrario. Pertanto, la configurazione deve essere (in genere) scritta in modo sufficientemente specifico da restringersi a un elemento nel contesto pertinente.

TESTO

Si tratta del tipo di elemento dell'interfaccia utente più semplice. L'elemento dell'interfaccia utente viene identificato dal testo e richiede una corrispondenza esatta.

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

TEXT_CONTAINS

Come TEXT, tranne per il fatto che VALUE specificato deve apparire solo da qualche parte nel testo dell'elemento da associare.

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

DESCRIZIONE

Identifica l'elemento tramite l'attributo descrizione dei contenuti, che richiede una corrispondenza esatta.

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

RESOURCE_ID

Identifica l'elemento tramite il relativo ID risorsa, eventualmente controllando anche il componente del pacchetto di quell'ID. La chiave PACKAGE è facoltativa; se omessa, verrà trovata una corrispondenza per qualsiasi pacchetto e verrà considerata solo la parte dell'ID successiva a :id/.

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

CLICCABILI, SCORREVOLI

Identifica l'elemento in base al fatto che sia (o meno) selezionabile o scorrevole. Si tratta di tipi di elementi molto ampi e in genere devono essere utilizzati solo in un MULTIPLE per restringere un altro tipo di elemento. La chiave FLAG è facoltativa e il valore predefinito è true.

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

CLASS

Identifica l'elemento in base alla sua classe.

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

HAS_ANCESTOR

Identifica l'elemento cercando la gerarchia dei widget nei suoi elementi precedenti. La chiave ANCESTOR contiene un oggetto che identifica l'antenato. La chiave DEPTH specifica fino a che punto cercare nella gerarchia. DEPTH è facoltativo e ha un valore predefinito 1.

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

HAS_DESCENDANT

Identifica l'elemento esaminando i suoi elementi secondari nella gerarchia. La chiave DESCENDANT contiene un oggetto che specifica l'elemento figlio da cercare. La chiave DEPTH specifica fino a che punto della gerarchia cercare. DEPTH è facoltativo e ha un valore predefinito di 1.

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

PIU'

Identifica l'elemento in base a più condizioni simultanee, che devono essere tutte soddisfatte.

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

In questo esempio, la configurazione identifica un RelativeLayout con un discendente a una profondità di 2, che ha il testo Permission manager.

Workflows

Un flusso di lavoro rappresenta una sequenza di azioni utilizzate per svolgere una determinata attività, che può variare notevolmente da un tipo di dispositivo all'altro ed è più flessibile da rappresentare nella configurazione rispetto al codice.

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

Ogni flusso di lavoro è una coppia chiave-valore in cui la chiave è il nome del flusso di lavoro e il valore è un array di azioni da eseguire. Ogni azione ha un NAME, un TYPE, (di solito) un CONFIG e (a volte) un SWIPE_CONFIG o SCROLL_CONFIG. Per la maggior parte dei tipi, CONFIG è un oggetto con una chiave UI_ELEMENT il cui valore assume la stessa forma di una voce dell'elemento dell'interfaccia utente (vedi sopra). Questi tipi di TYPE sono:

PRESS
LONG_PRESS
CLICK
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

Per gli altri tipi TYPE, i dettagli di configurazione sono:

Oggetto Descrizione
COMMAND Un oggetto con un valore TEXT contenente il comando da eseguire.
HAS_PACKAGE_IN_FOREGROUND Un oggetto con un valore TEXT contenente il pacchetto.
SWIPE Ometti CONFIG key per un'azione SWIPE. Questo utilizza solo SWIPE_CONFIG
WAIT_MS Un oggetto con un valore TEXT contenente il numero di millisecondi da attendere.

Le azioni di scorrimento e scorrimento richiedono una configurazione aggiuntiva, come segue:

SCROLL_CONFIG

Oggetto Descrizione
SCROLL_ACTION USE_GESTURE o USE_BUTTON
SCROLL_DIRECTION HORIZONTAL o VERTICAL
SCROLL_ELEMENT Un oggetto che indica il contenitore da scorrere, utilizzando la stessa forma di una configurazione dell'elemento UI (vedi sopra).
SCROLL_FORWARD, SCROLL_BACKWARD I pulsanti di scorrimento Avanti e Indietro (obbligatori quando SCROLL_ACTION è USE_BUTTON).
SCROLL_MARGIN Se SCROLL_ACTION è USE_GESTURE, la distanza dal bordo del contenitore per avviare e interrompere il trascinamento che verrà utilizzato per eseguire lo scorrimento (Facoltativo,predefinito = 10).
SCROLL_WAIT_TIME Se SCROLL_ACTION è USE_GESTURE, il tempo in millisecondi da attendere tra i gesti di scorrimento quando cerchi un oggetto su cui fare clic. (Facoltativo,valore predefinito = 1).

SWIPE_CONFIG

Oggetto Descrizione
SWIPE_DIRECTION TOP_TO_BOTTOM, BOTTOM_TO_TOP, LEFT_TO_RIGHT o RIGHT_TO_LEFT
SWIPE_FRACTION

Uno dei seguenti:

  • FULL: scorri dal bordo dello schermo all'altro

    OPPURE
  • DEFAULT: da un bordo dello schermo all'altro, con un buffer di cinque (5) pixel su ciascun lato.

    OPPURE
  • THREE_QUARTER, HALF o QUARTER: il gesto di scorrimento termina a cinque (5) pixel dal bordo dello schermo e inizia nel punto in modo da coprire la distanza indicata dello schermo.
NUMBER_OF_STEPS Il numero di passaggi da utilizzare per eseguire lo scorrimento. Leggi i segmentSteps.

Crea ed esegui

Il framework Spectatio viene compilato automaticamente nell'ambito dell'APK di test. Per compilare l'APK di test, la base di codice AOSP deve trovarsi sulla workstation locale. Dopo aver compilato l'APK di test, l'utente deve installarlo sul dispositivo ed eseguire il test.

Il seguente esempio di codice mostra la compilazione, l'installazione e l'esecuzione di un APK di 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

In questi comandi:

  • TEST-APK-NAME: il nome dell'app da testare. Ad esempio, imposta TEST-APK-NAME su AndroidAutomotiveSettingsTests per testare le impostazioni Wi-Fi come specificato nel file Android.bp. Il nome dell'APK è disponibile nel rispettivo file Android.bp per il test per auto e motori.

  • DEVICE-SERIAL: l'ID di serie del DUT. Questo parametro non è obbligatorio se è connesso un solo dispositivo all'host.

  • config-file-path: parametro facoltativo richiesto solo per fornire configurazioni dell'interfaccia utente del dispositivo non predefinite come specificato nel file di configurazione JSON. Se non vengono forniti, il framework utilizza i valori predefiniti per l'esecuzione dei test.

  • PATH-FOR-BUILT-TEST-APK: il percorso in cui viene compilato l'APK di test quando viene eseguito il comando make.

  • TEST-PACKAGE: il nome del pacchetto di test.

  • TEST-CLASSNAME: il nome della classe di test. Ad esempio, per il test Impostazioni Wi-Fi, il pacchetto di test è android.platform.tests e il nome della classe di test è WifiSettingTest.

Raccolta di snippet per auto e motori

La libreria di snippet per l'automotive è un insieme di librerie Android Test per Android Open Source Project (AOSP) progettate per interagire con app e servizi per l'automotive. Sfrutta Spectatio con un pratico meccanismo per eseguire chiamate di procedura remota (RPC) da una macchina host (di test) a un dispositivo Android.

Inizia

Prima di iniziare, consulta queste sezioni.

Prerequisiti

  • Python 3.x installato sulla macchina host.
  • Configurazione dell'ambiente AOSP con gli strumenti di compilazione necessari.
  • Un dispositivo Android Automotive (emulatore o dispositivo fisico) con accesso adb.

Compilation

Per compilare i vari snippet forniti dalla libreria di snippet per il settore auto e motori, puoi utilizzare il file android.bp fornito. Segui i comandi della sezione precedente per compilare l'APK.

Implementazione

Dopo aver compilato correttamente le librerie di snippet, esegui il deployment degli APK risultanti sul dispositivo di destinazione utilizzando il comando adb install indicato nella sezione precedente.

Esegui test

Le librerie di snippet mettono a disposizione diversi metodi RPC per interagire con il sistema auto e motori. Questi metodi possono essere invocati tramite il framework Mobly dalla macchina ospitante. Supponendo che tu abbia configurato l'ambiente di test Mobly, puoi utilizzare lo script snippet_shell.py per aprire una shell Python interattiva in cui puoi invocare manualmente i metodi RPC sul dispositivo. Chiamata di esempio:

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

Sostituisci <serial> con il numero di serie del dispositivo, che puoi ottenere conadb devices se sono collegati più dispositivi.

Librerie incluse

La libreria di snippet per i veicoli include le seguenti librerie di snippet e gli annunci di assistenza:

  • AutomotiveSnippet: fornisce API relative alle operazioni del veicolo, come dialing, controllo del volume, tasti fisici del veicolo e interazione con il media center.

  • PhoneSnippet: fornisce API correlate alla telefonia, tra cui gestione delle chiamate, navigazione tra i contatti e operazioni SMS.

Lo snippet Automotive e lo snippet Phone condividono una logica comune. Nello specifico, puoi invadere le chiamate RCP correlate al Bluetooth per accoppiare un dispositivo auto e uno smartphone. Questo bt_discovery_test mostra come.