Spectatio là khung kiểm thử nguồn mở được phát triển để kiểm thử Android Automotive OS (AAOS) trên thiết bị thực và thiết bị ảo. Spectatio cung cấp các API cho thử nghiệm ứng dụng trên thiết bị ô tô và là một giải pháp có thể mở rộng cũng như mở rộng dùng để xác minh chức năng và hiệu suất của AAOS và các ứng dụng đi kèm.
Thiết kế cao cấp
Khung Spectatio có thể điều chỉnh và mở rộng cho nhiều giao diện người dùng AAOS thực tế. Dùng để kiểm thử chức năng và hiệu suất của AAOS trên phần cứng của thiết bị, trình mô phỏng và môi trường ảo hoá.
Hình sau đây giải thích thiết kế cấp cao của khung Spectatio.
Hình 1. Thiết kế cấp cao của khung Spectatio.
Được xây dựng dựa trên UI Automator, khung Spectatio cung cấp một bộ API để tạo các bài kiểm thử giao diện người dùng tương tác với các ứng dụng của người dùng và hệ thống trên AAOS. Ô tô sử dụng API do khung Spectatio cung cấp để kiểm thử, điều này giúp các bài kiểm thử này độc lập với thiết bị đang kiểm thử (DUT) và có thể mở rộng để kiểm thử nhiều thiết bị, nếu được hỗ trợ.
Hình 1 cho thấy khung Spectatio được mô-đun hoá dựa trên tham chiếu như Trình quay số, Medicenter và Cài đặt bằng cách sử dụng các ứng dụng dành riêng cho ứng dụng giao diện và trình trợ giúp, giúp dễ dàng mở rộng ứng dụng mới. Hiệu ứng quang phổ khung này sử dụng lại các lớp trình trợ giúp tiện ích và tiêu chuẩn chung. Lớp trợ giúp tiêu chuẩn là lớp mẹ cho tất cả chức năng trợ giúp ứng dụng và cung cấp các chức năng chuẩn dành riêng cho thiết bị hoặc có thể áp dụng trên các ứng dụng. Chiến lược phát hành đĩa đơn các lớp trình trợ giúp tiện ích cung cấp các tiện ích như đọc hoặc ghi tệp từ thiết bị.
Kiến trúc
Để cung cấp một bộ API nhằm xây dựng các bài kiểm thử giao diện người dùng, khung Spectatio sẽ triển khai trình trợ giúp và giao diện dành riêng cho ứng dụng, đồng thời mở rộng trình trợ giúp chuẩn hiện có và nhập các lớp trình trợ giúp tiện ích.
Hình 2 minh hoạ kiến trúc cấp cao của khung Spectatio và tất cả các thực thể liên quan đến việc triển khai các API để kiểm thử một ứng dụng.
Hình 2. Kiến trúc cấp cao của khung Spectatio.
Giao diện trình trợ giúp ứng dụng cung cấp sơ đồ thiết kế để triển khai
một trình trợ giúp ứng dụng. Công cụ này có nhiều chức năng trợ giúp cần thiết
để thử nghiệm các ứng dụng. Mỗi ứng dụng đều có giao diện riêng, chẳng hạn như IAutoSettingHelper
và IAutoDialHelper
.
Để biết thêm thông tin và danh sách hàm giao diện, hãy xem các hàm giao diện của trình trợ giúp ứng dụng trên AOSP.
Lớp trợ giúp tiêu chuẩn bao gồm các thuộc tính và hàm chuẩn
bắt buộc để thiết lập thiết bị nhưng không dành riêng cho bất kỳ ứng dụng nào, chẳng hạn như pressHome
và scroll
. Lớp trợ giúp tiêu chuẩn được xác định trong AbstractAutoStandardAppHelper.java
.
Khung này sử dụng các lớp trình trợ giúp phần mềm tiện ích. Cho
Ví dụ: AutoJsonUtility.java
là một
lớp tiện ích tải tệp cấu hình JSON cụ thể của thiết bị và nội dung cập nhật
các cấu hình khung trong thời gian chạy.
Mô-đun triển khai trình trợ giúp ứng dụng là cốt lõi của Spectatio
khung. Tệp này chứa phương thức triển khai các chức năng trợ giúp được xác định trong
giao diện trợ giúp ứng dụng. Đây là giao diện bắt buộc để kiểm thử ứng dụng trên
thiết bị ô tô. Mỗi ứng dụng có cách triển khai riêng, chẳng hạn như SettingHelperImpl
và
DialHelperImpl
!
được sử dụng bởi
các bài kiểm thử Automotive để kiểm thử ứng dụng. Để biết thêm thông tin và xem danh sách
hãy xem hàm triển khai trình trợ giúp ứng dụng
"trên AOSP.
Kiểm thử ô tô
sử dụng các chức năng triển khai trình trợ giúp ứng dụng để kiểm thử nhiều hoạt động
liên quan đến ứng dụng. Sử dụng lớp HelperAccessor
để có quyền truy cập vào chức năng triển khai trình trợ giúp ứng dụng.
Mã sau đây minh hoạ cách thiết lập, dọn dẹp và thực thi một mẫu kiểm thử ô tô.
@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());
}
}
Tuỳ chỉnh
Khung Spectatio độc lập với giao diện người dùng của thiết bị, vì vậy, có thể mở rộng theo
thiết bị thử nghiệm với nhiều giao diện người dùng và phần cứng. Để đạt được khả năng mở rộng này,
Spectatio sử dụng cấu hình thiết bị mặc định dựa trên thiết bị tham chiếu. Người nhận
hỗ trợ cấu hình thiết bị không phải là cấu hình mặc định, khung này sẽ sử dụng một JSON
tệp cấu hình trong thời gian chạy để đặt các thay đổi giao diện người dùng mong muốn cho thiết bị. Đáp
Tệp cấu hình JSON hỗ trợ các thành phần trên giao diện người dùng như TEXT
, DESCRIPTION
và
RESOURCE_ID
, cùng với các chế độ cài đặt path
và chỉ được chứa thông tin
về các thay đổi đối với giao diện người dùng cho DUT. Các phần tử còn lại trên giao diện người dùng sử dụng giá trị mặc định
các giá trị cấu hình được cung cấp trong khung.
Cấu hình thiết bị mặc định
Tệp cấu hình JSON mẫu sau đây cho biết thiết bị có sẵn cấu hình và giá trị mặc định của chúng.
Nhấp vào đây để hiển thị JSON mẫu tệp cấu hình
{ "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" } } } }
Cấu hình thiết bị thay thế
Mã mẫu sau đây là một ví dụ về tệp cấu hình JSON trong đó các chế độ cài đặt mặc định sẽ bị chế độ cài đặt trên DUT ghi đè. Trong ví dụ này:
Chế độ cài đặt Internet được đặt tên là Network & Internet trên các thiết bị tham chiếu và Kết nối trên DUT.
Cài đặt ngày và giờ có trong phần Cài đặt > Ngày và giờ cho thiết bị tham chiếu và tại phần Cài đặt > Hệ thống > Ngày và giờ của 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"
},
....
}
Khi tệp cấu hình JSON đã sẵn sàng, tệp này sẽ được cung cấp trong thời gian chạy như minh hoạ trong khối mã sau:
# Push The JSON configuration file to the device
adb -s DEVICE-SERIAL push PATH-OF-JSON-FILE /data/local/tmp/runtimeSpectatioConfig.json
Trong lệnh này:
DEVICE-SERIAL: Mã sê-ri của DUT. Thông số này không là bắt buộc nếu chỉ có một thiết bị được kết nối với máy chủ.
PATH-TO-JSON-FILE: Đường dẫn của tệp JSON trên máy chủ lưu trữ.
Định dạng cấu hình
Có 5 đối tượng cấp cao nhất trong cấu hình với các khoá sau và giá trị:
Đối tượng | Mô tả |
---|---|
PACKAGES |
Đối tượng mô tả gói chính cho nhiều ứng dụng, được dùng để xác định thời điểm ứng dụng đó chạy trên nền trước. |
ACTIONS |
Đối tượng cho biết các loại hành động và tham số cho nhiều hành động. Ví dụ: sử dụng nút hay cử chỉ để cuộn. |
COMMANDS |
Một đối tượng chỉ định các lệnh thực hiện nhiều thao tác. |
UI_ELEMENTS |
Một đối tượng dùng để tạo UI Automator "BySelectors" (Trình tự động hoá giao diện người dùng) chọn giao diện người dùng Các phần tử (được mô tả chi tiết bên dưới). |
WORKFLOWS |
Trình tự các hành động hoàn thành các tác vụ cấp cao (được mô tả trong thông tin chi tiết bên dưới). |
Phần tử trên giao diện người dùng
Mỗi thành phần trên giao diện người dùng có một TYPE
xác định giao diện người dùng mà Automator sẽ tìm kiếm
xác định phần tử (chẳng hạn như mã nhận dạng tài nguyên, văn bản và mô tả) và
được liên kết với loại đó. Nói chung, bất cứ khi nào trợ giúp
xác định một phần tử trên màn hình bằng cấu hình này, thì cấu hình này sẽ nhận chính xác
một phần tử. Nếu nhiều phần tử khớp với cấu hình, một phần tử tuỳ ý sẽ
được dùng trong thử nghiệm. Do đó, (thường) nên viết cấu hình
đủ cụ thể để thu hẹp xuống một yếu tố trong bối cảnh có liên quan.
VĂN BẢN
Đây là loại phần tử giao diện người dùng đơn giản nhất. Thành phần trên giao diện người dùng được xác định bằng văn bản và yêu cầu kết quả khớp chính xác.
"CALL_HISTORY_MENU": {
"TYPE": "TEXT",
"VALUE": "Recents"
}
VĂN BẢN_CONTAINS
Giống như TEXT
, ngoại trừ việc VALUE
được chỉ định chỉ cần xuất hiện ở nơi nào đó trong
văn bản của phần tử cần so khớp.
"PRIVACY_CALENDAR": {
"TYPE": "TEXT_CONTAINS",
"VALUE": "Calendar"
}
NỘI DUNG MÔ TẢ
Xác định phần tử bằng thuộc tính mô tả nội dung của nó. Yêu cầu cung cấp thông tin chính xác khớp.
"APP_GRID_SCROLL_BACKWARD_BUTTON": {
"TYPE": "DESCRIPTION",
"VALUE": "Scroll up"
}
Mã tài nguyên
Xác định phần tử theo mã tài nguyên, cũng như không bắt buộc kiểm tra gói
của mã nhận dạng đó. Khoá PACKAGE
là không bắt buộc; nếu bị bỏ qua, bất kỳ gói nào
sẽ khớp và chỉ phần mã nhận dạng sau :id/
sẽ được xem xét.
"APP_LIST_SCROLL_ELEMENT": {
"TYPE": "RESOURCE_ID",
"VALUE": "apps_grid",
"PACKAGE": "com.android.car.carlauncher"
}
CÓ THỂ NHẤP CHUỘT, CÓ THỂ CUỘC
Xác định phần tử dựa trên việc phần tử đó có thể nhấp vào hoặc cuộn được hay không.
Đây là các loại phần tử rất rộng và thường chỉ nên được sử dụng trong
MULTIPLE
để giúp thu hẹp một loại phần tử khác. Khoá FLAG
là không bắt buộc
và mặc định là true
.
"SAMPLE_ELEMENT": {
"TYPE": "CLICKABLE",
"FLAG": false
}
LỚP
Xác định phần tử dựa trên lớp của nó.
"SECURITY_SETTINGS_ENTER_PASSWORD": {
"TYPE": "CLASS",
"VALUE": "android.widget.EditText"
}
HAS_ANCESTOR
Xác định phần tử bằng cách tra cứu hệ phân cấp tiện ích ở đối tượng cấp trên. Chiến lược phát hành đĩa đơn
Khoá ANCESTOR
chứa một đối tượng giúp xác định đối tượng cấp trên. Khoá DEPTH
chỉ rõ hệ thống phân cấp cần tìm đến đâu. DEPTH
là không bắt buộc và có
giá trị mặc định là 1
.
"SAMPLE_ELEMENT": {
"TYPE": "HAS_ANCESTOR",
"DEPTH": 2,
"ANCESTOR": {
"TYPE": "CLASS",
"VALUE": "android.view.ViewGroup"
}
}
HAS_DESCENDANT
Xác định phần tử bằng cách xem qua hệ phân cấp của các phần tử con. Chiến lược phát hành đĩa đơn
Khoá DESCENDANT
lưu một đối tượng chỉ định phần tử con cần tìm. Chiến lược phát hành đĩa đơn
Khoá DEPTH
xác định khoảng cách cho hệ phân cấp. DEPTH
là không bắt buộc và
có giá trị mặc định là 1
.
"SAMPLE_ELEMENT": {
"TYPE": "HAS_DESCENDANT",
"DEPTH": 2,
"DESCENDANT": {
"TYPE": "CLASS",
"VALUE": "android.view.ViewGroup"
}
}
NHIỀU
Xác định nguyên tố dựa trên nhiều điều kiện đồng thời, tất cả đều phải được đáp ứng.
"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"
}
}
]
}
Trong ví dụ này, cấu hình xác định một RelativeLayout
có phần tử
thành phần con ở độ sâu 2
, có văn bản Permission manager
.
Workflows
Luồng công việc biểu thị một chuỗi các hành động được dùng để hoàn thành một công việc cụ thể công việc có thể khác nhau đủ giữa loại thiết bị và loại thiết bị và linh hoạt để thể hiện trong cấu hình so với trong mã.
"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"
}
}
}
]
}
Mỗi quy trình làm việc là một cặp khoá-giá trị, trong đó khoá là tên của quy trình làm việc và
giá trị là một mảng các hành động cần thực hiện. Mỗi thao tác sẽ có một NAME
, một TYPE
(thường) CONFIG
và (đôi khi) SWIPE_CONFIG
hoặc SCROLL_CONFIG
. Cho
hầu hết các TYPE, CONFIG
là đối tượng có khoá UI_ELEMENT
có giá trị nhận
cùng một biểu mẫu với mục nhập phần tử trên giao diện người dùng (xem ở trên). Đó là:
NHẤN LONG_PRESS NHẤP 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 |
Đối với các TYPE khác, thông tin chi tiết về cấu hình như sau:
Đối tượng | Mô tả |
---|---|
COMMAND |
Một đối tượng có giá trị TEXT chứa lệnh cần thực thi. |
HAS_PACKAGE_IN_FOREGROUND |
Đối tượng có giá trị TEXT chứa gói. |
SWIPE |
Bỏ qua CONFIG key cho thao tác SWIPE . Chiến dịch này
chỉ sử dụng SWIPE_CONFIG |
WAIT_MS |
Đối tượng có giá trị TEXT chứa số
mili giây để chờ. |
Các thao tác liên quan đến cuộn và vuốt cần được thiết lập bổ sung như sau:
SCROLL_CONFIG
Đối tượng | Mô tả |
---|---|
SCROLL_ACTION |
USE_GESTURE hoặc USE_BUTTON |
SCROLL_DIRECTION |
HORIZONTAL hoặc VERTICAL |
SCROLL_ELEMENT |
Đối tượng cho biết vùng chứa cần cuộn, sử dụng cùng một biểu mẫu như giao diện người dùng Cấu hình phần tử (xem ở trên). |
SCROLL_FORWARD , SCROLL_BACKWARD |
Nút cuộn tiến và lùi (bắt buộc khi
SCROLL_ACTION là USE_BUTTON ). |
SCROLL_MARGIN |
Nếu SCROLL_ACTION là USE_GESTURE , khoảng cách
từ cạnh của vùng chứa để bắt đầu và dừng lực kéo sẽ được sử dụng
để cuộn (Không bắt buộc, mặc định = 10). |
SCROLL_WAIT_TIME |
Nếu SCROLL_ACTION là USE_GESTURE , thời gian theo
mili giây để chờ giữa các cử chỉ cuộn khi tìm kiếm một đối tượng để
nhấp vào.
(Không bắt buộc, mặc định = 1). |
SWIPE_CONFIG
Đối tượng | Mô tả |
---|---|
SWIPE_DIRECTION |
TOP_TO_BOTTOM , BOTTOM_TO_TOP ,
LEFT_TO_RIGHT hoặc RIGHT_TO_LEFT |
SWIPE_FRACTION |
Một trong các trường hợp sau:
|
NUMBER_OF_STEPS |
Số bước sẽ thực hiện thao tác vuốt. Hãy xem
segmentSteps .
|
Xây dựng và thực thi
Khung Spectatio được tạo tự động như một phần của APK kiểm thử. Xây dựng APK kiểm thử, cơ sở mã AOSP phải nằm trên máy trạm cục bộ. Sau APK kiểm thử được tạo, người dùng phải cài đặt APK trên thiết bị và thực thi thử nghiệm.
Mã mẫu sau đây minh hoạ cách xây dựng, lắp đặt và thực thi một APK kiểm thử.
# 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
Trong các lệnh sau:
TEST-APK-NAME: Tên của ứng dụng cần kiểm thử. Ví dụ: đặt TEST-APK-NAME đến
AndroidAutomotiveSettingsTests
để kiểm tra chế độ cài đặt Wi-Fi như được chỉ định trongAndroid.bp
. Bạn có thể tìm thấy tên của APK trong tệpAndroid.bp
tương ứng cho tính năng Kiểm thử ô tô.DEVICE-SERIAL: Mã sê-ri của DUT. Thông số này không là bắt buộc nếu chỉ có một thiết bị được kết nối với máy chủ.
config-file-path
: Tham số không bắt buộc, chỉ cần cung cấp để cung cấp cấu hình giao diện người dùng của thiết bị không mặc định như được chỉ định trong cấu hình JSON . Nếu không được cung cấp, khung này sử dụng các giá trị mặc định để thực thi chương trình kiểm thử.PATH-FOR-BUILT-TEST-APK: Đường dẫn tạo tệp APK kiểm thử khi thực thi lệnh
make
.TEST-PACKAGE: Tên của gói kiểm thử.
TEST-CLASSNAME: Tên của lớp kiểm thử. Ví dụ: đối với Cài đặt Wi-Fi, gói thử nghiệm là
android.platform.tests
và tên lớp kiểm tra làWifiSettingTest
.
Thư viện đoạn mã Automotive
Thư viện đoạn mã Automotive là một tập hợp các thư viện Kiểm thử Android dành cho Dự án nguồn mở Android (AOSP) được thiết kế để tương tác với ô tô các ứng dụng và dịch vụ. Nền tảng này tận dụng Spectatio với một cơ chế thuận tiện để thực thi các lệnh gọi quy trình từ xa (RPC) từ một máy chủ (kiểm thử) đến một Thiết bị chạy Android.
Bắt đầu
Trước khi bạn bắt đầu, hãy xem lại các mục này.
Điều kiện tiên quyết
- Python 3.x được cài đặt trên máy chủ.
- Thiết lập môi trường AOSP (Dự án nguồn mở Android) với các công cụ xây dựng cần thiết.
- Một thiết bị ô tô Android (trình mô phỏng hoặc thiết bị thực) có quyền truy cập adb.
Biên dịch
Để biên soạn các đoạn mã khác nhau do Thư viện đoạn mã Automotive cung cấp, bạn
có thể sử dụng tệp android.bp
được cung cấp. Đang thực hiện các lệnh trong trước
để biên dịch APK.
Triển khai
Sau khi biên dịch thành công các thư viện đoạn mã, hãy triển khai các APK thu được để
thiết bị mục tiêu bằng lệnh adb install
đã đề cập trong phần trước
.
Chạy chương trình kiểm thử
Các thư viện đoạn mã hiển thị một số phương thức RPC để tương tác với ô tô
hệ thống. Các phương thức này có thể được gọi thông qua khung AdMob từ máy chủ
máy. Giả sử bạn đã thiết lập môi trường kiểm thử di động, bạn có thể sử dụng
Tập lệnh snippet_shell.py
để mở một shell Python tương tác. Tại đây, bạn có thể
gọi các phương thức RPC trên thiết bị theo cách thủ công. Ví dụ về lệnh gọi:
python3 snippet_shell.py com.google.android.mobly.snippet.bundled -s <serial>
Thay thế <serial>
bằng số sê-ri của thiết bị mà bạn có thể lấy bằng số này
Thiết bị adb nếu có nhiều thiết bị được kết nối.
Thư viện đi kèm
Thư viện đoạn mã Automotive bao gồm các thư viện đoạn mã sau và trợ giúp:
AutomotiveĐoạn mã: Cung cấp các API liên quan đến hoạt động của xe, chẳng hạn như quay số, điều chỉnh âm lượng, phím cứng trên xe và tương tác trung tâm nội dung nghe nhìn.
PhoneSnippet: Cung cấp các API liên quan đến điện thoại, bao gồm cả tính năng xử lý cuộc gọi, duyệt danh bạ và thao tác SMS.
Đoạn mã Automotive và Đoạn mã điện thoại có chung một số logic.
Cụ thể, bạn có thể sử dụng các lệnh gọi RCP liên quan đến Bluetooth để ghép nối ô tô
và một thiết bị điện thoại. bt_discovery_test
này cho biết cách thực hiện.
- TEST-CLASSNAME: Tên của lớp kiểm thử. Ví dụ: đối với
kiểm tra Cài đặt Wi-Fi,
gói kiểm thử là
android.platform.tests
và tên lớp kiểm thử làWifiSettingTest
.