Spectatio: Framework pengujian otomotif

Spectatio adalah framework pengujian open source yang dikembangkan untuk menguji Android Automotive OS (AAOS) di perangkat nyata dan virtual. Spectatio menyediakan API untuk menguji aplikasi di perangkat otomotif dan merupakan solusi yang dapat diperluas dan diskalakan yang digunakan untuk memverifikasi kemampuan dan performa AAOS serta aplikasinya.

Desain tingkat tinggi

Framework Spectatio dapat diadaptasi dan diperluas untuk berbagai penerapan UI AAOS. Framework ini digunakan untuk menguji kemampuan dan performa AAOS pada hardware perangkat, emulator, dan lingkungan virtual.

Gambar berikut menjelaskan desain tingkat tinggi framework Spectatio.

Desain tingkat tinggi framework Spectatio

Gambar 1. Desain tingkat tinggi framework Spectatio.

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

Gambar 1 menunjukkan bahwa framework Spectatio dimodularisasi berdasarkan aplikasi referensi seperti Dialer, Medicenter, dan Setelan menggunakan antarmuka dan helper khusus aplikasi, sehingga mudah diperluas untuk aplikasi baru. Framework Spectatio menggunakan kembali class helper utilitas dan standar umum. Class helper standar adalah class induk untuk semua fungsi helper aplikasi dan menyediakan fungsi standar yang khusus untuk perangkat atau berlaku di seluruh aplikasi. Class helper utilitas menyediakan utilitas seperti membaca atau menulis file dari perangkat.

Arsitektur

Untuk menyediakan serangkaian API untuk membuat pengujian UI, framework Spectatio menerapkan antarmuka dan helper khusus aplikasi sambil memperluas class helper standar yang ada dan mengimpor class helper utilitas.

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

Arsitektur tingkat tinggi framework Spectatio

Gambar 2. Arsitektur tingkat tinggi framework Spectatio.

Antarmuka helper aplikasi menyediakan cetak biru untuk penerapan helper aplikasi. Antarmuka ini terdiri dari berbagai fungsi helper yang diperlukan untuk menguji aplikasi. Setiap aplikasi memiliki antarmukanya sendiri, seperti IAutoSettingHelper dan IAutoDialHelper. Untuk mengetahui informasi selengkapnya dan daftar fungsi antarmuka, lihat fungsi antarmuka helper aplikasi di AOSP.

Class helper standar terdiri dari atribut dan fungsi standar yang diperlukan untuk penyiapan perangkat, tetapi tidak khusus untuk aplikasi apa pun, seperti pressHome dan scroll. Class helper standar ditentukan dalam AbstractAutoStandardAppHelper.java.

Class helper utilitas digunakan oleh framework. Misalnya, AutoJsonUtility.java adalah class utilitas yang memuat file konfigurasi JSON perangkat yang diberikan dan mengupdate konfigurasi framework saat runtime.

Modul penerapan helper aplikasi adalah inti dari framework Spectatio. Modul ini berisi penerapan untuk fungsi helper yang ditentukan dalam antarmuka helper aplikasi, yang diperlukan untuk menguji aplikasi di perangkat otomotif. Setiap aplikasi memiliki implementasinya sendiri, seperti SettingHelperImpl dan DialHelperImpl, yang digunakan oleh pengujian Otomotif untuk menguji aplikasi. Untuk mengetahui informasi selengkapnya dan daftar penerapan, lihat fungsi penerapan helper aplikasi 'di AOSP.

Pengujian Otomotif menggunakan fungsi penerapan helper aplikasi untuk menguji berbagai operasi yang terkait dengan aplikasi. Gunakan class HelperAccessor untuk mendapatkan akses ke fungsi penerapan helper aplikasi.

Kode berikut menunjukkan penyiapan, pembersihan, dan eksekusi pengujian otomotif contoh.

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

Penyesuaian

Framework Spectatio independen dari UI perangkat, sehingga dapat diskalakan untuk menguji perangkat dengan berbagai UI dan hardware. Untuk mencapai skalabilitas ini, Spectatio menggunakan konfigurasi perangkat default berdasarkan perangkat referensi. Untuk mendukung konfigurasi perangkat non-default, framework menggunakan file konfigurasi JSON saat runtime untuk menetapkan perubahan UI yang diinginkan untuk perangkat. File konfigurasi JSON mendukung elemen UI seperti TEXT, DESCRIPTION, dan RESOURCE_ID, beserta setelan path dan hanya boleh berisi informasi tentang perubahan UI untuk DUT. Elemen UI lainnya menggunakan nilai konfigurasi default yang disediakan dalam framework.

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 tempat setelan default diganti oleh setelan di DUT. Dalam contoh ini:

  • Setelan internet diberi nama Network &internet di perangkat referensi dan Connectivity di DUT.

  • Setelan tanggal dan waktu tersedia di Settings > Date and time untuk perangkat referensi dan di Settings > System > Date and time 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"
    },
    ....
}

Saat file konfigurasi JSON siap, file tersebut akan disediakan 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:

Objek Deskripsi
PACKAGES Objek yang menjelaskan paket utama untuk berbagai aplikasi, yang digunakan untuk menentukan kapan aplikasi tersebut berada di latar depan.
ACTIONS Objek yang menunjukkan jenis tindakan dan parameter untuk berbagai tindakan. Misalnya, apakah akan menggunakan tombol atau gestur untuk men-scroll.
COMMANDS Objek yang menentukan perintah yang melakukan berbagai tindakan.
UI_ELEMENTS Objek yang digunakan untuk membuat `BySelectors` UI Automator yang memilih Elemen UI (dijelaskan secara mendetail di bawah).
WORKFLOWS Urutan tindakan yang menyelesaikan tugas tingkat tinggi (dijelaskan secara mendetail di bawah).

Elemen UI

Setiap elemen UI memiliki TYPE yang menentukan apa yang akan dicari UI Automator untuk mengidentifikasi elemen (seperti ID resource, teks, dan deskripsi) serta nilai konfigurasi yang terkait dengan jenis tersebut. Secara umum, setiap kali helper mengidentifikasi elemen di layar menggunakan konfigurasi ini, helper akan mendapatkan tepat satu elemen. Jika beberapa elemen cocok dengan konfigurasi, elemen arbitrer akan digunakan dalam pengujian. Oleh karena itu, konfigurasi (umumnya) harus ditulis secara cukup spesifik sehingga mempersempit ke satu elemen dalam konteks yang relevan.

TEKS

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

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

TEXT_CONTAINS

Sama seperti TEXT, kecuali bahwa VALUE yang ditentukan hanya perlu muncul di suatu tempat dalam teks elemen agar cocok.

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

DESKRIPSI

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

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

RESOURCE_ID

Identifikasi elemen berdasarkan ID resource-nya, yang secara opsional juga memeriksa komponen paket ID tersebut. Kunci PACKAGE bersifat opsional; jika dihilangkan, paket apa pun akan cocok, dan hanya bagian ID yang mengikuti :id/ yang akan dipertimbangkan.

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

DAPAT DIKLIK, DAPAT DI-SCROLL

Identifikasi elemen berdasarkan apakah elemen tersebut dapat (atau tidak) diklik atau di-scroll. Ini adalah jenis elemen yang sangat luas, dan umumnya hanya boleh digunakan dalam MULTIPLE untuk membantu mempersempit jenis elemen lain. Kunci FLAG bersifat opsional, dan defaultnya adalah true.

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

CLASS

Identifikasi elemen berdasarkan class-nya.

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

HAS_ANCESTOR

Identifikasi elemen dengan mencari hierarki widget di ancestor-nya. Kunci ANCESTOR menyimpan objek yang mengidentifikasi ancestor. Kunci DEPTH menentukan seberapa jauh hierarki yang akan dicari. 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 di turunannya. Kunci DESCENDANT menyimpan objek yang menentukan turunan yang akan dicari. Kunci DEPTH menentukan seberapa jauh hierarki yang akan dicari. DEPTH bersifat opsional dan memiliki nilai default 1.

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

MULTIPLE

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.

Workflows

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 daripada 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 dengan kunci adalah nama alur kerja dan nilai adalah array tindakan yang akan 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 memiliki bentuk yang sama dengan entri elemen UI (lihat di atas). TYPE tersebut adalah:

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

Untuk TYPE lainnya, detail konfigurasinya adalah:

Objek Deskripsi
COMMAND Objek dengan nilai TEXT yang berisi perintah yang akan dieksekusi.
HAS_PACKAGE_IN_FOREGROUND Objek dengan nilai TEXT yang berisi paket.
SWIPE Hapus CONFIG key untuk tindakan SWIPE. Tindakan ini hanya menggunakan SWIPE_CONFIG
WAIT_MS Objek dengan nilai TEXT yang berisi jumlah milidetik yang akan ditunggu.

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

SCROLL_CONFIG

Objek Deskripsi
SCROLL_ACTION USE_GESTURE atau USE_BUTTON
SCROLL_DIRECTION HORIZONTAL atau VERTICAL
SCROLL_ELEMENT Objek yang menunjukkan penampung yang akan di-scroll, menggunakan bentuk yang sama dengan konfigurasi Elemen UI (lihat di atas).
SCROLL_FORWARD, SCROLL_BACKWARD Tombol scroll maju dan mundur (diperlukan saat SCROLL_ACTION adalah USE_BUTTON).
SCROLL_MARGIN Jika SCROLL_ACTION adalah USE_GESTURE, jarak dari tepi penampung untuk memulai dan menghentikan operasi tarik yang akan digunakan untuk melakukan scroll (Opsional, default = 10).
SCROLL_WAIT_TIME Jika SCROLL_ACTION adalah USE_GESTURE, waktu dalam milidetik untuk menunggu antara gestur scroll saat mencari objek yang akan diklik. (Opsional, default = 1).

SWIPE_CONFIG

Objek Deskripsi
SWIPE_DIRECTION Either TOP_TO_BOTTOM, BOTTOM_TO_TOP, LEFT_TO_RIGHT, atau RIGHT_TO_LEFT
SWIPE_FRACTION

Salah satu dari berikut:

  • FULL: Gestur geser 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 geser selesai lima (5) piksel dari tepi layar, dan dimulai pada titik sehingga mencakup jarak layar yang ditunjukkan.
NUMBER_OF_STEPS Jumlah langkah yang akan digunakan untuk melakukan geser. Lihat segmentSteps.

Mem-build dan menjalankan

Framework Spectatio otomatis di-build sebagai bagian dari APK pengujian. Untuk mem-build APK pengujian, codebase AOSP harus berada di workstation lokal. Setelah APK pengujian di-build, pengguna harus menginstal APK di perangkat dan menjalankan pengujian.

Contoh kode berikut menunjukkan pembuatan, penginstalan, 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, tetapkan TEST-APK-NAME ke AndroidAutomotiveSettingsTests untuk menguji setelan Wi-Fi seperti yang ditentukan dalam Android.bp file. Nama APK dapat ditemukan di file Android.bp masing-masing untuk pengujian Otomotif.

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

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

  • PATH-FOR-BUILT-TEST-APK: Jalur tempat APK pengujian di-build saat perintah make dijalankan.

  • TEST-PACKAGE: Nama paket pengujian.

  • TEST-CLASSNAME: Nama class pengujian. Misalnya, untuk pengujian Setelan Wi-Fi, paket pengujiannya adalah android.platform.tests dan nama class pengujiannya adalah WifiSettingTest.

Library Cuplikan Otomotif

Library Cuplikan Otomotif adalah kumpulan library Pengujian Android untuk Project Open Source Android (AOSP) yang dirancang untuk berinteraksi dengan aplikasi dan layanan otomotif. Library ini memanfaatkan Spectatio dengan mekanisme yang mudah untuk menjalankan panggilan prosedur jarak jauh (RPC) dari mesin host (pengujian) ke perangkat yang didukung Android.

Mulai

Sebelum memulai, tinjau bagian ini.

Prasyarat

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

Kompilasi

Untuk mengompilasi berbagai cuplikan yang disediakan oleh Library Cuplikan Otomotif, Anda dapat menggunakan file android.bp yang disediakan. Ikuti perintah di bagian sebelumnya untuk mengompilasi APK.

Deployment

Setelah berhasil mengompilasi library cuplikan, deploy APK yang dihasilkan ke perangkat target menggunakan perintah adb install yang disebutkan di bagian sebelumnya.

Menjalankan pengujian

Library cuplikan mengekspos beberapa metode RPC untuk berinteraksi dengan sistem otomotif. Metode ini dapat dipanggil melalui framework 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 di 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.

Library yang disertakan

Library Cuplikan Otomotif menyertakan library dan helper cuplikan berikut:

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

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

Cuplikan Otomotif dan PhoneSnippet berbagi beberapa logika umum. Secara khusus, Anda dapat mengganggu panggilan RCP terkait Bluetooth untuk memasangkan perangkat otomotif dan perangkat telepon. Ini bt_discovery_test menunjukkan caranya.