Spectatio เป็นเฟรมเวิร์กการทดสอบโอเพ่นซอร์สที่พัฒนาขึ้นเพื่อทดสอบ Android Automotive OS (AAOS) บนอุปกรณ์จริงและเสมือน Spectatio จัดเตรียม API สำหรับการทดสอบแอปบนอุปกรณ์ยานยนต์ และเป็นโซลูชันที่ขยายและปรับขนาดได้ ซึ่งใช้สำหรับตรวจสอบความสามารถและประสิทธิภาพของ AAOS และแอปต่างๆ
การออกแบบระดับสูง
เฟรมเวิร์ก Spectatio สามารถปรับเปลี่ยนและขยายได้สำหรับการใช้งาน AAOS UI ต่างๆ ใช้สำหรับทดสอบความสามารถและประสิทธิภาพของ 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
Automotive Tests ใช้ฟังก์ชันการใช้งานตัวช่วยแอปเพื่อทดสอบการทำงานต่างๆ ที่เกี่ยวข้องกับแอป ใช้คลาส 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 : Serial ID ของ DUT ไม่จำเป็นต้องใช้พารามิเตอร์นี้หากมีอุปกรณ์เพียงเครื่องเดียวเชื่อมต่อกับโฮสต์
PATH-TO-JSON-FILE : เส้นทางของไฟล์ JSON บนเครื่องโฮสต์
รูปแบบการกำหนดค่า
มีออบเจ็กต์ระดับบนสุดห้าออบเจ็กต์ในการกำหนดค่า โดยมีคีย์และค่าต่อไปนี้:
วัตถุ | คำอธิบาย |
---|---|
PACKAGES | ออบเจ็กต์ที่อธิบายแพ็กเกจหลักสำหรับแอปต่างๆ ซึ่งใช้เพื่อระบุว่าแอปนั้นอยู่เบื้องหน้าเมื่อใด |
ACTIONS | ออบเจ็กต์ที่ระบุประเภทการดำเนินการและพารามิเตอร์สำหรับการดำเนินการต่างๆ เช่น จะใช้ปุ่มหรือท่าทางในการเลื่อน |
COMMANDS | อ็อบเจ็กต์ที่ระบุคำสั่งที่ดำเนินการต่างๆ |
UI_ELEMENTS | ออบเจ็กต์ที่ใช้สร้าง UI Automator `BySelectors` ที่เลือกองค์ประกอบ UI (อธิบายในรายละเอียดด้านล่าง) |
WORKFLOWS | ลำดับของการกระทำที่ทำให้งานระดับสูงสำเร็จ (อธิบายรายละเอียดด้านล่าง) |
องค์ประกอบ UI
แต่ละองค์ประกอบ UI มี TYPE
ซึ่งระบุว่า UI Automator ใดที่จะค้นหาเพื่อระบุองค์ประกอบ (เช่น ID ทรัพยากร ข้อความ และคำอธิบาย) และค่าการกำหนดค่าที่เกี่ยวข้องกับประเภทนั้น โดยทั่วไป เมื่อใดก็ตามที่ผู้ช่วยเหลือระบุองค์ประกอบบนหน้าจอโดยใช้การกำหนดค่านี้ ผู้ช่วยเหลือจะได้รับองค์ประกอบเดียวเท่านั้น หากองค์ประกอบหลายรายการตรงกับการกำหนดค่า จะมีการใช้องค์ประกอบที่กำหนดเองในการทดสอบ ดังนั้น การกำหนดค่า (โดยทั่วไป) ควรเขียนไว้โดยเฉพาะเพียงพอจนจำกัดให้เหลือเพียงองค์ประกอบเดียวในบริบทที่เกี่ยวข้อง
ข้อความ
นี่คือประเภทองค์ประกอบ 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"
}
ทรัพยากร_ID
ระบุองค์ประกอบด้วยรหัสทรัพยากร หรืออาจตรวจสอบส่วนประกอบแพ็กเกจของรหัสนั้นด้วย รหัส PACKAGE
เป็นทางเลือก หากละเว้น แพ็คเกจใดๆ จะตรงกัน และจะพิจารณาเฉพาะส่วนของ ID ต่อไปนี้ :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": {
"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 (ดูด้านบน) ประเภทเหล่านั้นคือ:
กด LONG_PRESS คลิก 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 |
สำหรับประเภทอื่นๆ รายละเอียดการกำหนดค่าคือ:
วัตถุ | คำอธิบาย |
---|---|
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 : ชื่อของคลาสการทดสอบ ตัวอย่างเช่น สำหรับการทดสอบ การตั้งค่า Wifi แพ็กเกจทดสอบคือ
android.platform.tests
และชื่อคลาสการทดสอบคือWifiSettingTest
ห้องสมุดตัวอย่างยานยนต์
Automotive Snippet Library คือชุดไลบรารีการทดสอบ Android สำหรับ Android Open Source Project (AOSP) ที่ออกแบบมาเพื่อโต้ตอบกับแอปและบริการด้านยานยนต์ มันใช้ประโยชน์จาก Spectatio ด้วยกลไกที่สะดวกสำหรับการดำเนินการเรียกขั้นตอนระยะไกล (RPC) จากเครื่องโฮสต์ (ทดสอบ) ไปยังอุปกรณ์ที่ใช้ระบบ Android
เริ่ม
ก่อนที่คุณจะเริ่มต้น ให้ตรวจสอบส่วนเหล่านี้
ข้อกำหนดเบื้องต้น
- ติดตั้ง Python 3.x บนเครื่องโฮสต์
- การตั้งค่าสภาพแวดล้อม AOSP ด้วยเครื่องมือสร้างที่จำเป็น
- อุปกรณ์ยานยนต์ Android (โปรแกรมจำลองหรืออุปกรณ์จริง) ที่มีสิทธิ์การเข้าถึง ADB
การรวบรวม
ในการคอมไพล์ตัวอย่างข้อมูลต่างๆ ที่จัดทำโดย Automotive Snippet Library คุณสามารถใช้ไฟล์ 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 หากมีอุปกรณ์เชื่อมต่อหลายเครื่อง
รวมห้องสมุด
Automotive Snippet Library ประกอบด้วยไลบรารีตัวอย่างและผู้ช่วยเหลือต่อไปนี้:
AutomotiveSnippet: มอบ API ที่เกี่ยวข้องกับการทำงานของยานพาหนะ เช่น การโทรออก การควบคุมระดับเสียง ฮาร์ดคีย์ของยานพาหนะ และการโต้ตอบกับ Media Center
PhoneSnippet: ให้บริการ API ที่เกี่ยวข้องกับระบบโทรศัพท์ รวมถึงการจัดการการโทร การเรียกดูรายชื่อติดต่อ และการดำเนินการ SMS
ตัวอย่างข้อมูลยานยนต์และ PhoneSnippet มีตรรกะร่วมกันบางประการ โดยเฉพาะ คุณสามารถบุกรุกการโทร RCP ที่เกี่ยวข้องกับ Bluetooth เพื่อจับคู่รถยนต์และอุปกรณ์โทรศัพท์ได้ bt_discovery_test
นี้แสดงให้เห็นว่า
- TEST-CLASSNAME : ชื่อของคลาสการทดสอบ ตัวอย่างเช่น สำหรับการทดสอบ การตั้งค่า Wifi แพ็กเกจทดสอบคือ
android.platform.tests
และชื่อคลาสการทดสอบคือWifiSettingTest