Spectatio ist ein Open-Source-Test-Framework, das zum Testen von Android entwickelt wurde. Automotive OS (AAOS) auf realen und virtuellen Geräten Spectatio bietet APIs für Das Testen von Apps auf einem Automobilgerät ist eine erweiterbare und skalierbare Lösung. zur Überprüfung der Leistungsfähigkeit und Leistung von AAOS und seinen Apps.
Übergeordnetes Design
Das Spectatio-Framework ist an verschiedene AAOS-UIs anpassbar und erweiterbar Implementierungen. Damit werden die Fähigkeiten und die Leistung von AAOS getestet. in Gerätehardware, in Emulatoren und in virtualisierten Umgebungen.
In der folgenden Abbildung wird das übergeordnete Design des Spectatio-Frameworks erläutert.
Abbildung 1: High-Level-Design des Spectatio-Frameworks.
Das Spectatio-Framework basiert auf UI Automator und bietet eine Reihe von APIs. zum Erstellen von UI-Tests, die mit Nutzer- und System-Apps unter AAOS interagieren. Automobilindustrie Tests nutzen die vom Spectatio-Framework bereitgestellten APIs, wodurch Diese Tests sind unabhängig vom zu testenden Gerät und können getestet werden verschiedene Geräte verwenden, sofern dies unterstützt wird.
Abbildung 1 zeigt, dass das Spectatio-Framework basierend auf Referenzen modularisiert wird. wie Dialer, Medicenter und Einstellungen mit app-spezifischen Benutzeroberflächen und Hilfsfunktionen, sodass es einfach für neue Apps erweitert werden kann. Das Spetatio verwendet die gängigen Standard- und Hilfsprogramm-Hilfsklassen. Standard-Hilfsklasse ist die übergeordnete Klasse für alle App-Hilfsfunktionen und bietet Standardfunktionen, die gerätespezifisch sind oder appübergreifend anwendbar sind. Die utility-helper-Klassen bieten Dienstprogramme wie das Lesen oder Schreiben von Dateien auf dem Gerät.
Architektur
Um eine Reihe von APIs zum Erstellen von UI-Tests bereitzustellen, implementiert das Spectatio-Framework App-spezifische Schnittstellen und Hilfsfunktionen und erweitern gleichzeitig das bestehende und importieren die Hilfsprogrammklassen.
Abbildung 2 veranschaulicht die allgemeine Architektur des Spectatio-Frameworks und alle Entitäten, die an der Implementierung von APIs zum Testen einer Anwendung beteiligt sind.
Abbildung 2: Allgemeine Architektur des Spectatio-Frameworks
Die App-Hilfsoberfläche enthält eine Vorlage für die Implementierung von
App Helper. Sie besteht aus verschiedenen Hilfsfunktionen,
zum Testen von Apps. Jede App hat eine eigene Benutzeroberfläche, z. B. IAutoSettingHelper
.
und IAutoDialHelper
.
Weitere Informationen und eine Liste der Schnittstellenfunktionen finden Sie unter Oberflächenfunktionen des App-Hilfsprogramms auf AOSP.
Die Standardhilfsklasse besteht aus Standardattributen und -funktionen, die
für die Geräteeinrichtung erforderlich, sind aber nicht für eine App spezifisch, z. B. pressHome
und scroll
. Die Standard-Hilfsklasse ist in AbstractAutoStandardAppHelper.java
definiert.
Die Dienstprogramm-Hilfsklassen werden vom Framework verwendet. Für
AutoJsonUtility.java
ist beispielsweise
Dienstprogrammklasse, die die angegebene JSON-Konfigurationsdatei für das Gerät lädt und aktualisiert
Framework-Konfigurationen während der Laufzeit.
Das App Helper-Implementierungsmodul ist der Kern von Spectatio
Framework. Es enthält die Implementierung der Hilfsfunktionen, die in
der App-Hilfsoberfläche, die zum Testen von Apps auf einem
im Auto. Jede App hat eine eigene Implementierung, z. B. SettingHelperImpl
.
und
DialHelperImpl
,
verwendet von
die Automotive-Tests
zum Testen der Apps. Weitere Informationen sowie eine Liste der
Weitere Informationen zu Implementierungen finden Sie unter Implementierungsfunktionen des App-Hilfeassistenten.
auf AOSP.
Autotests
Mit den Implementierungsfunktionen des App Helper verschiedene Vorgänge testen
die mit der App in Zusammenhang stehen. HelperAccessor
-Klasse verwenden
um Zugriff auf die Implementierungsfunktionen des App-Hilfsprogramms zu erhalten.
Der folgende Code zeigt die Einrichtung, Bereinigung und Ausführung eines Beispiels in der Automobilbranche.
@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());
}
}
Personalisierung
Das Spectatio-Framework ist unabhängig von der Geräte-UI und daher skalierbar für
mit unterschiedlichen Benutzeroberflächen und Hardware testen. Um diese Skalierbarkeit zu erreichen,
Spectatio verwendet Standardgerätekonfigurationen basierend auf dem Referenzgerät. Bis
nicht standardmäßige Gerätekonfigurationen unterstützen, verwendet das Framework
Konfigurationsdatei, um die gewünschten Änderungen an der Benutzeroberfläche für das Gerät festzulegen. A
Die JSON-Konfigurationsdatei unterstützt UI-Elemente wie TEXT
, DESCRIPTION
und
RESOURCE_ID
, zusammen mit den path
-Einstellungen und darf nur die Informationen enthalten
zu den UI-Änderungen
für das DUT. Für die restlichen UI-Elemente werden die
Konfigurationswerte, die im Framework bereitgestellt werden.
Standard-Gerätekonfigurationen
Das folgende Beispiel für eine JSON-Konfigurationsdatei zeigt das verfügbare Gerät. Konfigurationen und deren Standardwerte.
Hier klicken, um ein JSON-Beispiel anzusehen Konfigurationsdatei
{ "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" } } } }
Alternative Gerätekonfigurationen
Das folgende Codebeispiel zeigt ein Beispiel für eine JSON-Konfigurationsdatei, in der Standardeinstellungen werden von den Einstellungen auf dem DUT überschrieben. In diesem Beispiel gilt Folgendes:
Die Interneteinstellungen heißen Netzwerk- und Internet auf Referenzgeräten und Konnektivität auf dem DUT.
Die Datums- und Uhrzeiteinstellungen finden Sie unter Einstellungen > Datum und Uhrzeit für Gerätereferenz und wählen Sie Einstellungen > System > Datum und Uhrzeit für die 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"
},
....
}
Wenn die JSON-Konfigurationsdatei fertig ist, wird sie zur Laufzeit bereitgestellt, wie in folgenden Codeblock:
# Push The JSON configuration file to the device
adb -s DEVICE-SERIAL push PATH-OF-JSON-FILE /data/local/tmp/runtimeSpectatioConfig.json
In diesem Befehl gilt:
DEVICE-SERIAL: Seriennummer des DUT. Dieser Parameter ist nicht erforderlich, wenn nur ein Gerät mit dem Host verbunden ist.
PATH-TO-JSON-FILE: Pfad der JSON-Datei auf dem Hostcomputer.
Konfigurationsformat
Die Konfiguration enthält fünf Objekte der obersten Ebene mit den folgenden Schlüsseln und Werte:
Objekt | Beschreibung |
---|---|
PACKAGES |
Ein Objekt, das das Hauptpaket für verschiedene Apps beschreibt, die für Folgendes verwendet werden: wann diese App im Vordergrund ausgeführt wird. |
ACTIONS |
Ein Objekt, das Aktionstypen und Parameter für verschiedene Aktionen angibt. Legen Sie beispielsweise fest, ob zum Scrollen Schaltflächen oder eine Touch-Geste verwendet werden soll. |
COMMANDS |
Ein Objekt, das Befehle zum Ausführen verschiedener Aktionen angibt. |
UI_ELEMENTS |
Ein Objekt zum Erstellen des UI-Automators „BySelectors“, der die Benutzeroberfläche auswählt Elemente (ausführlich unten beschrieben). |
WORKFLOWS |
Abfolgen von Aktionen, die übergeordnete Aufgaben erledigen (beschrieben in siehe unten). |
UI-Elemente
Jedes UI-Element hat ein TYPE
, das angibt, wonach der UI-Automator sucht,
Identifizieren des Elements (z. B. Ressourcen-ID, Text und Beschreibung) und
Konfigurationswerte, die diesem Typ zugeordnet sind. Grundsätzlich gilt, wenn ein Hilfsprogramm
mit dieser Konfiguration ein Element auf dem Bildschirm identifiziert,
ein Element. Wenn mehrere Elemente mit der Konfiguration übereinstimmen, wird ein beliebiges Element verwendet.
die im Test verwendet wurden. Daher sollte die Konfiguration (im Allgemeinen) so geschrieben werden,
dass es sich im relevanten Kontext auf ein Element beschränkt.
TEXT
Dies ist der einfachste UI-Elementtyp. Das UI-Element wird durch seinen Text, und erfordert eine genaue Übereinstimmung.
"CALL_HISTORY_MENU": {
"TYPE": "TEXT",
"VALUE": "Recents"
}
TEXT_ENTHÄLT
Entspricht TEXT
, mit dem Unterschied, dass die angegebenen VALUE
nur irgendwo in
den Text des Elements, das abgeglichen werden soll.
"PRIVACY_CALENDAR": {
"TYPE": "TEXT_CONTAINS",
"VALUE": "Calendar"
}
BESCHREIBUNG
Identifizieren Sie das Element anhand seines Inhaltsbeschreibungsattributs. Hierfür ist eine genaue Übereinstimmung.
"APP_GRID_SCROLL_BACKWARD_BUTTON": {
"TYPE": "DESCRIPTION",
"VALUE": "Scroll up"
}
RESSOURCEN-ID
Identifizieren Sie das Element anhand seiner Ressourcen-ID und prüfen Sie optional auch das Paket
Komponente dieser ID. Der Schlüssel PACKAGE
ist optional. wenn nicht angegeben, alle Pakete
stimmt überein und nur der Teil der ID nach :id/
wird berücksichtigt.
"APP_LIST_SCROLL_ELEMENT": {
"TYPE": "RESOURCE_ID",
"VALUE": "apps_grid",
"PACKAGE": "com.android.car.carlauncher"
}
ANKLICKBAR, SCROLLBAR
Identifizieren Sie das Element danach, ob es anklickbar oder scrollbar ist.
Dies sind sehr weit gefasste Elementtypen, die im Allgemeinen nur in
MULTIPLE
, um einen anderen Elementtyp einzugrenzen. Der Schlüssel FLAG
ist optional.
und ist standardmäßig auf true
gesetzt.
"SAMPLE_ELEMENT": {
"TYPE": "CLICKABLE",
"FLAG": false
}
KLASSE
Bestimmen Sie das Element anhand seiner Klasse.
"SECURITY_SETTINGS_ENTER_PASSWORD": {
"TYPE": "CLASS",
"VALUE": "android.widget.EditText"
}
HAS_ANCESTOR
Identifizieren Sie das Element, indem Sie die Widget-Hierarchie bei seinen Ancestors ansehen. Die
Der Schlüssel ANCESTOR
enthält ein Objekt, das den Ancestor identifiziert. Der DEPTH
-Schlüssel
gibt an, wie weit nach oben in der Hierarchie gesucht werden soll. DEPTH
ist optional und hat einen
Standardwert 1
.
"SAMPLE_ELEMENT": {
"TYPE": "HAS_ANCESTOR",
"DEPTH": 2,
"ANCESTOR": {
"TYPE": "CLASS",
"VALUE": "android.view.ViewGroup"
}
}
HAS_DESCENDANT
Identifizieren Sie das Element, indem Sie sich in der Hierarchie die untergeordneten Elemente ansehen. Die
Der Schlüssel DESCENDANT
enthält ein Objekt, das das untergeordnete Element angibt, nach dem gesucht werden soll. Die
Der Schlüssel DEPTH
gibt an, wie weit nach oben in der Hierarchie gesucht werden soll. DEPTH
ist optional und
hat den Standardwert 1
.
"SAMPLE_ELEMENT": {
"TYPE": "HAS_DESCENDANT",
"DEPTH": 2,
"DESCENDANT": {
"TYPE": "CLASS",
"VALUE": "android.view.ViewGroup"
}
}
MEHRERE
Das Element basierend auf mehreren gleichzeitigen Bedingungen identifizieren, die alle erfüllt sein müssen.
"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 diesem Beispiel identifiziert die Konfiguration ein RelativeLayout
mit einem
Nachfolgerelement in der Tiefe 2
mit dem Text Permission manager
.
Workflows
Ein Workflow stellt eine Abfolge von Aktionen dar, die verwendet werden, um eine bestimmte die sich von Gerätetyp zu Gerätetyp stark unterscheiden kann und lässt sich in der Konfiguration flexibel als im Code darstellen.
"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"
}
}
}
]
}
Jeder Workflow besteht aus einem Schlüssel/Wert-Paar, bei dem der Schlüssel der Name des Workflows und
Der Wert ist ein Array von durchzuführenden Aktionen. Jeder Aktion ist ein NAME
, ein TYPE
,
(normalerweise) CONFIG
und manchmal SWIPE_CONFIG
oder SCROLL_CONFIG
. Für
ist das CONFIG
ein Objekt mit einem UI_ELEMENT
-Schlüssel, dessen Wert
dasselbe Formular wie ein UI-Element-Eintrag (siehe oben). Diese TYPE sind:
DRÜCKEN LONG_PRESS KLICK 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 WISCHEN_TO_FIND_AND_CLICK_IF_EXIST |
Für die anderen TYPE sind die Konfigurationsdetails:
Objekt | Beschreibung |
---|---|
COMMAND |
Ein Objekt mit einem TEXT -Wert, der den auszuführenden Befehl enthält. |
HAS_PACKAGE_IN_FOREGROUND |
Ein Objekt mit einem TEXT -Wert, der das Paket enthält. |
SWIPE |
Lassen Sie CONFIG key für eine SWIPE -Aktion weg. Dieses
verwendet nur SWIPE_CONFIG |
WAIT_MS |
Ein Objekt mit einem TEXT -Wert, der die Anzahl der
Millisekunden warten. |
Aktionen zum Scrollen und Wischen erfordern eine zusätzliche Konfiguration:
SCROLL-KONFIGURATION
Objekt | Beschreibung |
---|---|
SCROLL_ACTION |
Entweder USE_GESTURE oder USE_BUTTON |
SCROLL_DIRECTION |
Entweder HORIZONTAL oder VERTICAL |
SCROLL_ELEMENT |
Ein Objekt, das den zu scrollenden Container angibt und dasselbe Format wie eine Benutzeroberfläche verwendet. Elementkonfiguration (siehe oben) |
SCROLL_FORWARD , SCROLL_BACKWARD |
Mit den Schaltflächen zum Vorwärts- und Rückwärtsscrollen (erforderlich bei
SCROLL_ACTION ist USE_BUTTON ). |
SCROLL_MARGIN |
Wenn SCROLL_ACTION den Wert USE_GESTURE hat, ist die Entfernung
vom Rand des Containers aus, um die Ziehbewegung zu starten und zu stoppen
zum Scrollen (optional,Standard = 10). |
SCROLL_WAIT_TIME |
Wenn SCROLL_ACTION den Wert USE_GESTURE hat, wird die Zeit in
Millisekunden zwischen Scrollbewegungen bleibt, wenn Sie nach einem Objekt suchen,
klicken.
(Optional,Standardwert = 1). |
SWIPE_CONFIG
Objekt | Beschreibung |
---|---|
SWIPE_DIRECTION |
Entweder TOP_TO_BOTTOM , BOTTOM_TO_TOP ,
LEFT_TO_RIGHT oder RIGHT_TO_LEFT |
SWIPE_FRACTION |
Eine der folgenden Optionen:
|
NUMBER_OF_STEPS |
Die Anzahl der Schritte, die für das Wischen ausgeführt werden sollen.
segmentSteps ansehen.
|
Erstellen und ausführen
Das Spectatio-Framework wird automatisch als Teil des Test-APKs erstellt. Zum Erstellen Test-APK muss sich die AOSP-Codebasis auf der lokalen Workstation befinden. Nach dem Test-APK erstellt, muss der Nutzer das APK auf dem Gerät installieren und die testen.
Das folgende Codebeispiel zeigt den Aufbau, die Installation und die Ausführung einer Test-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
Für diese Befehle gilt:
TEST-APK-NAME: Der Name der zu testenden App. Beispiel: Legen Sie TEST-APK-NAME bis
AndroidAutomotiveSettingsTests
, um die WLAN-Einstellungen zu testen wie inAndroid.bp
angegeben -Datei. Den Namen des APK finden Sie in der entsprechendenAndroid.bp
-Datei für den Automotive-Test.DEVICE-SERIAL: Die Seriennummer des DUT. Dieser Parameter ist nicht erforderlich, wenn nur ein Gerät mit dem Host verbunden ist.
config-file-path
: Optionaler Parameter, der nur zur Angabe erforderlich ist Nicht standardmäßige Konfigurationen für die Benutzeroberfläche von Geräten, wie in der JSON-Konfiguration angegeben Datei. Falls nicht angegeben, verwendet zum Ausführen der Tests Standardwerte.PATH-FOR-BUILT-TEST-APK: Pfad, in dem das Test-APK erstellt wird wenn der Befehl
make
ausgeführt wird.TEST-PACKAGE: Der Name des Testpakets.
TEST-CLASSNAME: Der Name der Testklasse. Für das Feld Wifi-Einstellungen testen, ist das Testpaket
android.platform.tests
und die Der Name der Testklasse lautetWifiSettingTest
.
Automotive-Snippet-Bibliothek
Die Automotive-Snippet-Bibliothek besteht aus einer Reihe von Android-Testbibliotheken für die Open Source Project (AOSP) von Android für die Interaktion mit der Automobilbranche Apps und Dienste. Es nutzt Spectatio mit einem praktischen Mechanismus zum Ausführen von Remoteprozeduraufrufen (Remote Procedure Calls, RPCs) von einer Host- bzw. Testmaschine an eine Android-Gerät
Erste Schritte
Lesen Sie sich diese Abschnitte durch, bevor Sie beginnen.
Voraussetzungen
- Python 3.x ist auf dem Hostcomputer installiert.
- Einrichtung der AOSP-Umgebung mit den erforderlichen Build-Tools
- Ein Android Automotive-Gerät (Emulator oder physisches Gerät) mit ADB-Zugriff.
Compilation
Um die verschiedenen Snippets der Automotive-Snippet-Bibliothek zu kompilieren,
können die bereitgestellte Datei android.bp
verwenden. Mit den folgenden Befehlen im vorherigen
, um das APK zu kompilieren.
Bereitstellung
Nachdem Sie die Snippet-Bibliotheken erfolgreich kompiliert haben, stellen Sie die resultierenden APKs auf
mit dem oben erwähnten Befehl adb install
an das Zielgerät
.
Tests ausführen
Die Snippet-Bibliotheken bieten mehrere RPC-Methoden für die Interaktion mit der Automobilindustrie
System. Diese Methoden können über das Mobly-Framework vom Host aus aufgerufen werden
Maschine. Wenn Sie die Mobly-Testumgebung eingerichtet haben, können Sie die Methode
snippet_shell.py
, um eine interaktive Python-Shell zu öffnen, in der Sie
RPC-Methoden auf dem Gerät manuell aufrufen. Beispielaufruf:
python3 snippet_shell.py com.google.android.mobly.snippet.bundled -s <serial>
Ersetzen Sie <serial>
durch die Seriennummer des Geräts, die Sie mit
ADB-Geräte, wenn mehrere Geräte verbunden sind.
Eingeschlossene Bibliotheken
Die Automotive-Snippet-Bibliothek enthält die folgenden Snippet-Bibliotheken und Helfer:
AutomotiveSnippet: stellt APIs für den Fahrzeugbetrieb bereit, z. B. Wählen, Lautstärkeregelung, Fahrzeugtasten und Interaktion mit dem Mediacenter.
PhoneSnippet: Bietet Telefonie-APIs, einschließlich Anrufbehandlung, das Durchsuchen von Kontakten und SMS-Vorgänge.
Das Automotive-Snippet und das PhoneSnippet haben eine gemeinsame Logik.
Insbesondere können Sie Bluetooth-bezogene RCP-Anrufe verwenden, um ein Automobil zu koppeln.
und einem Smartphone. In diesem bt_discovery_test
erfahren Sie, wie das geht.
- TEST-CLASSNAME: Der Name der Testklasse. Für das Feld
Wifi-Einstellungen testen,
Das Testpaket ist
android.platform.tests
und der Name der Testklasse istWifiSettingTest
.