Spectatio เป็นเฟรมเวิร์กการทดสอบแบบโอเพนซอร์สที่พัฒนาขึ้นสำหรับการทดสอบ Android Automotive OS (AAOS) ในอุปกรณ์จริงและอุปกรณ์เสมือน Spectatio มี API สำหรับ ทดสอบแอปในอุปกรณ์ยานยนต์ และเป็นโซลูชันที่ขยายและรองรับการปรับขนาด ใช้เพื่อยืนยันความสามารถและประสิทธิภาพของ AAOS และแอปของบริษัท
ดีไซน์เหนือระดับ
เฟรมเวิร์ก Spectatio สามารถปรับขยายได้และขยายได้สำหรับ UI ของ AAOS ที่หลากหลาย การนำไปใช้งานจริง ใช้สำหรับการทดสอบความสามารถและประสิทธิภาพของ AAOS เกี่ยวกับฮาร์ดแวร์ของอุปกรณ์ โปรแกรมจำลอง และสภาพแวดล้อมเสมือนจริง
รูปภาพต่อไปนี้อธิบายการออกแบบระดับสูงของเฟรมเวิร์ก Spectatio
รูปที่ 1 การออกแบบระดับสูงของกรอบการคาดการณ์
เฟรมเวิร์ก Spectatio จะสร้างขึ้นจาก UI Automator และมีชุด API เพื่อสร้างการทดสอบ UI ที่โต้ตอบกับแอปของผู้ใช้และแอประบบใน AAOS สำหรับรถหรือยานพาหนะ ใช้ API ที่เฟรมเวิร์ก Spectatio มีให้สำหรับการทดสอบ ซึ่งทำให้ การทดสอบเหล่านี้โดยไม่ขึ้นกับอุปกรณ์ที่อยู่ภายใต้การทดสอบ (DUT) และสามารถรองรับการทดสอบได้ อุปกรณ์ที่หลากหลาย หากรองรับ
รูปที่ 1 แสดงให้เห็นว่าเฟรมเวิร์ก Spectatio ได้รับการแยกเป็นโมดูลตามการอ้างอิง แอปต่างๆ เช่น Dialer, Medicenter และ Settings โดยใช้เฉพาะแอป อินเทอร์เฟซและตัวช่วยต่างๆ ซึ่งทำให้แอปใหม่ๆ สามารถขยายการใช้งานได้อย่างง่ายดาย ประสบการณ์ ของเฟรมเวิร์กจะนำมาตรฐานและชั้นเรียนตัวช่วยด้านยูทิลิตีทั่วไปมาใช้ใหม่ ชั้นเรียนตัวช่วยมาตรฐาน เป็นคลาสระดับบนสุดสำหรับฟังก์ชันตัวช่วยสำหรับแอปทั้งหมด ฟังก์ชันมาตรฐานที่เจาะจงอุปกรณ์หรือมีผลใช้งานในแอปต่างๆ คลาสตัวช่วยยูทิลิตีจะมียูทิลิตี้ต่างๆ เช่น อ่านหรือเขียนไฟล์จากอุปกรณ์
สถาปัตยกรรม
เฟรมเวิร์ก Spectatio ใช้ในการจัดหาชุด API สำหรับสร้างการทดสอบ UI อินเทอร์เฟซและตัวช่วยเหลือสำหรับแอปโดยเฉพาะ ไปพร้อมๆ กับขยายผู้ช่วยมาตรฐานที่มีอยู่ และนำเข้าคลาสตัวช่วยยูทิลิตี
รูปที่ 2 แสดงสถาปัตยกรรมระดับสูงของเฟรมเวิร์ก Spectatio และ เอนทิตีทั้งหมดที่เกี่ยวข้องกับการใช้ API สำหรับการทดสอบแอป
รูปที่ 2 สถาปัตยกรรมระดับสูงของเฟรมเวิร์กข้อมูลจำเพาะ
อินเทอร์เฟซตัวช่วยแอปแสดงพิมพ์เขียวสำหรับการติดตั้งใช้งาน
ผู้ช่วยแอป ซึ่งประกอบด้วยฟังก์ชันตัวช่วยต่างๆ ที่จำเป็นต้องใช้
เพื่อทดสอบแอป แต่ละแอปมีอินเทอร์เฟซของตัวเอง เช่น 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 และฮาร์ดแวร์ที่หลากหลาย เพื่อให้สามารถปรับขนาดได้
ข้อมูลจำเพาะใช้การกำหนดค่าอุปกรณ์เริ่มต้นตามอุปกรณ์อ้างอิง ถึง
รองรับการกำหนดค่าอุปกรณ์ที่ไม่ใช่ค่าเริ่มต้น โดยเฟรมเวิร์กจะใช้ 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 อัตโนมัติที่เลือก UI องค์ประกอบ (อธิบายไว้อย่างละเอียดด้านล่าง) |
WORKFLOWS |
ลำดับการดำเนินการที่บรรลุผลสำเร็จในระดับสูง (อธิบายไว้ใน ตามรายละเอียดด้านล่าง) |
องค์ประกอบ UI
องค์ประกอบ UI แต่ละรายการจะมี TYPE
ซึ่งระบุสิ่งที่ตัวดำเนินการอัตโนมัติของ UI จะมองหา
ระบุองค์ประกอบ (เช่น รหัสทรัพยากร ข้อความ และคำอธิบาย) และ
การกำหนดค่าที่เชื่อมโยงกับประเภทนั้นๆ โดยทั่วไป เมื่อใดก็ตามที่ผู้ช่วย
ระบุองค์ประกอบบนหน้าจอโดยใช้การกำหนดค่านี้
1 องค์ประกอบ หากมีหลายองค์ประกอบตรงกับการกำหนดค่า ระบบจะกำหนดค่า
ที่ใช้ในการทดสอบ ดังนั้นจึงควรเขียนการกำหนดค่า (โดยทั่วไป)
ให้แคบลงเหลือแค่องค์ประกอบเดียวในบริบทที่เกี่ยวข้อง
ข้อความ
นี่เป็นองค์ประกอบ UI ประเภทพื้นฐานที่สุด องค์ประกอบ UI จะได้รับการระบุด้วยข้อความ และต้องมีการทำงานแบบตรงทั้งหมด
"CALL_HISTORY_MENU": {
"TYPE": "TEXT",
"VALUE": "Recents"
}
ข้อความมี
เหมือนกับ TEXT
เว้นแต่ว่า VALUE
ที่ระบุจะต้องปรากฏที่ใดที่หนึ่งเท่านั้น
ข้อความขององค์ประกอบที่จะจับคู่
"PRIVACY_CALENDAR": {
"TYPE": "TEXT_CONTAINS",
"VALUE": "Calendar"
}
คำอธิบาย
ระบุองค์ประกอบตามแอตทริบิวต์รายละเอียดเนื้อหา โดยต้องใส่ ที่ตรงกัน
"APP_GRID_SCROLL_BACKWARD_BUTTON": {
"TYPE": "DESCRIPTION",
"VALUE": "Scroll up"
}
รหัสทรัพยากร
ระบุองค์ประกอบตามรหัสทรัพยากร หรือจะตรวจสอบแพ็กเกจด้วยก็ได้
ของรหัสนั้นๆ คีย์ 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"
}
}
หลายรายการ
ระบุธาตุตามเงื่อนไขหลายข้อพร้อมกัน ซึ่งทุกข้อ ให้ตรงตามข้อกำหนด
"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 (ดูด้านบน) TYPE เหล่านั้นคือ
PRESS Llong_PRESS คลิก LONG_คลิก CLICK_IF_EXIST |
HAS_UI_ELEMENT_IN_FOREGROUND SCROLL_TO_FIND_AND_คลิก SCROLL_TO_FIND_AND_CLICK_IF_EXIST SWIPE_TO_FIND_AND_คลิก 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_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
วัตถุ | คำอธิบาย |
---|---|
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 การทดสอบ เมื่อมีการเรียกใช้คำสั่ง
make
TEST-PACKAGE: ชื่อแพ็กเกจทดสอบ
TEST-CLASSNAME: ชื่อชั้นเรียนทดสอบ ตัวอย่างเช่น สำหรับ การทดสอบการตั้งค่า Wi-Fi แพ็กเกจทดสอบคือ
android.platform.tests
และ ชื่อคลาสการทดสอบคือWifiSettingTest
ไลบรารีข้อมูลโค้ดยานยนต์
ไลบรารีข้อมูลโค้ด Automotive เป็นชุดไลบรารี Android Test สําหรับ โครงการโอเพนซอร์ส Android (AOSP) ที่ออกแบบมาเพื่อโต้ตอบกับยานยนต์ แอปและบริการ ใช้ประโยชน์จาก Spectatio ที่มีกลไกการทำงานที่สะดวก สำหรับการเรียกใช้โพรซีเยอร์ระยะไกล (RPC) จากเครื่องโฮสต์ (ทดสอบ) ไปยัง อุปกรณ์ที่ใช้ระบบ Android
เริ่มต้นใช้งาน
โปรดอ่านหัวข้อเหล่านี้ก่อนเริ่ม
สิ่งที่ต้องมีก่อน
- ติดตั้ง Python 3.x ในเครื่องโฮสต์แล้ว
- การตั้งค่าสภาพแวดล้อม AOSP ด้วยเครื่องมือบิลด์ที่จำเป็น
- อุปกรณ์ Android Automotive (จําลองหรืออุปกรณ์จริง) ที่มีสิทธิ์เข้าถึง adb
การรวบรวม
ในการรวบรวมข้อมูลโค้ดต่างๆ ที่ได้จากไลบรารีข้อมูลโค้ด Automotive คุณ
ใช้ไฟล์ android.bp
ที่ให้ไว้ได้ ทำตามคำสั่งก่อนหน้านี้
เพื่อคอมไพล์ APK
การทำให้ใช้งานได้
หลังจากคอมไพล์ไลบรารีข้อมูลโค้ดสำเร็จแล้ว ให้นำ APK ที่ได้มาใช้งานได้เพื่อ
อุปกรณ์เป้าหมายโดยใช้คำสั่ง adb install
ที่กล่าวถึงไปก่อนหน้านี้
ทำการทดสอบ
ไลบรารีข้อมูลโค้ดแสดงวิธี RPC หลายวิธีในการโต้ตอบกับยานยนต์
ระบบ คุณจะเรียกใช้วิธีการเหล่านี้ได้ผ่านเฟรมเวิร์ก Mobly จากโฮสต์
อุปกรณ์ สมมติว่าคุณตั้งค่าสภาพแวดล้อมการทดสอบ Mobly แล้ว คุณสามารถใช้
snippet_shell.py
เพื่อเปิด Shell ของ Python แบบอินเทอร์แอกทีฟ ซึ่งคุณสามารถ
เรียกใช้เมธอด RPC ในอุปกรณ์ด้วยตนเอง ตัวอย่างการเรียกใช้
python3 snippet_shell.py com.google.android.mobly.snippet.bundled -s <serial>
แทนที่ <serial>
ด้วยหมายเลขซีเรียลของอุปกรณ์ซึ่งคุณจะดูได้
อุปกรณ์ adb หากมีการเชื่อมต่อหลายอุปกรณ์
คลังที่รวม
ไลบรารีข้อมูลโค้ด Automotive ประกอบด้วยไลบรารีข้อมูลโค้ดต่อไปนี้และ ผู้ช่วย:
AutomotiveSnippet: ระบุ API ที่เกี่ยวข้องกับการปฏิบัติงานของยานพาหนะ เช่น การโทร การควบคุมระดับเสียง แป้นกดของยานพาหนะ และการโต้ตอบในศูนย์สื่อ
PhoneSnippet: มอบ API ที่เกี่ยวข้องกับโทรศัพท์ รวมถึงการจัดการสายเรียกเข้า การเรียกดูรายชื่อติดต่อ และการดำเนินการ SMS
Automotive snippet และ Phonesnippet ใช้ตรรกะทั่วไปบางอย่าง
กล่าวอย่างเจาะจงคือ คุณสามารถบุกรุกการเรียกใช้ RCP ที่เกี่ยวข้องกับบลูทูธเพื่อจับคู่รถยนต์
และอุปกรณ์โทรศัพท์ bt_discovery_test
นี้จะแสดงวิธีการ
- TEST-CLASSNAME: ชื่อชั้นเรียนทดสอบ ตัวอย่างเช่น สำหรับ
การทดสอบการตั้งค่า Wi-Fi
แพ็กเกจการทดสอบคือ
android.platform.tests
และชื่อคลาสการทดสอบคือWifiSettingTest