Spectatio: Kerangka uji otomotif

Spectatio adalah kerangka pengujian sumber terbuka yang dikembangkan untuk menguji Android Automotive OS (AAOS) pada perangkat nyata dan virtual. Spectatio menyediakan API untuk menguji aplikasi pada perangkat otomotif dan merupakan solusi yang dapat diperluas dan diskalakan yang digunakan untuk memverifikasi kemampuan dan kinerja AAOS dan aplikasinya.

Desain tingkat tinggi

Kerangka kerja Spectatio dapat diadaptasi dan diperluas untuk berbagai implementasi AAOS UI. Ini digunakan untuk menguji kemampuan dan kinerja AAOS pada perangkat keras, emulator, dan lingkungan virtual.

Gambar berikut menjelaskan desain tingkat tinggi kerangka Spectatio.

Kerangka Spectatio desain tingkat tinggi

Gambar 1. Kerangka Spectatio desain tingkat tinggi.

Dibangun di atas UI Automator , kerangka kerja Spectatio menyediakan serangkaian API untuk membangun pengujian UI yang berinteraksi dengan aplikasi pengguna dan sistem di AAOS. Pengujian otomotif menggunakan API yang disediakan oleh kerangka kerja Spectatio untuk pengujian, yang menjadikan pengujian ini independen terhadap perangkat yang diuji (DUT) dan dapat diskalakan untuk menguji berbagai perangkat, jika didukung.

Gambar 1 menunjukkan bahwa kerangka Spectatio dimodulasi berdasarkan aplikasi referensi seperti Dialer, Medicenter, dan Pengaturan menggunakan antarmuka dan pembantu khusus aplikasi, sehingga mudah diperluas untuk aplikasi baru. Kerangka kerja Spectatio menggunakan kembali kelas pembantu standar dan utilitas umum. Kelas pembantu standar adalah kelas induk untuk semua fungsi pembantu aplikasi dan menyediakan fungsi standar yang spesifik untuk perangkat atau dapat diterapkan di seluruh aplikasi. Kelas pembantu utilitas menyediakan utilitas seperti membaca atau menulis file dari perangkat.

Arsitektur

Untuk menyediakan serangkaian API guna membangun pengujian UI, kerangka kerja Spectatio mengimplementasikan antarmuka dan pembantu khusus aplikasi sambil memperluas kelas pembantu standar yang ada dan mengimpor kelas pembantu utilitas.

Gambar 2 mengilustrasikan arsitektur tingkat tinggi kerangka Spectatio dan semua entitas yang terlibat dalam penerapan API untuk menguji aplikasi.

Kerangka Spectatio arsitektur tingkat tinggi

Gambar 2. Kerangka Spectatio arsitektur tingkat tinggi.

Antarmuka pembantu aplikasi menyediakan cetak biru untuk implementasi pembantu aplikasi. Ini terdiri dari berbagai fungsi pembantu yang diperlukan untuk menguji aplikasi. Setiap aplikasi memiliki antarmukanya sendiri, seperti IAutoSettingHelper dan IAutoDialHelper . Untuk informasi lebih lanjut dan daftar fungsi antarmuka, lihat fungsi antarmuka pembantu aplikasi di AOSP.

Kelas pembantu standar terdiri dari atribut dan fungsi standar yang diperlukan untuk pengaturan perangkat tetapi tidak spesifik untuk aplikasi apa pun, seperti pressHome dan scroll . Kelas pembantu standar didefinisikan dalam AbstractAutoStandardAppHelper.java .

Kelas pembantu utilitas digunakan oleh kerangka kerja. Misalnya, AutoJsonUtility.java adalah kelas utilitas yang memuat file konfigurasi JSON perangkat tertentu dan memperbarui konfigurasi kerangka kerja saat runtime.

Modul implementasi pembantu aplikasi adalah inti dari kerangka kerja Spectatio. Ini berisi implementasi fungsi pembantu yang ditentukan dalam antarmuka pembantu aplikasi, yang diperlukan untuk menguji aplikasi pada perangkat otomotif. Setiap aplikasi memiliki implementasinya sendiri, seperti SettingHelperImpl dan DialHelperImpl , yang digunakan oleh pengujian Otomotif untuk menguji aplikasi. Untuk informasi lebih lanjut dan daftar implementasi, lihat fungsi implementasi pembantu aplikasi 'di AOSP.

Tes Otomotif menggunakan fungsi implementasi pembantu aplikasi untuk menguji berbagai operasi yang terkait dengan aplikasi. Gunakan kelas HelperAccessor untuk mendapatkan akses ke fungsi implementasi pembantu aplikasi.

Kode berikut menunjukkan pengaturan, pembersihan, dan pelaksanaan contoh pengujian otomotif.

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

Kustomisasi

Framework Spectatio tidak bergantung pada UI perangkat, sehingga dapat diskalakan untuk menguji perangkat dengan beragam UI dan perangkat keras. Untuk mencapai skalabilitas ini, Spectatio menggunakan konfigurasi perangkat default berdasarkan perangkat referensi. Untuk mendukung konfigurasi perangkat non-default, kerangka kerja ini menggunakan file konfigurasi JSON saat runtime untuk mengatur perubahan UI yang diinginkan untuk perangkat. File konfigurasi JSON mendukung elemen UI seperti TEXT , DESCRIPTION , dan RESOURCE_ID , bersama dengan pengaturan path dan harus berisi hanya informasi tentang perubahan UI untuk DUT. Elemen UI lainnya menggunakan nilai konfigurasi default yang disediakan dalam kerangka kerja.

Konfigurasi perangkat default

Contoh file konfigurasi JSON berikut menunjukkan konfigurasi perangkat yang tersedia dan nilai defaultnya.

Klik di sini untuk menampilkan contoh file konfigurasi 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"
                        }
                }
        }
}
  

Konfigurasi perangkat alternatif

Contoh kode berikut menunjukkan contoh file konfigurasi JSON yang pengaturan defaultnya diganti dengan pengaturan di DUT. Dalam contoh ini:

  • Pengaturan Internet diberi nama Jaringan & internet pada perangkat referensi dan Konektivitas pada DUT.

  • Pengaturan tanggal dan waktu tersedia di Pengaturan > Tanggal dan waktu untuk perangkat referensi dan di Pengaturan > Sistem > Tanggal dan waktu untuk 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"
    },
    ....
}

Ketika file konfigurasi JSON sudah siap, file tersebut disediakan pada saat runtime seperti yang ditunjukkan dalam blok kode berikut:

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

Dalam perintah ini:

  • DEVICE-SERIAL : ID Seri DUT. Parameter ini tidak diperlukan jika hanya satu perangkat yang terhubung ke host.

  • PATH-TO-JSON-FILE : Jalur file JSON di mesin host.

Format konfigurasi

Ada lima objek tingkat atas dalam konfigurasi, dengan kunci dan nilai berikut:

Obyek Keterangan
PACKAGES Sebuah objek yang mendeskripsikan paket utama untuk berbagai aplikasi, yang digunakan untuk menentukan kapan aplikasi tersebut berada di latar depan.
ACTIONS Sebuah objek yang menunjukkan jenis tindakan dan parameter untuk berbagai tindakan. Misalnya apakah akan menggunakan tombol atau isyarat untuk menggulir.
COMMANDS Sebuah objek yang menentukan perintah yang melakukan berbagai tindakan.
UI_ELEMENTS Sebuah objek yang digunakan untuk membuat UI Automator `BySelectors` yang memilih Elemen UI (dijelaskan secara detail di bawah).
WORKFLOWS Urutan tindakan yang menyelesaikan tugas tingkat tinggi (dijelaskan secara rinci di bawah).

elemen UI

Setiap elemen UI memiliki TYPE yang menentukan apa yang akan dicari oleh UI Automator untuk mengidentifikasi elemen (seperti ID sumber daya, teks, dan deskripsi) dan nilai konfigurasi yang terkait dengan jenis tersebut. Secara umum, setiap kali helper mengidentifikasi sebuah elemen di layar menggunakan konfigurasi ini, ia mendapat tepat satu elemen. Jika beberapa elemen cocok dengan konfigurasinya, elemen arbitrer akan digunakan dalam pengujian. Oleh karena itu, konfigurasinya (umumnya) harus ditulis dengan cukup spesifik sehingga dapat dipersempit menjadi satu elemen dalam konteks yang relevan.

TEKS

Ini adalah tipe elemen UI yang paling sederhana. Elemen UI diidentifikasi berdasarkan teksnya, dan memerlukan pencocokan tepat.

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

TEXT_CONTAINS

Sama seperti TEXT , hanya saja VALUE yang ditentukan hanya perlu muncul di suatu tempat di teks elemen yang akan dicocokkan.

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

KETERANGAN

Identifikasi elemen berdasarkan atribut deskripsi kontennya, yang memerlukan pencocokan tepat.

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

RESOURCE_ID

Identifikasi elemen berdasarkan ID sumber dayanya, dan secara opsional periksa juga komponen paket dari ID tersebut. Kunci PACKAGE bersifat opsional; jika dihilangkan, paket apa pun akan cocok, dan hanya bagian dari ID berikut :id/ yang akan dipertimbangkan.

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

DAPAT DIKLIK, DAPAT DIGULIR

Identifikasi elemen berdasarkan apakah elemen tersebut dapat (atau tidak) dapat diklik atau digulir. Ini adalah tipe elemen yang sangat luas, dan umumnya hanya digunakan dalam MULTIPLE untuk membantu mempersempit tipe elemen lainnya. Kunci FLAG bersifat opsional, dan defaultnya adalah true .

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

KELAS

Identifikasi elemen berdasarkan kelasnya.

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

HAS_ANCESTOR

Identifikasi elemen dengan melihat hierarki widget berdasarkan leluhurnya. Kunci ANCESTOR menyimpan objek yang mengidentifikasi leluhur. Kunci DEPTH menentukan seberapa jauh hierarki yang akan dilihat. DEPTH bersifat opsional dan memiliki nilai default 1 .

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

HAS_DESCENDANT

Identifikasi elemen dengan melihat hierarki pada anak-anaknya. Kunci DESCENDANT menyimpan objek yang menentukan anak yang akan dicari. Kunci DEPTH menentukan seberapa jauh hierarki yang akan dilihat. DEPTH bersifat opsional dan memiliki nilai default 1 .

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

GANDA

Identifikasi elemen berdasarkan beberapa kondisi simultan, yang semuanya harus dipenuhi.

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

Dalam contoh ini, konfigurasi mengidentifikasi RelativeLayout yang memiliki turunan di kedalaman 2 , yang memiliki teks Permission manager .

Alur kerja

Alur kerja mewakili urutan tindakan yang digunakan untuk menyelesaikan tugas tertentu, yang mungkin cukup berbeda dari jenis perangkat ke jenis perangkat dan lebih fleksibel untuk direpresentasikan dalam konfigurasi dibandingkan dalam kode.

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

Setiap alur kerja adalah pasangan kunci-nilai yang mana kuncinya adalah nama alur kerja dan nilainya adalah serangkaian tindakan yang harus dilakukan. Setiap tindakan memiliki NAME , TYPE , (biasanya) CONFIG , dan (terkadang) SWIPE_CONFIG atau SCROLL_CONFIG . Untuk sebagian besar TYPE, CONFIG adalah objek dengan kunci UI_ELEMENT yang nilainya mengambil bentuk yang sama dengan entri elemen UI (lihat di atas). JENIS-JENIS tersebut adalah:

TEKAN
PANJANG_PRESS
KLIK
PANJANG_KLIK
KLIK_IF_EXIST
HAS_UI_ELEMENT_IN_FOREGROUND
GULIR_TO_FIND_AND_KLIK
SCROLL_TO_FIND_AND_CLICK_IF_EXIST
SWIPE_TO_FIND_AND_KLIK
SWIPE_TO_FIND_AND_CLICK_IF_EXIST

Untuk JENIS lainnya, detail konfigurasinya adalah:

Obyek Keterangan
COMMAND Sebuah objek dengan nilai TEXT yang berisi perintah untuk dieksekusi.
HAS_PACKAGE_IN_FOREGROUND Sebuah objek dengan nilai TEXT yang berisi paket.
SWIPE Hilangkan CONFIG key untuk tindakan SWIPE . Ini hanya menggunakan SWIPE_CONFIG
WAIT_MS Sebuah objek dengan nilai TEXT berisi jumlah milidetik untuk menunggu.

Tindakan terkait gulir dan geser memerlukan konfigurasi tambahan, sebagai berikut:

GULIR_CONFIG

Obyek Keterangan
SCROLL_ACTION Entah USE_GESTURE atau USE_BUTTON
SCROLL_DIRECTION Bisa HORIZONTAL atau VERTICAL
SCROLL_ELEMENT Sebuah objek yang menunjukkan wadah untuk digulir, menggunakan formulir yang sama dengan konfigurasi Elemen UI (lihat di atas).
SCROLL_FORWARD , SCROLL_BACKWARD Tombol gulir maju dan mundur (diperlukan jika SCROLL_ACTION adalah USE_BUTTON ).
SCROLL_MARGIN Jika SCROLL_ACTION adalah USE_GESTURE , jarak dari tepi wadah untuk memulai dan menghentikan drag yang akan digunakan untuk melakukan scroll ( Opsional, default = 10).
SCROLL_WAIT_TIME Jika SCROLL_ACTION adalah USE_GESTURE , waktu dalam milidetik untuk menunggu di antara gerakan gulir saat mencari objek yang akan diklik. ( Opsional, default = 1).

SWIPE_CONFIG

Obyek Keterangan
SWIPE_DIRECTION Entah TOP_TO_BOTTOM , BOTTOM_TO_TOP , LEFT_TO_RIGHT , atau RIGHT_TO_LEFT
SWIPE_FRACTION

Satu dari berikut:

  • FULL : Gesek gerakan dari tepi layar ke tepi layar

    ATAU,
  • DEFAULT : Tepi layar ke tepi layar, dengan buffer lima (5) piksel di setiap sisi.

    ATAU,
  • THREE_QUARTER , HALF , atau QUARTER : Gestur gesek berakhir pada lima (5) piksel dari tepi layar, dan dimulai pada titik yang mencakup jarak layar yang ditentukan.
NUMBER_OF_STEPS Jumlah langkah yang akan digunakan untuk melakukan gesekan. Lihat segmentSteps .

Bangun dan jalankan

Framework Spectatio secara otomatis dibuat sebagai bagian dari APK pengujian. Untuk membuat APK pengujian, basis kode AOSP harus berada di stasiun kerja lokal. Setelah APK pengujian dibuat, pengguna harus menginstal APK pada perangkat dan menjalankan pengujian.

Contoh kode berikut menunjukkan pembuatan, instalasi, dan eksekusi APK pengujian.

# 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

Dalam perintah ini:

  • TEST-APK-NAME : Nama aplikasi yang akan diuji. Misalnya, setel TEST-APK-NAME ke AndroidAutomotiveSettingsTests untuk menguji setelan Wi-Fi seperti yang ditentukan dalam file Android.bp . Nama APK dapat ditemukan di masing-masing file Android.bp untuk tes Otomotif .

  • DEVICE-SERIAL : ID serial DUT. Parameter ini tidak diperlukan jika hanya satu perangkat yang terhubung ke host.

  • config-file-path : Parameter opsional yang diperlukan hanya untuk menyediakan konfigurasi UI perangkat non-default seperti yang ditentukan dalam file konfigurasi JSON . Jika tidak disediakan, kerangka kerja akan menggunakan nilai default untuk menjalankan pengujian.

  • PATH-FOR-BUILT-TEST-APK : Jalur tempat APK pengujian dibuat ketika perintah make dijalankan.

  • TEST-PACKAGE : Nama paket tes.

  • TEST-CLASSNAME : Nama kelas tes. Misalnya, untuk pengujian Wifi Settings , paket pengujiannya adalah android.platform.tests dan nama kelas pengujiannya adalah WifiSettingTest .

Perpustakaan Cuplikan Otomotif

Library Cuplikan Otomotif adalah sekumpulan pustaka Tes Android untuk Proyek Sumber Terbuka Android (AOSP) yang dirancang untuk berinteraksi dengan aplikasi dan layanan otomotif. Ini memanfaatkan Spectatio dengan mekanisme yang mudah untuk mengeksekusi panggilan prosedur jarak jauh (RPC) dari mesin host (pengujian) ke perangkat yang diberdayakan Android.

Memulai

Sebelum Anda mulai, tinjau bagian ini.

Prasyarat

  • Python 3.x diinstal pada mesin host.
  • Pengaturan lingkungan AOSP dengan alat build yang diperlukan.
  • Perangkat otomotif Android (emulator atau perangkat fisik) dengan akses adb.

Kompilasi

Untuk mengkompilasi berbagai snippet yang disediakan oleh Automotive Snippet Library, Anda dapat menggunakan file android.bp yang telah disediakan. Mengikuti perintah di bagian sebelumnya untuk mengkompilasi APK.

Penyebaran

Setelah berhasil mengkompilasi pustaka cuplikan, terapkan APK yang dihasilkan ke perangkat target menggunakan perintah adb install yang disebutkan di bagian sebelumnya.

Jalankan tes

Pustaka cuplikan memaparkan beberapa metode RPC untuk berinteraksi dengan sistem otomotif. Metode ini dapat dijalankan melalui kerangka Mobly dari mesin host. Dengan asumsi Anda telah menyiapkan lingkungan pengujian Mobly, Anda dapat menggunakan skrip snippet_shell.py untuk membuka shell Python interaktif, tempat Anda dapat memanggil metode RPC secara manual pada perangkat. Contoh pemanggilan:

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

Ganti <serial> dengan nomor seri perangkat, yang dapat Anda peroleh dengan perangkat adb jika beberapa perangkat terhubung.

Perpustakaan yang disertakan

Perpustakaan Cuplikan Otomotif mencakup pustaka cuplikan dan pembantu berikut:

  • AutomotiveSnippet: Menyediakan API yang terkait dengan pengoperasian kendaraan, seperti panggilan, kontrol volume, tombol keras kendaraan, dan interaksi pusat media.

  • PhoneSnippet: Menyediakan API terkait telepon, termasuk penanganan panggilan, penelusuran kontak, dan operasi SMS.

Cuplikan Otomotif dan PhoneSnippet memiliki logika yang sama. Secara khusus, Anda dapat menyerang panggilan RCP terkait Bluetooth untuk memasangkan perangkat otomotif dan telepon. bt_discovery_test ini menunjukkan caranya.