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 และการตั้งค่า โดยใช้อินเทอร์เฟซและตัวช่วยเฉพาะแอป ซึ่งทำให้ขยายการทำงานไปยังแอปใหม่ๆ ได้อย่างง่ายดาย เฟรมเวิร์ก 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
// 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 |
ออบเจ็กต์ที่ใช้สร้าง UI Automator "BySelectors" ที่เลือกองค์ประกอบ UI (อธิบายไว้อย่างละเอียดด้านล่าง) |
WORKFLOWS |
ลำดับการดำเนินการที่ทำงานระดับสูงให้เสร็จสมบูรณ์ (อธิบายไว้อย่างละเอียดด้านล่าง) |
องค์ประกอบ UI
องค์ประกอบ UI แต่ละรายการมี TYPE
ซึ่งระบุสิ่งที่ UI Automator จะมองหาเพื่อระบุองค์ประกอบ (เช่น รหัสทรัพยากร ข้อความ และคำอธิบาย) และค่าการกำหนดค่าที่เชื่อมโยงกับประเภทนั้น โดยทั่วไป เมื่อใดก็ตามที่ตัวช่วยระบุองค์ประกอบบนหน้าจอโดยใช้การกำหนดค่านี้ ตัวช่วยจะพบองค์ประกอบเพียงองค์ประกอบเดียว หากองค์ประกอบหลายรายการตรงกับการกำหนดค่า ระบบจะใช้องค์ประกอบใดก็ได้ในการทดสอบ ดังนั้น (โดยทั่วไป) การกําหนดค่าควรเขียนให้เฉพาะเจาะจงมากพอที่จะจำกัดขอบเขตให้เหลือเพียงองค์ประกอบเดียวในบริบทที่เกี่ยวข้อง
ข้อความ
องค์ประกอบประเภทนี้เป็นองค์ประกอบ 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
}
CLASS
ระบุองค์ประกอบตามคลาส
"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
สําหรับประเภทส่วนใหญ่ CONFIG
จะเป็นออบเจ็กต์ที่มีคีย์ UI_ELEMENT
ซึ่งค่าอยู่ในรูปแบบเดียวกับรายการองค์ประกอบ UI (ดูด้านบน) ประเภทเหล่านั้น ได้แก่
กด กดค้าง คลิก กดค้าง คลิกหากมี |
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 |
สําหรับประเภทอื่นๆ รายละเอียดการกําหนดค่ามีดังนี้
วัตถุ | คำอธิบาย |
---|---|
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 ทดสอบเมื่อมีการเรียกใช้คำสั่ง
make
TEST-PACKAGE: ชื่อแพ็กเกจทดสอบ
TEST-CLASSNAME: ชื่อคลาสทดสอบ เช่น สำหรับการทดสอบการตั้งค่า Wi-Fi แพ็กเกจทดสอบคือ
android.platform.tests
และชื่อคลาสทดสอบคือWifiSettingTest
ไลบรารีตัวอย่างข้อมูลยานยนต์
ไลบรารีข้อมูลโค้ดของยานยนต์คือชุดไลบรารีการทดสอบ Android สำหรับโครงการโอเพนซอร์ส Android (AOSP) ที่ออกแบบมาเพื่อโต้ตอบกับแอปและบริการยานยนต์ โดยใช้ประโยชน์จาก Spectatio ด้วยกลไกที่สะดวกสําหรับการเรียกใช้กระบวนการระยะไกล (RPC) จากเครื่องโฮสต์ (ทดสอบ) ไปยังอุปกรณ์ที่ใช้ Android
เริ่มต้นใช้งาน
โปรดอ่านส่วนต่อไปนี้ก่อนเริ่มต้น
สิ่งที่ต้องมีก่อน
- ติดตั้ง Python 3.x ในเครื่องโฮสต์
- การตั้งค่าสภาพแวดล้อม AOSP ด้วยเครื่องมือสร้างที่จำเป็น
- อุปกรณ์ Android Automotive (โปรแกรมจำลองหรืออุปกรณ์จริง) ที่มีสิทธิ์เข้าถึง adb
การรวบรวม
หากต้องการคอมไพล์ข้อมูลโค้ดต่างๆ ที่ได้จากคลังข้อมูลโค้ดยานยนต์ คุณสามารถใช้ไฟล์ android.bp
ที่ให้มา คำสั่งต่อไปนี้ในส่วนก่อนหน้าเพื่อคอมไพล์ APK
การทำให้ใช้งานได้
หลังจากคอมไพล์ไลบรารีข้อมูลโค้ดเรียบร้อยแล้ว ให้ติดตั้ง 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