Spectatio: Khung kiểm tra ô tô

Spectatio là một khung thử nghiệm nguồn mở được phát triển để thử nghiệm Android Automotive OS (AAOS) trên các thiết bị thực và ảo. Spectatio cung cấp API để thử nghiệm ứng dụng trên thiết bị ô tô, đồng thời là giải pháp có thể mở rộng và mở rộng được dùng để xác minh khả năng và hiệu suất của AAOS cũng như các ứng dụng đi kèm.

Thiết kế cấp cao

Khung Spectatio có khả năng thích ứng và mở rộng để triển khai các giao diện người dùng AAOS khác nhau. Nó được sử dụng để kiểm tra khả năng và hiệu suất của AAOS trên phần cứng thiết bị, trình mô phỏng và môi trường ảo hóa.

Hình dưới đây giải thích thiết kế cấp cao của khung Spectatio.

Thiết kế cấp cao 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 để xây dựng các thử nghiệm giao diện người dùng tương tác với các ứng dụng hệ thống và người dùng trên AAOS. Thử nghiệm ô tô sử dụng các API do khung Spectatio cung cấp để thử nghiệm, giúp các thử nghiệm này trở nên độc lập với thiết bị được thử nghiệm (DUT) và có thể mở rộng để thử nghiệm nhiều thiết bị khác nhau, nếu được hỗ trợ.

Hình 1 cho thấy khung Spectatio được mô-đun hóa dựa trên các ứng dụng tham chiếu như Dialer, Medicenter và Cài đặt bằng cách sử dụng các giao diện và trình trợ giúp dành riêng cho ứng dụng, giúp dễ dàng mở rộng cho các ứng dụng mới. Khung Spectatio sử dụng lại các lớp trợ giúp tiện ích và tiêu chuẩn chung. Lớp trình trợ giúp tiêu chuẩn là lớp cha cho tất cả các chức năng của trình trợ giúp ứng dụng và cung cấp các hàm tiêu chuẩn dành riêng cho thiết bị hoặc có thể áp dụng trên các ứng dụng. Các lớp trợ giúp tiện ích cung cấp các tiện ích như đọc hoặc ghi tập tin từ thiết bị.

Ngành kiến ​​​​trúc

Để cung cấp một bộ API nhằm xây dựng các thử nghiệm giao diện người dùng, khung Spectatio triển khai các giao diện và trình trợ giúp dành riêng cho ứng dụng, đồng thời mở rộng lớp trình trợ giúp tiêu chuẩn hiện có và nhập các lớp trình trợ giúp tiện ích.

Hình 2 minh họa 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 API để thử nghiệm một ứng dụng.

Kiến trúc cấp cao khung Spectatio

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 bản thiết kế chi tiết để triển khai trình trợ giúp ứng dụng. Nó bao gồm nhiều chức năng trợ giúp khác nhau cần thiết cho việc thử nghiệm ứng dụng. Mỗi ứng dụng có giao diện riêng, chẳng hạn như IAutoSettingHelperIAutoDialHelper . Để biết thêm thông tin và danh sách các chức năng giao diện, hãy xem các chức năng giao diện trợ giúp ứng dụng trên AOSP.

Lớp trình trợ giúp tiêu chuẩn bao gồm các thuộc tính và chức năng tiêu chuẩn được yêu cầu để 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ư pressHomescroll . Lớp trình trợ giúp tiêu chuẩn được định nghĩa trong AbstractAutoStandardAppHelper.java .

Các lớp trợ giúp tiện ích được khung sử dụng. Ví dụ: AutoJsonUtility.java là một lớp tiện ích tải tệp cấu hình JSON của thiết bị đã cho và cập nhật cấu hình khung khi chạy.

Mô-đun triển khai trình trợ giúp ứng dụng là cốt lõi của khung Spectatio. Nó chứa phần 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, cần thiết để thử nghiệm ứ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ư SettingHelperImplDialHelperImpl , được các thử nghiệm Ô tô sử dụng để thử nghiệm ứng dụng. Để biết thêm thông tin và danh sách triển khai, hãy xem các chức năng triển khai của trình trợ giúp ứng dụng 'trên AOSP.

Thử nghiệm ô tô sử dụng các chức năng triển khai của trình trợ giúp ứng dụng để thử nghiệm các hoạt động khác nhau liên quan đến ứng dụng. Sử dụng lớp HelperAccessor để có quyền truy cập vào các chức năng triển khai trình trợ giúp ứng dụng.

Đoạn mã sau đây hiển thị quá trình thiết lập, dọn dẹp và thực hiện thử nghiệm ô tô mẫu.

@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());
  }
}

Tùy chỉnh

Khung Spectatio độc lập với giao diện người dùng của thiết bị, do đó, nó có thể mở rộng để thử nghiệm các thiết bị có giao diện người dùng và phần cứng khác nhau. Để đạ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. Để hỗ trợ các cấu hình thiết bị không mặc định, khung sử dụng tệp cấu hình JSON 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ị. Tệp cấu hình JSON hỗ trợ các thành phần giao diện người dùng như TEXT , DESCRIPTIONRESOURCE_ID , cùng với cài đặt path và chỉ được chứa thông tin về các thay đổi giao diện người dùng cho DUT. Phần còn lại của các thành phần giao diện người dùng sử dụng các giá trị cấu hình mặc đị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 hiển thị các cấu hình thiết bị có sẵn và các giá trị mặc định của chúng.

Nhấp vào đây để hiển thị tệp cấu hình JSON mẫu

    {
        "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ẫu mã sau đây hiển thị ví dụ về tệp cấu hình JSON trong đó cài đặt mặc định bị ghi đè bởi cài đặt trên DUT. Trong ví dụ này:

  • Cài đặt Internet được đặt tên là Mạng & 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ó sẵn tại Cài đặt > Ngày và giờ cho các thiết bị tham chiếu và tại Cài đặt > Hệ thống > Ngày và giờ cho 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, nó sẽ được cung cấp trong thời gian chạy như minh họa 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 : ID nối tiếp của DUT. Tham số này không 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 file JSON trên máy chủ.

Định dạng cấu hình

Có năm đối tượng cấp cao nhất trong cấu hình, với các khóa và giá trị sau:

Sự vật Sự miêu tả
PACKAGES Một đối tượng mô tả gói chính cho các ứng dụng khác nhau, được sử dụng để xác định thời điểm ứng dụng đó ở nền trước.
ACTIONS Một đối tượng chỉ ra các loại hành động và các tham số cho các hành động khác nhau. 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 các hành động khác nhau.
UI_ELEMENTS Một đối tượng được sử dụng để xây dựng UI Automator `BySelectors` để chọn các Thành phần UI (được mô tả chi tiết bên dưới).
WORKFLOWS Chuỗi hành động hoàn thành nhiệm vụ cấp cao (được mô tả chi tiết bên dưới).

thành phần giao diện người dùng

Mỗi thành phần giao diện người dùng có một TYPE chỉ định những gì UI Automator sẽ tìm kiếm để xác định thành phần (chẳng hạn như ID tài nguyên, văn bản và mô tả) cũng như các giá trị cấu hình được liên kết với loại đó. Nói chung, bất cứ khi nào người 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, nó sẽ nhận được chính xác một phần tử. Nếu nhiều phần tử khớp với cấu hình thì một phần tử tùy ý sẽ được sử dụng trong thử nghiệm. Do đó, cấu hình (nói chung) phải được viết đủ cụ thể để thu hẹp thành một thành phần trong ngữ cảnh liên quan.

CHỮ

Đây là loại thành phần UI đơn giản nhất. Thành phần giao diện người dùng được xác định bằng văn bản của nó và yêu cầu phải khớp chính xác.

    "CALL_HISTORY_MENU": {
      "TYPE": "TEXT",
      "VALUE": "Recents"
    }

TEXT_CONTAINS

Tương tự như TEXT , ngoại trừ VALUE được chỉ định chỉ cần xuất hiện ở đâu đó trong văn bản của phần tử cần khớp.

    "PRIVACY_CALENDAR": {
      "TYPE": "TEXT_CONTAINS",
      "VALUE": "Calendar"
    }

SỰ MIÊU TẢ

Xác định phần tử theo thuộc tính mô tả nội dung của nó, yêu cầu khớp chính xác.

    "APP_GRID_SCROLL_BACKWARD_BUTTON": {
      "TYPE": "DESCRIPTION",
      "VALUE": "Scroll up"
    }

TÀI NGUYÊN_ID

Xác định phần tử theo ID tài nguyên của nó, tùy ý kiểm tra thành phần gói của ID đó. Phím PACKAGE là tùy chọn; nếu bị bỏ qua, mọi gói sẽ khớp và chỉ phần ID sau :id/ mới được xem xét.

    "APP_LIST_SCROLL_ELEMENT": {
      "TYPE": "RESOURCE_ID",
      "VALUE": "apps_grid",
      "PACKAGE": "com.android.car.carlauncher"
    }

CÓ THỂ NHẤP VÀO, CÓ THỂ CUỘN

Xác định phần tử dựa trên việc nó có thể (hoặc không) có thể nhấp hoặc cuộn được. Đâ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 loại phần tử khác. Khóa FLAG là tùy chọn và có giá trị mặc định là true .

    "SAMPLE_ELEMENT": {
      "TYPE": "CLICKABLE",
      "FLAG": false
    }

LỚP HỌC

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ệ thống phân cấp tiện ích ở tổ tiên của nó. Khóa ANCESTOR giữ một đối tượng xác định tổ tiên. Khóa DEPTH chỉ định mức độ phân cấp cần tìm. DEPTH là tùy chọn 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 nhìn xuống phần tử con của nó. Khóa DESCENDANT giữ một đối tượng chỉ định đứa trẻ cần tìm. Khóa DEPTH chỉ định mức độ phân cấp cần tìm. DEPTH là tùy chọn 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 phầ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ử con ở độ sâu 2 , có phần văn bản Permission manager .

Quy trình làm việc

Luồng công việc thể hiện một chuỗi các hành động được sử dụng để hoàn thành một nhiệm vụ cụ thể, có thể khác nhau tùy theo loại thiết bị và linh hoạt hơn khi 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 khóa-giá trị trong đó khóa là tên của quy trình làm việc và giá trị là một mảng hành động cần thực hiện. Mỗi hành động có NAME , TYPE , (thường) CONFIG và (đôi khi) SWIPE_CONFIG hoặc SCROLL_CONFIG . Đối với hầu hết các LOẠI, CONFIG là một đối tượng có khóa UI_ELEMENT có giá trị có dạng giống như mục nhập thành phần UI (xem ở trên). Những LOẠI đó là:

NHẤN
LONG_PRESS
NHẤP CHUỘT
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 LOẠI khác, chi tiết cấu hình là:

Sự vật Sự miêu tả
COMMAND Một đối tượng có giá trị TEXT chứa lệnh cần thực thi.
HAS_PACKAGE_IN_FOREGROUND Một đối tượng có giá trị TEXT chứa gói.
SWIPE Bỏ qua CONFIG key cho hành động SWIPE . Điều này chỉ sử dụng SWIPE_CONFIG
WAIT_MS Một đối tượng có giá trị TEXT chứa số mili giây cần chờ.

Các hành động liên quan đến cuộn và vuốt yêu cầu cấu hình bổ sung, như sau:

SCROLL_CONFIG

Sự vật Sự miêu tả
SCROLL_ACTION USE_GESTURE hoặc USE_BUTTON
SCROLL_DIRECTION HORIZONTAL hoặc VERTICAL
SCROLL_ELEMENT Một đối tượng biểu thị vùng chứa cần cuộn, sử dụng biểu mẫu tương tự như cấu hình Thành phần giao diện người dùng (xem bên trên).
SCROLL_FORWARD , SCROLL_BACKWARD Các nút cuộn tiến và lùi (bắt buộc khi SCROLL_ACTIONUSE_BUTTON ).
SCROLL_MARGIN Nếu SCROLL_ACTIONUSE_GESTURE thì khoảng cách từ mép container đến điểm bắt đầu và dừng thao tác kéo sẽ dùng để thực hiện thao tác cuộn ( Tùy chọn, mặc định = 10).
SCROLL_WAIT_TIME Nếu SCROLL_ACTIONUSE_GESTURE , thời gian tính bằng mili giây để chờ giữa các cử chỉ cuộn khi tìm kiếm đối tượng để nhấp vào. ( Tùy chọn, mặc định = 1).

SWIPE_CONFIG

Sự vật Sự miêu tả
SWIPE_DIRECTION TOP_TO_BOTTOM , BOTTOM_TO_TOP , LEFT_TO_RIGHT hoặc RIGHT_TO_LEFT
SWIPE_FRACTION

Một trong những điều sau đây:

  • FULL : Cử chỉ vuốt từ mép màn hình này sang mép màn hình khác

    HOẶC,
  • DEFAULT : Từ mép màn hình đến mép màn hình, với vùng đệm năm (5) pixel ở mỗi bên.

    HOẶC,
  • THREE_QUARTER , HALF hoặc QUARTER : Cử chỉ vuốt kết thúc năm (5) pixel tính từ mép màn hình và bắt đầu tại điểm bao phủ khoảng cách được chỉ định của màn hình.
NUMBER_OF_STEPS Số bước được sử dụng để thực hiện thao tác vuốt. Xem segmentSteps .

Xây dựng và thực hiện

Khung Spectatio được xây dựng tự động như một phần của APK thử nghiệm. Để xây dựng APK thử nghiệm, cơ sở mã AOSP phải nằm trên máy trạm cục bộ. Sau khi APK thử nghiệm được tạo, người dùng phải cài đặt APK trên thiết bị và thực hiện thử nghiệm.

Mẫu mã sau đây cho thấy quá trình xây dựng, cài đặt và thực thi APK thử nghiệm.

# 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 này:

  • TEST-APK-NAME : Tên của ứng dụng cần kiểm tra. Ví dụ: đặt TEST-APK-NAME thành AndroidAutomotiveSettingsTests để kiểm tra cài đặt Wi-Fi như được chỉ định trong tệp Android.bp . Bạn có thể tìm thấy tên của APK trong tệp Android.bp tương ứng cho bài kiểm tra Ô tô .

  • DEVICE-SERIAL : ID nối tiếp của DUT. Tham số này không 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ố tùy chọn chỉ được yêu cầu để cung cấp cấu hình giao diện người dùng thiết bị không mặc định như được chỉ định trong tệp cấu hình JSON . Nếu không được cung cấp, khung sẽ sử dụng các giá trị mặc định để thực hiện kiểm tra.

  • PATH-FOR-BUILT-TEST-APK : Đường dẫn nơi APK thử nghiệm được tạo khi lệnh make được thực thi.

  • TEST-PACKAGE : Tên của gói thử nghiệm.

  • TEST-CLASSNAME : Tên của lớp kiểm tra. Ví dụ: đối với bài kiểm tra Cài đặt Wifi , gói kiểm tra là android.platform.tests và tên lớp kiểm tra là WifiSettingTest .

Thư viện đoạn mã ô tô

Thư viện đoạn mã ô tô là một tập hợp các thư viện Kiểm thử Android dành cho Dự án mã nguồn mở Android (AOSP) được thiết kế để tương tác với các ứng dụng và dịch vụ ô tô. Nó tận dụng Spectatio với một cơ chế thuận tiện để thực hiện các cuộc gọi thủ tục từ xa (RPC) từ máy chủ (kiểm tra) đến thiết bị chạy Android.

Bắt đầu

Trước khi bạn bắt đầu, hãy xem lại các phần 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 với các công cụ xây dựng cần thiết.
  • Thiết bị ô tô Android (trình mô phỏng hoặc thiết bị vật lý) có quyền truy cập adb.

biên soạn

Để biên dịch nhiều đoạn mã khác nhau do Thư viện đoạn mã ô tô cung cấp, bạn có thể sử dụng tệp android.bp được cung cấp. Làm theo các lệnh trong phần 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 kết quả đến thiết bị đích bằng lệnh adb install được đề cập trong phần trước.

Chạy thử nghiệm

Thư viện đoạn mã hiển thị một số phương pháp RPC để tương tác với hệ thống ô tô. Các phương thức này có thể được gọi thông qua khung Mobly từ máy chủ. Giả sử bạn đã thiết lập môi trường thử nghiệm Mobly, bạn có thể sử dụng tập lệnh snippet_shell.py để mở shell Python tương tác, nơi bạn có thể gọi các phương thức RPC theo cách thủ công trên thiết bị. Lời gọi ví dụ:

python3 snippet_shell.py com.google.android.mobly.snippet.bundled -s <serial>

Thay thế <serial> bằng số sê-ri thiết bị mà bạn có thể lấy bằng adb devices nếu nhiều thiết bị được kết nối.

Thư viện đi kèm

Thư viện đoạn mã ô tô bao gồm các thư viện đoạn mã và trình trợ giúp sau:

  • AutomotiveSnippet: 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 khiển âm lượng, phím cứng của xe và tương tác với trung tâm truyền thông.

  • PhoneSnippet: Cung cấp các API liên quan đến điện thoại, bao gồm xử lý cuộc gọi, duyệt danh bạ và hoạt động SMS.

Đoạn mã Ô tô và Đoạn mã điện thoại có chung một số logic chung. Cụ thể, bạn có thể thực hiện các cuộc gọi RCP liên quan đến Bluetooth để ghép nối thiết bị ô tô và điện thoại. bt_discovery_test này chỉ ra cách thực hiện.