Spectatio เป็นเฟรมเวิร์กการทดสอบแบบโอเพนซอร์สที่พัฒนาขึ้นเพื่อทดสอบ Android Automotive OS (AAOS) ในอุปกรณ์จริงและอุปกรณ์เสมือน Spectatio มี API สำหรับ การทดสอบแอปในอุปกรณ์ยานยนต์ และเป็นโซลูชันที่ขยายและปรับขนาดได้ ซึ่งใช้เพื่อยืนยันความสามารถและประสิทธิภาพของ AAOS และแอปต่างๆ
การออกแบบระดับสูง
เฟรมเวิร์ก Spectatio สามารถปรับเปลี่ยนและขยายได้สำหรับการติดตั้งใช้งาน UI ของ AAOS ที่หลากหลาย ใช้เพื่อทดสอบความสามารถและประสิทธิภาพของ AAOS ในฮาร์ดแวร์ของอุปกรณ์ โปรแกรมจำลอง และสภาพแวดล้อมเสมือน
รูปภาพต่อไปนี้อธิบายการออกแบบระดับสูงของเฟรมเวิร์ก Spectatio
รูปที่ 1 การออกแบบระดับสูงของเฟรมเวิร์ก Spectatio
เฟรมเวิร์ก Spectatio สร้างขึ้นบน UI Automator และมีชุด API สำหรับสร้างการทดสอบ UI ที่โต้ตอบกับแอปของผู้ใช้และแอปของระบบใน AAOS การทดสอบยานยนต์ ใช้ API ที่เฟรมเวิร์ก Spectatio มีไว้สำหรับการทดสอบ ซึ่งทำให้ การทดสอบเหล่านี้ไม่ขึ้นอยู่กับอุปกรณ์ภายใต้การทดสอบ (DUT) และปรับขนาดเพื่อทดสอบ อุปกรณ์ต่างๆ ได้ หากรองรับ
รูปที่ 1 แสดงให้เห็นว่าเฟรมเวิร์ก Spectatio มีการแยกส่วนตามแอปอ้างอิง เช่น Dialer, Medicenter และ Settings โดยใช้อินเทอร์เฟซและตัวช่วยเฉพาะแอป ซึ่งทำให้ขยายไปยังแอปใหม่ๆ ได้ง่าย เฟรมเวิร์ก Spectatio ใช้คลาสตัวช่วยมาตรฐานและยูทิลิตีทั่วไปซ้ำ คลาสตัวช่วยมาตรฐาน เป็นคลาสหลักสำหรับฟังก์ชันตัวช่วยของแอปทั้งหมด และมี ฟังก์ชันมาตรฐานที่เฉพาะเจาะจงสำหรับอุปกรณ์หรือใช้ได้ในแอปต่างๆ คลาสตัวช่วยยูทิลิตีมีฟีเจอร์ยูทิลิตี เช่น การอ่านหรือเขียนไฟล์จากอุปกรณ์
สถาปัตยกรรม
เพื่อจัดเตรียมชุด API สำหรับสร้างการทดสอบ UI เฟรมเวิร์ก Spectatio จึงใช้ อินเทอร์เฟซและตัวช่วยเฉพาะแอป พร้อมทั้งขยายตัวช่วยมาตรฐานที่มีอยู่ และนำเข้าคลาสตัวช่วยยูทิลิตี
รูปที่ 2 แสดงสถาปัตยกรรมระดับสูงของเฟรมเวิร์ก Spectatio และ เอนทิตีทั้งหมดที่เกี่ยวข้องกับการใช้ API สำหรับการทดสอบแอป
รูปที่ 2 สถาปัตยกรรมระดับสูงของเฟรมเวิร์ก Spectatio
อินเทอร์เฟซแอปผู้ช่วยมีพิมพ์เขียวสำหรับการติดตั้งใช้งาน
แอปผู้ช่วย ซึ่งประกอบด้วยฟังก์ชันตัวช่วยต่างๆ ที่จำเป็น
สำหรับการทดสอบแอป แอปแต่ละแอปมีอินเทอร์เฟซของตัวเอง เช่น IAutoSettingHelper
และ IAutoDialHelper
ดูข้อมูลเพิ่มเติมและรายการฟังก์ชันอินเทอร์เฟซได้ที่ฟังก์ชันอินเทอร์เฟซตัวช่วยแอปใน AOSP
คลาสตัวช่วยมาตรฐานประกอบด้วยแอตทริบิวต์และฟังก์ชันมาตรฐานที่
จำเป็นสำหรับการตั้งค่าอุปกรณ์ แต่ไม่ได้เจาะจงสำหรับแอปใดแอปหนึ่ง เช่น pressHome
และ scroll คลาสผู้ช่วยมาตรฐานกำหนดไว้ใน AbstractAutoStandardAppHelper.java
เฟรมเวิร์กใช้คลาสตัวช่วยยูทิลิตี ตัวอย่างเช่น AutoJsonUtility.java เป็น
คลาสยูทิลิตีที่โหลดไฟล์การกำหนดค่า JSON ของอุปกรณ์ที่ระบุและอัปเดต
การกำหนดค่าเฟรมเวิร์กที่รันไทม์
โมดูลการติดตั้งใช้งานตัวช่วยแอปเป็นหัวใจสำคัญของเฟรมเวิร์ก Spectatio
ซึ่งมีการติดตั้งใช้งานสำหรับฟังก์ชันผู้ช่วยที่กำหนดไว้ใน
อินเทอร์เฟซผู้ช่วยของแอป ซึ่งจำเป็นสำหรับการทดสอบแอปใน
อุปกรณ์ยานยนต์ แต่ละแอปมีการติดตั้งใช้งานของตัวเอง เช่น SettingHelperImpl
และ
DialHelperImpl
ซึ่งใช้โดย
การทดสอบยานยนต์เพื่อทดสอบแอป ดูข้อมูลเพิ่มเติมและรายการการติดตั้งใช้งานได้ที่ฟังก์ชันการติดตั้งใช้งานตัวช่วยแอป
ใน AOSP
การทดสอบยานยนต์
ใช้ฟังก์ชันการติดตั้งใช้งานตัวช่วยแอปเพื่อทดสอบการดำเนินการต่างๆ
ที่เกี่ยวข้องกับแอป ใช้คลาส HelperAccessor
เพื่อเข้าถึงฟังก์ชันการติดตั้งใช้งานตัวช่วยแอป
โค้ดต่อไปนี้แสดงการตั้งค่า การล้างข้อมูล และการดำเนินการทดสอบยานยนต์ตัวอย่าง
@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());
}
}
การปรับแต่ง
เฟรมเวิร์ก Spectatio ไม่ขึ้นอยู่กับ UI ของอุปกรณ์ จึงปรับขนาดได้สำหรับ
อุปกรณ์ทดสอบที่มี UI และฮาร์ดแวร์ที่หลากหลาย Spectatio ใช้การกำหนดค่าอุปกรณ์เริ่มต้นตามอุปกรณ์อ้างอิงเพื่อให้มีความสามารถในการปรับขนาดนี้
เฟรมเวิร์กใช้ไฟล์การกำหนดค่า JSON ที่รันไทม์เพื่อตั้งค่าการเปลี่ยนแปลง UI ที่ต้องการสำหรับอุปกรณ์ เพื่อรองรับการกำหนดค่าอุปกรณ์ที่ไม่ใช่ค่าเริ่มต้น
ไฟล์การกำหนดค่า JSON รองรับองค์ประกอบ UI เช่น TEXT, DESCRIPTION และ RESOURCE_ID รวมถึงการตั้งค่า path และต้องมีเฉพาะข้อมูลเกี่ยวกับการเปลี่ยนแปลง UI สำหรับ DUT องค์ประกอบ UI ที่เหลือจะใช้ค่าการกำหนดค่าเริ่มต้นที่ระบุไว้ในเฟรมเวิร์ก
การกำหนดค่าอุปกรณ์เริ่มต้น
ไฟล์การกำหนดค่า JSON ตัวอย่างต่อไปนี้แสดงการกำหนดค่าอุปกรณ์ที่มีอยู่ และค่าเริ่มต้น
คลิกที่นี่เพื่อแสดงตัวอย่างไฟล์การกำหนดค่า 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" } } } }
การกำหนดค่าอุปกรณ์ทางเลือก
ตัวอย่างโค้ดต่อไปนี้แสดงตัวอย่างไฟล์การกำหนดค่า JSON ที่การตั้งค่าเริ่มต้นถูกลบล้างโดยการตั้งค่าใน DUT ในตัวอย่างนี้
การตั้งค่าอินเทอร์เน็ตมีชื่อว่าเครือข่ายและอินเทอร์เน็ตในอุปกรณ์อ้างอิง และการเชื่อมต่อใน DUT
การตั้งค่าวันที่และเวลาจะอยู่ที่การตั้งค่า > วันที่และเวลาสำหรับ อุปกรณ์อ้างอิง และอยู่ที่การตั้งค่า > ระบบ > วันที่และเวลาสำหรับ 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"
},
....
}
เมื่อไฟล์การกำหนดค่า JSON พร้อมแล้ว ระบบจะระบุไฟล์ดังกล่าวในขณะรันไทม์ตามที่แสดงในโค้ดบล็อกต่อไปนี้
# Push The JSON configuration file to the device
adb -s DEVICE-SERIAL push PATH-OF-JSON-FILE /data/local/tmp/runtimeSpectatioConfig.json
ในคำสั่งนี้
DEVICE-SERIAL: รหัสซีเรียลของ DUT พารามิเตอร์นี้ไม่จำเป็นหากมีอุปกรณ์เพียงเครื่องเดียวที่เชื่อมต่อกับโฮสต์
PATH-TO-JSON-FILE: เส้นทางของไฟล์ JSON ในเครื่องโฮสต์
รูปแบบการกำหนดค่า
การกำหนดค่ามีออบเจ็กต์ระดับบนสุด 5 รายการ โดยมีคีย์และค่าต่อไปนี้
| วัตถุ | คำอธิบาย |
|---|---|
PACKAGES |
ออบเจ็กต์ที่อธิบายแพ็กเกจหลักสำหรับแอปต่างๆ ซึ่งใช้เพื่อ กำหนดเวลาที่แอปนั้นอยู่เบื้องหน้า |
ACTIONS |
ออบเจ็กต์ที่ระบุประเภทการดำเนินการและพารามิเตอร์สำหรับการดำเนินการต่างๆ เช่น จะใช้ปุ่มหรือท่าทางสัมผัสเพื่อเลื่อน |
COMMANDS |
ออบเจ็กต์ที่ระบุคำสั่งที่ดำเนินการต่างๆ |
UI_ELEMENTS |
ออบเจ็กต์ที่ใช้สร้าง `BySelectors` ของ UI Automator ซึ่งเลือกองค์ประกอบ UI (อธิบายโดยละเอียดด้านล่าง) |
WORKFLOWS |
ลำดับการดำเนินการที่ทำภารกิจระดับสูงให้สำเร็จ (อธิบายโดยละเอียดด้านล่าง) |
องค์ประกอบ UI
องค์ประกอบ UI แต่ละรายการมี TYPE ซึ่งระบุสิ่งที่ UI Automator จะค้นหาเพื่อระบุองค์ประกอบ (เช่น รหัสทรัพยากร ข้อความ และคำอธิบาย) และค่าการกำหนดค่าที่เชื่อมโยงกับประเภทนั้น โดยทั่วไป เมื่อใดก็ตามที่โปรแกรมช่วยเหลือ
ระบุองค์ประกอบบนหน้าจอโดยใช้การกำหนดค่านี้ โปรแกรมจะได้รับองค์ประกอบ
เพียง 1 รายการเท่านั้น หากมีองค์ประกอบหลายรายการที่ตรงกับการกำหนดค่า ระบบจะใช้องค์ประกอบใดก็ได้ในการทดสอบ
ดังนั้น การกำหนดค่าจึงควรเขียน (โดยทั่วไป) ให้เฉพาะเจาะจงมากพอที่จะจำกัดให้เหลือองค์ประกอบเดียวในบริบทที่เกี่ยวข้อง
ข้อความ
ซึ่งเป็นประเภทองค์ประกอบ UI ที่ง่ายที่สุด องค์ประกอบ UI จะระบุด้วยข้อความ และต้องตรงกันทุกประการ
"CALL_HISTORY_MENU": {
"TYPE": "TEXT",
"VALUE": "Recents"
}
TEXT_CONTAINS
เหมือนกับ TEXT ยกเว้นว่า VALUE ที่ระบุจะต้องปรากฏที่ใดที่หนึ่งในข้อความขององค์ประกอบที่จะจับคู่
"PRIVACY_CALENDAR": {
"TYPE": "TEXT_CONTAINS",
"VALUE": "Calendar"
}
คำอธิบาย
ระบุองค์ประกอบตามแอตทริบิวต์คำอธิบายเนื้อหา ซึ่งต้องตรงกันทุกประการ
"APP_GRID_SCROLL_BACKWARD_BUTTON": {
"TYPE": "DESCRIPTION",
"VALUE": "Scroll up"
}
RESOURCE_ID
ระบุองค์ประกอบตามรหัสทรัพยากร และอาจตรวจสอบแพ็กเกจ
คอมโพเนนต์ของรหัสนั้นด้วย PACKAGE คีย์เป็นตัวเลือก หากไม่ระบุ ระบบจะจับคู่แพ็กเกจใดก็ได้
และจะพิจารณาเฉพาะส่วนของรหัสที่อยู่หลัง :id/
"APP_LIST_SCROLL_ELEMENT": {
"TYPE": "RESOURCE_ID",
"VALUE": "apps_grid",
"PACKAGE": "com.android.car.carlauncher"
}
คลิกได้ เลื่อนได้
ระบุองค์ประกอบโดยพิจารณาว่าคลิกได้หรือเลื่อนได้หรือไม่
องค์ประกอบเหล่านี้เป็นประเภทองค์ประกอบที่กว้างมาก และโดยทั่วไปควรใช้ในMULTIPLE
เพื่อช่วยจำกัดประเภทองค์ประกอบอื่น คีย์ FLAG เป็นค่าที่ไม่บังคับ
และมีค่าเริ่มต้นเป็น true
"SAMPLE_ELEMENT": {
"TYPE": "CLICKABLE",
"FLAG": false
}
ชั้นเรียน
ระบุองค์ประกอบตามคลาส
"SECURITY_SETTINGS_ENTER_PASSWORD": {
"TYPE": "CLASS",
"VALUE": "android.widget.EditText"
}
HAS_ANCESTOR
ระบุองค์ประกอบโดยค้นหาลำดับชั้นของวิดเจ็ตที่บรรพบุรุษ คีย์
ANCESTORมีออบเจ็กต์ที่ระบุระดับบน คีย์ DEPTH
ระบุว่าควรดูที่ระดับใดในลำดับชั้น DEPTH เป็นค่าที่ไม่บังคับและมีค่าเริ่มต้นเป็น 1
"SAMPLE_ELEMENT": {
"TYPE": "HAS_ANCESTOR",
"DEPTH": 2,
"ANCESTOR": {
"TYPE": "CLASS",
"VALUE": "android.view.ViewGroup"
}
}
HAS_DESCENDANT
ระบุองค์ประกอบโดยดูที่ลำดับชั้นขององค์ประกอบย่อย คีย์
DESCENDANT มีออบเจ็กต์ที่ระบุองค์ประกอบย่อยที่จะค้นหา คีย์
DEPTH จะระบุว่าควรค้นหาในลำดับชั้นใด DEPTH เป็นตัวเลือกและมีค่าเริ่มต้นเป็น 1
"SAMPLE_ELEMENT": {
"TYPE": "HAS_DESCENDANT",
"DEPTH": 2,
"DESCENDANT": {
"TYPE": "CLASS",
"VALUE": "android.view.ViewGroup"
}
}
MULTIPLE
ระบุองค์ประกอบตามเงื่อนไขหลายอย่างพร้อมกัน ซึ่งทั้งหมด ต้องเป็นไปตามข้อกำหนด
"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"
}
}
]
}
ในตัวอย่างนี้ การกำหนดค่าจะระบุ RelativeLayout ที่มี
องค์ประกอบย่อยที่ระดับความลึก 2 ซึ่งมีข้อความ Permission manager
Workflows
เวิร์กโฟลว์แสดงลําดับการกระทําที่ใช้เพื่อทํา งานหนึ่งๆ ให้สําเร็จ ซึ่งอาจแตกต่างกันมากจากอุปกรณ์ประเภทหนึ่งไปยังอีกประเภทหนึ่ง และมีความ ยืดหยุ่นมากกว่าในการแสดงในการกําหนดค่ามากกว่าในโค้ด
"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"
}
}
}
]
}
แต่ละเวิร์กโฟลว์คือคู่คีย์-ค่า โดยคีย์คือชื่อของเวิร์กโฟลว์ และ
ค่าคืออาร์เรย์ของการดำเนินการที่จะทำ โดยแต่ละการดำเนินการจะมี NAME, TYPE,
(โดยปกติ) CONFIG และ (บางครั้ง) SWIPE_CONFIG หรือ SCROLL_CONFIG สำหรับ TYPE ส่วนใหญ่ CONFIG คือออบเจ็กต์ที่มีคีย์ UI_ELEMENT ซึ่งมีค่าในรูปแบบเดียวกับรายการองค์ประกอบ UI (ดูด้านบน) โดยมีประเภทดังนี้
| 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 |
สำหรับ TYPE อื่นๆ รายละเอียดการกำหนดค่ามีดังนี้
| วัตถุ | คำอธิบาย |
|---|---|
COMMAND |
ออบเจ็กต์ที่มีค่า TEXT ซึ่งมีคำสั่งที่จะดำเนินการ |
HAS_PACKAGE_IN_FOREGROUND |
ออบเจ็กต์ที่มีค่า TEXT ซึ่งมีแพ็กเกจ |
SWIPE |
ละเว้น CONFIG key สำหรับSWIPEการดำเนินการ การตั้งค่านี้
ใช้ได้เฉพาะ SWIPE_CONFIG |
WAIT_MS |
ออบเจ็กต์ที่มีค่า TEXT ซึ่งมีจำนวนมิลลิวินาทีที่ต้องรอ
|
การดำเนินการที่เกี่ยวข้องกับการเลื่อนและการปัดต้องมีการกำหนดค่าเพิ่มเติมดังนี้
SCROLL_CONFIG
| วัตถุ | คำอธิบาย |
|---|---|
SCROLL_ACTION |
USE_GESTURE หรือ USE_BUTTON ก็ได้ |
SCROLL_DIRECTION |
HORIZONTAL หรือ VERTICAL ก็ได้ |
SCROLL_ELEMENT |
ออบเจ็กต์ที่ระบุคอนเทนเนอร์ที่จะเลื่อน โดยใช้รูปแบบเดียวกับการกำหนดค่าองค์ประกอบ UI (ดูด้านบน) |
SCROLL_FORWARD, SCROLL_BACKWARD |
ปุ่มเลื่อนไปข้างหน้าและข้างหลัง (ต้องระบุเมื่อ SCROLL_ACTION เป็น USE_BUTTON) |
SCROLL_MARGIN |
หาก SCROLL_ACTION เป็น USE_GESTURE ระยะห่าง
จากขอบของคอนเทนเนอร์เพื่อเริ่มและหยุดการลากที่จะใช้
เพื่อเลื่อน (ไม่บังคับ ค่าเริ่มต้น = 10) |
SCROLL_WAIT_TIME |
หาก SCROLL_ACTION เป็น USE_GESTURE เวลาเป็นมิลลิวินาทีที่จะรอระหว่างท่าทางการเลื่อนเมื่อค้นหาออบเจ็กต์ที่จะคลิก
(ไม่บังคับ ค่าเริ่มต้น = 1) |
SWIPE_CONFIG
| วัตถุ | คำอธิบาย |
|---|---|
SWIPE_DIRECTION |
TOP_TO_BOTTOM, BOTTOM_TO_TOP,
LEFT_TO_RIGHT หรือ RIGHT_TO_LEFT |
SWIPE_FRACTION |
อย่างใดอย่างหนึ่งต่อไปนี้
|
NUMBER_OF_STEPS |
จำนวนขั้นตอนที่จะใช้ในการปัด โปรดอ่าน
segmentSteps
|
สร้างและดำเนินการ
ระบบจะสร้างเฟรมเวิร์ก Spectatio โดยอัตโนมัติเป็นส่วนหนึ่งของ APK ทดสอบ หากต้องการสร้าง APK ทดสอบ โค้ดเบส AOSP ต้องอยู่ในเวิร์กสเตชันภายใน หลังจากสร้าง APK ทดสอบแล้ว ผู้ใช้ต้องติดตั้ง APK ในอุปกรณ์และเรียกใช้ การทดสอบ
ตัวอย่างโค้ดต่อไปนี้แสดงการสร้าง การติดตั้ง และการเรียกใช้ APK สำหรับทดสอบ
# Build Test APK make TEST-APK-NAME# Install Test APK adb -s DEVICE-SERIAL install -r PATH-FOR-BUILT-TEST-APK# Execute Test with the JSON file adb -s DEVICE-SERIAL shell am instrument -w -r -e debug false -e config-file-path /data/local/tmp/jsonFile.json -e class TEST-PACKAGE.TEST-CLASSNAME TEST-PACKAGE/androidx.test.runner.AndroidJUnitRunner
ในคำสั่งเหล่านี้
TEST-APK-NAME: ชื่อของแอปที่จะทดสอบ เช่น ตั้งค่า TEST-APK-NAMEเป็น
AndroidAutomotiveSettingsTestsเพื่อทดสอบการตั้งค่า Wi-Fi ตามที่ระบุไว้ในไฟล์Android.bpคุณดูชื่อของ APK ได้ในไฟล์Android.bpที่เกี่ยวข้องสำหรับการทดสอบยานยนต์DEVICE-SERIAL: รหัสซีเรียลของ DUT พารามิเตอร์นี้ไม่จำเป็นหากมีอุปกรณ์เพียงเครื่องเดียวที่เชื่อมต่อกับโฮสต์
config-file-path: พารามิเตอร์ที่ไม่บังคับซึ่งจำเป็นต่อการระบุ การกำหนดค่า UI ของอุปกรณ์ที่ไม่ใช่ค่าเริ่มต้นตามที่ระบุไว้ในไฟล์การกำหนดค่า JSON เท่านั้น หากไม่ได้ระบุไว้ เฟรมเวิร์กจะใช้ค่าเริ่มต้นในการเรียกใช้การทดสอบPATH-FOR-BUILT-TEST-APK: เส้นทางที่สร้าง APK ทดสอบ เมื่อเรียกใช้คำสั่ง
makeTEST-PACKAGE: ชื่อแพ็กเกจทดสอบ
TEST-CLASSNAME: ชื่อของชั้นเรียนทดสอบ เช่น สำหรับการทดสอบการตั้งค่า Wi-Fi แพ็กเกจการทดสอบคือ
android.platform.testsและชื่อคลาสการทดสอบคือWifiSettingTest
คลังตัวอย่างยานยนต์
Automotive Snippet Library คือชุดไลบรารีการทดสอบ Android สำหรับ โครงการโอเพนซอร์ส Android (AOSP) ซึ่งออกแบบมาเพื่อโต้ตอบกับแอปและบริการ ยานยนต์ โดยใช้ประโยชน์จาก Spectatio ด้วยกลไกที่สะดวก สำหรับการเรียกกระบวนการระยะไกล (RPC) จากเครื่องโฮสต์ (ทดสอบ) ไปยังอุปกรณ์ที่ใช้ ระบบปฏิบัติการ Android
เริ่มต้นใช้งาน
โปรดอ่านส่วนต่อไปนี้ก่อนเริ่มต้น
สิ่งที่ต้องมีก่อน
- ติดตั้ง Python 3.x ในเครื่องโฮสต์
- ตั้งค่าสภาพแวดล้อม AOSP ด้วยเครื่องมือบิลด์ที่จำเป็น
- อุปกรณ์ Android Automotive (โปรแกรมจำลองหรืออุปกรณ์จริง) ที่มีสิทธิ์เข้าถึง adb
การรวบรวม
หากต้องการรวบรวมข้อมูลโค้ดต่างๆ ที่ไลบรารีข้อมูลโค้ดยานยนต์มีให้ คุณ
สามารถใช้ไฟล์ android.bp ที่ให้มาได้ คำสั่งต่อไปนี้ในส่วนก่อนหน้า
เพื่อคอมไพล์ APK
การทำให้ใช้งานได้
หลังจากคอมไพล์ไลบรารีโค้ด Snippet เรียบร้อยแล้ว ให้ติดตั้ง APK ที่ได้ลงใน
อุปกรณ์เป้าหมายโดยใช้คำสั่ง adb install ที่กล่าวถึงในส่วนก่อนหน้า
ทำการทดสอบ
ไลบรารีโค้ดจะแสดงเมธอด RPC หลายรายการเพื่อโต้ตอบกับระบบยานยนต์
เรียกใช้เมธอดเหล่านี้ผ่านเฟรมเวิร์ก Mobly จากเครื่องโฮสต์ได้
หากตั้งค่าสภาพแวดล้อมการทดสอบ Mobly แล้ว คุณจะใช้สคริปต์ snippet_shell.py เพื่อเปิดเชลล์ Python แบบอินเทอร์แอกทีฟได้ ซึ่งคุณจะเรียกใช้เมธอด RPC ในอุปกรณ์ด้วยตนเองได้ ตัวอย่างการเรียกใช้
python3 snippet_shell.py com.google.android.mobly.snippet.bundled -s <serial>
แทนที่ <serial> ด้วยหมายเลขซีเรียลของอุปกรณ์ ซึ่งคุณจะดูได้ด้วย
adb devices หากเชื่อมต่ออุปกรณ์หลายเครื่อง
ไลบรารีที่รวมไว้
คลังข้อมูลโค้ดยานยนต์มีคลังข้อมูลโค้ดและตัวช่วยต่อไปนี้
AutomotiveSnippet: มี API ที่เกี่ยวข้องกับการทำงานของยานพาหนะ เช่น การโทร การควบคุมระดับเสียง ปุ่มฮาร์ดคีย์ของยานพาหนะ และการโต้ตอบกับศูนย์สื่อ
PhoneSnippet: มี API ที่เกี่ยวข้องกับโทรศัพท์ ซึ่งรวมถึงการจัดการการโทร การเรียกดูรายชื่อติดต่อ และการดำเนินการ SMS
ข้อมูลโค้ดยานยนต์และ PhoneSnippet ใช้ตรรกะร่วมกันบางอย่าง
โดยเฉพาะอย่างยิ่ง คุณสามารถแทรกแซงการเรียก RCP ที่เกี่ยวข้องกับบลูทูธเพื่อจับคู่อุปกรณ์ยานยนต์
และโทรศัพท์ bt_discovery_test นี้แสดงวิธีการ
- TEST-CLASSNAME: ชื่อของชั้นเรียนทดสอบ เช่น สำหรับการทดสอบการตั้งค่า Wi-Fi
แพ็กเกจการทดสอบคือ
android.platform.testsและชื่อคลาสการทดสอบคือWifiSettingTest