Spectatio: platforma do testów motoryzacyjnych

Spectatio to platforma testowa typu open source opracowana do testowania systemu operacyjnego Android Automotive (AAOS) na rzeczywistych i wirtualnych urządzeniach. Spectatio udostępnia interfejsy API do testowania aplikacji na urządzeniu samochodowym. Jest to rozszerzalne i skalowalne rozwiązanie służące do weryfikowania możliwości i wydajności AAOS oraz jego aplikacji.

Projekt wysokiego poziomu

Platforma Spectatio jest elastyczna i można ją rozbudowywać w celu obsługi różnych implementacji interfejsu AAOS. Służy do testowania możliwości i wydajności AAOS na sprzęcie urządzenia, emulatorach i w środowiskach wirtualnych.

Na rysunku poniżej przedstawiono ogólną strukturę platformy Spectatio.

Ogólny projekt platformy Spectatio

Rysunek 1. Ogólny projekt platformy Spectatio.

Platforma Spectatio, oparta na UI Automator, udostępnia zestaw interfejsów API do tworzenia testów interfejsu, które wchodzą w interakcje z aplikacjami użytkownika i systemowymi w AAOS. Testy Automotive korzystają z interfejsów API udostępnianych przez platformę Spectatio, co sprawia, że są one niezależne od testowanego urządzenia i można je skalować, aby testować różne urządzenia, jeśli są one obsługiwane.

Na rysunku 1 widać, że platforma Spectatio jest podzielona na moduły na podstawie aplikacji referencyjnych, takich jak Dialer, Medicenter i Ustawienia, które korzystają z interfejsów i funkcji pomocniczych specyficznych dla aplikacji, co ułatwia rozszerzanie platformy o nowe aplikacje. Platforma Spectatio ponownie wykorzystuje standardowe i pomocnicze klasy narzędziowe. Standardowa klasa pomocnicza jest klasą nadrzędną dla wszystkich funkcji pomocniczych aplikacji i zapewnia standardowe funkcje, które są specyficzne dla urządzenia lub mają zastosowanie w różnych aplikacjach. Klasy narzędziowe udostępniają narzędzia, takie jak odczytywanie i zapisywanie plików na urządzeniu.

Architektura

Aby udostępnić zestaw interfejsów API do tworzenia testów interfejsu, platforma Spectatio implementuje interfejsy i funkcje pomocnicze specyficzne dla aplikacji, rozszerzając istniejącą standardową klasę funkcji pomocniczych i importując klasy funkcji pomocniczych narzędzi.

Rysunek 2 przedstawia ogólną architekturę platformy Spectatio i wszystkie podmioty zaangażowane we wdrażanie interfejsów API do testowania aplikacji.

Architektura wysokiego poziomu platformy Spectatio

Rysunek 2. Architektura wysokiego poziomu platformy Spectatio.

Interfejs pomocnika aplikacji zawiera plan wdrożenia pomocnika aplikacji. Zawiera różne funkcje pomocnicze potrzebne do testowania aplikacji. Każda aplikacja ma własny interfejs, np. IAutoSettingHelperIAutoDialHelper. Więcej informacji i listę funkcji interfejsu znajdziesz w sekcji Funkcje interfejsu pomocnika aplikacji na stronie AOSP.

Standardowa klasa pomocnicza składa się ze standardowych atrybutów i funkcji, które są wymagane do konfiguracji urządzenia, ale nie są specyficzne dla żadnej aplikacji, np. pressHomescroll. Standardowa klasa pomocnicza jest zdefiniowana w pliku AbstractAutoStandardAppHelper.java.

Framework korzysta z klas pomocniczych narzędzi. Na przykład AutoJsonUtility.java to klasa narzędziowa, która wczytuje podany plik konfiguracji JSON urządzenia i aktualizuje konfiguracje platformy w czasie działania.

Moduł implementacji pomocnika aplikacji jest podstawą platformy Spectatio. Zawiera implementację funkcji pomocniczych zdefiniowanych w interfejsie funkcji pomocniczych aplikacji, które są wymagane do testowania aplikacji na urządzeniu samochodowym. Każda aplikacja ma własną implementację, np. SettingHelperImplDialHelperImpl, używaną przez testy motoryzacyjne do testowania aplikacji. Więcej informacji i listę implementacji znajdziesz w sekcji Funkcje implementacji narzędzia do pomocy w aplikacji w AOSP.

Testy motoryzacyjne wykorzystują funkcje implementacji pomocnika aplikacji do testowania różnych operacji związanych z aplikacją. Aby uzyskać dostęp do funkcji implementacji pomocnika aplikacji, użyj klasy HelperAccessor.

Poniższy kod pokazuje konfigurację, czyszczenie i wykonanie przykładowego testu motoryzacyjnego.

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

Dostosowywanie

Platforma Spectatio jest niezależna od interfejsu urządzenia, więc można ją skalować do testowania urządzeń z różnymi interfejsami i sprzętem. Aby osiągnąć taką skalowalność, Spectatio używa domyślnych konfiguracji urządzeń opartych na urządzeniu referencyjnym. Aby obsługiwać niestandardowe konfiguracje urządzeń, platforma używa w czasie działania pliku konfiguracji JSON do ustawiania żądanych zmian interfejsu na urządzeniu. Plik konfiguracji JSON obsługuje elementy interfejsu, takie jak TEXT, DESCRIPTIONRESOURCE_ID, a także ustawienia path. Musi zawierać tylko informacje o zmianach interfejsu DUT. Pozostałe elementy interfejsu korzystają z domyślnych wartości konfiguracji udostępnianych w ramach platformy.

Domyślne konfiguracje urządzeń

Poniższy przykładowy plik konfiguracji JSON zawiera dostępne konfiguracje urządzeń i ich wartości domyślne.

Kliknij tutaj, aby wyświetlić przykładowy plik konfiguracyjny 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"
                        }
                }
        }
}
  

Konfiguracje urządzeń alternatywnych

Poniższy przykładowy kod pokazuje plik konfiguracyjny JSON, w którym ustawienia domyślne są zastępowane przez ustawienia na urządzeniu. W tym przykładzie:

  • Ustawienia internetu na urządzeniach referencyjnych noszą nazwę Sieć i internet, a na urządzeniu DUT – Łączność.

  • Ustawienia daty i godziny są dostępne w przypadku urządzeń referencyjnych w sekcji Ustawienia > Data i godzina, a w przypadku testowanego urządzenia – w sekcji Ustawienia > System > Data i godzina.

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

Gdy plik konfiguracyjny JSON jest gotowy, jest on udostępniany w czasie działania, jak pokazano w tym bloku kodu:

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

W tym poleceniu:

  • DEVICE-SERIAL: numer seryjny testowanego urządzenia. Ten parametr nie jest wymagany, jeśli z hostem połączone jest tylko jedno urządzenie.

  • PATH-TO-JSON-FILE: ścieżka do pliku JSON na komputerze hosta.

Format konfiguracji

Konfiguracja zawiera 5 obiektów najwyższego poziomu o tych kluczach i wartościach:

Obiekt Opis
PACKAGES Obiekt opisujący główny pakiet różnych aplikacji, który służy do określania, kiedy aplikacja jest na pierwszym planie.
ACTIONS Obiekt wskazujący typy działań i parametry różnych działań. Możesz na przykład wybrać, czy do przewijania chcesz używać przycisków czy gestu.
COMMANDS Obiekt określający polecenia, które wykonują różne działania.
UI_ELEMENTS Obiekt służący do tworzenia selektorów UI Automator `BySelectors`, które wybierają elementy interfejsu (opisane szczegółowo poniżej).
WORKFLOWS Sekwencje działań, które wykonują zadania wyższego poziomu (opisane szczegółowo poniżej).

Elementy interfejsu

Każdy element interfejsu ma TYPE, który określa, czego UI Automator będzie szukać, aby zidentyfikować element (np. identyfikator zasobu, tekst i opis), oraz wartości konfiguracji powiązane z tym typem. Ogólnie rzecz biorąc, gdy pomocnik zidentyfikuje element na ekranie za pomocą tej konfiguracji, otrzyma dokładnie jeden element. Jeśli do konfiguracji pasuje wiele elementów, w teście zostanie użyty dowolny z nich. Dlatego konfiguracja powinna być (zwykle) wystarczająco szczegółowa, aby w odpowiednim kontekście ograniczać się do jednego elementu.

TEKST

To najprostszy typ elementu interfejsu. Element interfejsu jest identyfikowany na podstawie tekstu i wymaga dopasowania ścisłego.

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

TEXT_CONTAINS

Podobnie jak TEXT, z tym wyjątkiem, że określony VALUE musi pojawić się tylko w tekście elementu, aby został dopasowany.

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

OPIS

Wyszukaj element na podstawie atrybutu opisu treści, wymagając dokładnego dopasowania.

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

RESOURCE_ID

Zidentyfikuj element na podstawie jego identyfikatora zasobu, opcjonalnie sprawdzając też komponent pakietu tego identyfikatora. Klucz PACKAGE jest opcjonalny. Jeśli go pominiesz, będzie pasować do dowolnego pakietu, a pod uwagę będzie brana tylko część identyfikatora po znaku :id/.

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

KLIKALNE, MOŻLIWE DO PRZEWIJANIA

Określ element na podstawie tego, czy można go kliknąć lub przewinąć. Są to bardzo ogólne typy elementów, które zwykle powinny być używane tylko w MULTIPLE, aby zawęzić inny typ elementu. Klucz FLAG jest opcjonalny i domyślnie ma wartość true.

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

KLASA

Określ element na podstawie jego klasy.

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

HAS_ANCESTOR

Zidentyfikuj element, sprawdzając hierarchię widżetów u jego przodków. Klucz ANCESTOR zawiera obiekt, który identyfikuje element nadrzędny. Klucz DEPTH określa, jak daleko w górę hierarchii ma sięgać wyszukiwanie. DEPTH jest opcjonalny i ma domyślną wartość 1.

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

HAS_DESCENDANT

Zidentyfikuj element, przeglądając hierarchię jego elementów podrzędnych. Klucz DESCENDANT zawiera obiekt, który określa element podrzędny do wyszukania. Klucz DEPTH określa, jak daleko w górę hierarchii ma sięgać wyszukiwanie. DEPTH jest opcjonalne i ma domyślną wartość 1.

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

WIELOKROTNE

Określ element na podstawie wielu warunków, które muszą być spełnione jednocześnie.

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

W tym przykładzie konfiguracja identyfikuje element RelativeLayout, który ma element podrzędny na poziomie 2, zawierający tekst Permission manager.

Workflows

Przepływ pracy to sekwencja działań służących do wykonania określonego zadania, która może się różnić w zależności od typu urządzenia i jest bardziej elastyczna w konfiguracji niż w kodzie.

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

Każdy przepływ pracy to para klucz-wartość, w której klucz jest nazwą przepływu pracy, a wartość to tablica działań do wykonania. Każda czynność ma NAMETYPE, (zwykle) CONFIG oraz (czasami) SWIPE_CONFIG lub SCROLL_CONFIG. W przypadku większości TYPÓW CONFIG to obiekt z kluczem UI_ELEMENT, którego wartość ma taką samą postać jak wpis elementu interfejsu (patrz wyżej). Są to:

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

W przypadku pozostałych TYPÓW szczegóły konfiguracji są następujące:

Obiekt Opis
COMMAND Obiekt z wartością TEXT zawierającą polecenie do wykonania.
HAS_PACKAGE_IN_FOREGROUND Obiekt z wartością TEXT zawierającą pakiet.
SWIPE W przypadku działania SWIPE pomiń znak CONFIG key. Ta funkcja korzysta tylko z SWIPE_CONFIG
WAIT_MS Obiekt z wartością TEXT zawierającą liczbę milisekund, które należy odczekać.

Działania związane z przewijaniem i przesuwaniem wymagają dodatkowej konfiguracji:

SCROLL_CONFIG

Obiekt Opis
SCROLL_ACTION Może to być USE_GESTURE lub USE_BUTTON
SCROLL_DIRECTION Może to być HORIZONTAL lub VERTICAL
SCROLL_ELEMENT Obiekt wskazujący kontener do przewijania, w takiej samej formie jak konfiguracja elementu interfejsu (patrz wyżej).
SCROLL_FORWARD, SCROLL_BACKWARD przyciski przewijania do przodu i do tyłu (wymagane, gdy SCROLL_ACTION ma wartość USE_BUTTON);
SCROLL_MARGIN Jeśli SCROLL_ACTION ma wartość USE_GESTURE, odległość od krawędzi kontenera, w której należy rozpocząć i zakończyć przeciąganie, aby przewinąć zawartość (opcjonalnie, domyślnie 10).
SCROLL_WAIT_TIME Jeśli wartość SCROLL_ACTION to USE_GESTURE, jest to czas w milisekundach, jaki należy odczekać między gestami przewijania podczas wyszukiwania obiektu, który ma zostać kliknięty. (Opcjonalne,wartość domyślna = 1).

SWIPE_CONFIG

Obiekt Opis
SWIPE_DIRECTION Może to być TOP_TO_BOTTOM, BOTTOM_TO_TOP, LEFT_TO_RIGHT lub RIGHT_TO_LEFT
SWIPE_FRACTION

Jedna z tych opcji:

  • FULL: gest przesuwania od krawędzi ekranu do krawędzi ekranu

    LUB
  • DEFAULT: od krawędzi do krawędzi ekranu, z 5-pikselowym marginesem po każdej stronie.

    LUB
  • THREE_QUARTER, HALF lubQUARTER: gest przesuwania kończy się 5 pikseli od krawędzi ekranu i zaczyna się w takim punkcie, aby obejmował wskazany odcinek ekranu.
NUMBER_OF_STEPS Liczba kroków, które należy wykonać, aby przesunąć palcem. Zobacz segmentSteps.

Tworzenie i wykonywanie

Platforma Spectatio jest automatycznie tworzona w ramach testowego pliku APK. Aby utworzyć testowy plik APK, kod źródłowy AOSP musi znajdować się na lokalnej stacji roboczej. Po utworzeniu testowego pliku APK użytkownik musi zainstalować go na urządzeniu i przeprowadzić test.

Poniższy przykładowy kod pokazuje tworzenie, instalowanie i wykonywanie testowego pliku APK.

# 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

W tych poleceniach:

  • TEST-APK-NAME: Nazwa aplikacji, która ma zostać przetestowana. Na przykład ustaw wartość TEST-APK-NAME na AndroidAutomotiveSettingsTests, aby przetestować ustawienia Wi-Fi zgodnie z plikiem Android.bp. Nazwę pliku APK znajdziesz w odpowiednim pliku Android.bp w przypadku testu aplikacji samochodowej.

  • DEVICE-SERIAL: numer seryjny testowanego urządzenia. Ten parametr nie jest wymagany, jeśli z hostem połączone jest tylko jedno urządzenie.

  • config-file-path: parametr opcjonalny, który jest wymagany tylko w przypadku udostępniania niestandardowych konfiguracji interfejsu urządzenia zgodnie z opisem w pliku konfiguracji JSON. Jeśli nie podasz tych wartości, platforma użyje wartości domyślnych do przeprowadzenia testów.

  • PATH-FOR-BUILT-TEST-APK: ścieżka, w której tworzony jest testowy plik APK po wykonaniu polecenia make.

  • TEST-PACKAGE: nazwa pakietu testowego.

  • TEST-CLASSNAME: nazwa klasy testu. Na przykład w przypadku testu Ustawienia Wi-Fi pakiet testowy to android.platform.tests, a nazwa klasy testowej to WifiSettingTest.

Biblioteka fragmentów dotyczących motoryzacji

Biblioteka fragmentów kodu Automotive to zestaw bibliotek testowych Androida dla Projektu Android Open Source Project (AOSP), które umożliwiają interakcję z aplikacjami i usługami motoryzacyjnymi. Wykorzystuje Spectatio z wygodnym mechanizmem wykonywania zdalnych wywołań procedur (RPC) z hosta (maszyny testowej) na urządzenie z Androidem.

Rozpocznij

Zanim zaczniesz, zapoznaj się z tymi sekcjami.

Wymagania wstępne

  • Python 3.x zainstalowany na komputerze hosta.
  • Konfiguracja środowiska AOSP z niezbędnymi narzędziami do kompilacji.
  • Urządzenie z Androidem Automotive (emulator lub urządzenie fizyczne) z dostępem do adb.

Kompilacja

Aby skompilować różne fragmenty kodu udostępnione w bibliotece fragmentów kodu dla branży motoryzacyjnej, możesz użyć podanego pliku android.bp. Aby skompilować plik APK, użyj poleceń z poprzedniej sekcji.

Wdrażanie

Po pomyślnym skompilowaniu bibliotek fragmentów wdróż uzyskane pliki APK na urządzeniu docelowym za pomocą polecenia adb install wspomnianego w poprzedniej sekcji.

Przeprowadzanie testów

Biblioteki fragmentów kodu udostępniają kilka metod RPC do interakcji z systemem samochodowym. Te metody można wywoływać za pomocą platformy Mobly z komputera hosta. Jeśli masz skonfigurowane środowisko testowe Mobly, możesz użyć skryptu snippet_shell.py, aby otworzyć interaktywną powłokę Pythona, w której możesz ręcznie wywoływać na urządzeniu metody RPC. Przykładowe wywołanie:

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

Zastąp <serial> numerem seryjnym urządzenia, który możesz uzyskać za pomocą polecenia adb devices, jeśli podłączonych jest wiele urządzeń.

Uwzględnione biblioteki

Biblioteka fragmentów kodu dla branży motoryzacyjnej zawiera te biblioteki fragmentów kodu i funkcje pomocnicze:

  • AutomotiveSnippet: udostępnia interfejsy API związane z obsługą pojazdu, takie jak wybieranie numeru, sterowanie głośnością, klawisze fizyczne pojazdu i interakcja z centrum multimediów.

  • PhoneSnippet: udostępnia interfejsy API związane z telefonią, w tym obsługę połączeń, przeglądanie kontaktów i operacje SMS.

Fragment kodu Automotive i fragment kodu PhoneSnippet mają wspólną logikę. Możesz w szczególności naruszać wywołania RCP związane z Bluetooth, aby sparować urządzenie samochodowe z telefonem. Ten bt_discovery_test pokazuje, jak to zrobić.