Quang phổ: Khung kiểm thử Automotive

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

Thiết kế cao cấp

Khung Spectatio có thể thích ứng và mở rộng cho nhiều cách triển khai giao diện người dùng AAOS. Công cụ này dùng để kiểm thử 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 hoá.

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

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 Công cụ tự động hoá giao diện người dùng, khung Spectatio cung cấp một bộ API để tạo các chương trình kiểm thử giao diện người dùng tương tác với ứng dụng người dùng và ứng dụng hệ thống trên AAOS. Các chương trình kiểm thử trong ngành ô tô sử dụng các API do khung Spectatio cung cấp để kiểm thử, nhờ đó, các chương trình kiểm thử này độc lập với thiết bị đang được 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 các ứng dụng tham chiếu như Trình quay số, Trung tâm y tế 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 phổ biến. Lớp trợ giúp chuẩn là lớp mẹ cho tất cả các hàm trợ giúp ứng dụng và cung cấp các hàm chuẩn dành riêng cho thiết bị hoặc áp dụng trên các ứng dụng. 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 chương trình kiểm thử 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 hoạ cấu 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 để kiểm thử ứng dụng.

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

Hình 2. Cấu 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ế để triển khai trình trợ giúp ứng dụng. Thư viện này bao gồm nhiều hàm trợ giúp cần thiết để kiểm thử ứng dụng. Mỗi ứng dụng đều 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 hàm giao diện, hãy xem các hàm giao diện trình trợ giúp ứng dụng trên AOSP.

Lớp trình trợ giúp chuẩn bao gồm các thuộc tính và hàm chuẩn cần thiết để thiết lập thiết bị nhưng không dành riêng cho ứng dụng nào, chẳng hạn như pressHomescroll. Lớp trình trợ giúp chuẩn được xác định trong AbstractAutoStandardAppHelper.java.

Khung này sử dụng các lớp trình trợ giúp tiện ích. 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 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 khung Spectatio. Tệp này chứa nội dung triển khai cho các hàm trợ giúp được xác định trong giao diện trình trợ giúp ứng dụng, cần thiết để 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ư SettingHelperImplDialHelperImpl mà các kiểm thử Automotive sử dụng để kiểm thử ứng dụng. Để biết thêm thông tin và danh sách các cách triển khai, hãy xem các 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 hàm triển khai trình trợ giúp ứng dụng để kiểm thử nhiều thao tác liên quan đến ứng dụng. Sử dụng lớp HelperAccessor để có quyền truy cập vào các hàm triển khai trình trợ giúp ứng dụng.

Mã sau đây cho thấy cách thiết lập, dọn dẹp và thực thi một quy trình kiểm thử ô 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());
  }
}

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, khung này có thể mở rộng để kiểm thử các thiết bị có 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. Để hỗ trợ các cấu hình thiết bị không phải mặc định, khung này 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á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ử giao diện người dùng còn lại sử dụng 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 cho thấy các cấu hình thiết bị hiện có và giá trị mặc định của các cấu hình đó.

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

  • Chế độ cài đặt Internet có tên là Mạng và Internet trên thiết bị tham chiếu và Kết nối trên thiết bị được kiểm thử (DUT).

  • Bạn có thể tìm thấy chế độ cài đặt ngày và giờ tại Cài đặt > Ngày và giờ cho thiết bị tham chiếu và tại Cài đặt > Hệ thống > Ngày và giờ cho thiết bị được kiểm thử (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ư 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ã nhận dạng theo thứ tự của DUT. Bạn không bắt buộc phải sử dụng tham số này nếu chỉ có một thiết bị 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ủ.

Đị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á và giá trị sau:

Đối tượng Mô tả
PACKAGES Một đố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 ở nền trước.
ACTIONS Một đối tượng cho biết các loại hành động và tham số cho nhiều hành động. Ví dụ: có nên sử dụng nút hay cử chỉ để cuộn hay không.
COMMANDS Một đối tượng chỉ định các lệnh thực hiện nhiều hành động.
UI_ELEMENTS Một đối tượng dùng để tạo "BySelectors" của Trình tự động hoá giao diện người dùng, đối tượng này sẽ chọn các Phần tử giao diện người dùng (được mô tả chi tiết bên dưới).
WORKFLOWS Trình tự các hành động giúp hoàn thành các tác vụ cấp cao (được mô tả 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 đều có một TYPE chỉ định nội dung mà Trình tự động hoá giao diện người dùng sẽ tìm kiếm để xác định thành phần đó (chẳng hạn như mã nhận dạng tài nguyên, văn bản và nội dung mô tả) và các giá trị cấu hình liên kết với loại đó. Nhìn chung, bất cứ khi nào một trình 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, trình trợ giúp đó sẽ nhận được đúng 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ử tuỳ ý sẽ được sử dụng trong kiểm thử. Do đó, cấu hình (thường) phải được viết một cách cụ thể để thu hẹp thành một phần tử trong ngữ cảnh có liên quan.

VĂN BẢN

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

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

TEXT_CONTAINS

Tương tự như TEXT, ngoại trừ việc VALUE được chỉ định chỉ cần xuất hiện ở đâu đó 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ử theo thuộc tính mô tả nội dung, yêu cầu khớp chính xác.

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

RESOURCE_ID

Xác định phần tử theo mã nhận dạng tài nguyên, cũng có thể kiểm tra thành phần gói của mã nhận dạng đó (không bắt buộc). Bạn không bắt buộc phải sử dụng khoá PACKAGE; nếu bạn bỏ qua khoá này, mọi gói sẽ khớp và chỉ phần mã nhận dạng theo 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, DI CHUYỂN

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

    "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 ở các phần tử mẹ. Khoá ANCESTOR chứa một đối tượng xác định đối tượng cấp trên. Khoá DEPTH chỉ định khoảng cách xem trong 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_ANCESTOR",
      "DEPTH": 2,
      "ANCESTOR": {
        "TYPE": "CLASS",
        "VALUE": "android.view.ViewGroup"
      }
    }

HAS_DESCENDANT

Xác định phần tử bằng cách xem hệ phân cấp của các phần tử con. Khoá DESCENDANT chứa một đối tượng chỉ định phần tử con cần tìm. Khoá DEPTH chỉ định khoảng cách xem trong 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 phần tử dựa trên nhiều điều kiện đồng thời, tất cả điều kiện đó đề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ó một phần tử con ở độ sâu 2, có văn bản Permission manager.

Workflows

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

Nhấn
Nhấn và giữ
Nhấp
Nhấp và giữ
Nhấp nếu có
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, thông tin chi tiết về cấu hình là:

Đối tượng Mô tả
COMMAND Một đối tượng có giá trị TEXT chứa lệnh để 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 thao tác SWIPE. Phương thức 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 thao tác liên quan đến thao tác cuộn và vuốt yêu cầu phải định cấu hình thêm 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 Một đối tượng cho biết vùng chứa cần cuộn, sử dụng cùng một hình thức với cấu hình Phần tử giao diện người dùng (xem ở 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ừ cạnh của vùng chứa để bắt đầu và dừng thao tác kéo sẽ được dùng để thực hiện thao tác cuộn (Không bắt buộc, 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 một đối tượng để nhấp. (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 những điều sau:

  • FULL: Vuốt từ cạnh màn hình này sang cạnh màn hình kia

    HOẶC,
  • DEFAULT: Cạnh màn hình này đến cạnh màn hình kia, với vùng đệm 5 pixel ở mỗi bên.

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

Tạo bản dựng và thực thi

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

Mã mẫu sau đây cho thấy quá trình tạo, cài đặt và thực thi 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 này:

  • TEST-APK-NAME: Tên ứng dụng cần kiểm thử. Ví dụ: đặt TEST-APK-NAME thành AndroidAutomotiveSettingsTests để kiểm thử chế độ 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 tệp APK trong tệp Android.bp tương ứng cho Kiểm thử ô tô.

  • DEVICE-SERIAL: Mã nhận dạng tuần tự của DUT. Bạn không bắt buộc phải sử dụng tham số này 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 thiết để 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 bạn không cung cấp, khung sẽ sử dụng các giá trị mặc định để thực thi các chương trình kiểm thử.

  • PATH-FOR-BUILT-TEST-APK: Đường dẫn nơi 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 kiểm thử Wifi Settings (Cài đặt Wi-Fi), gói kiểm thử là android.platform.tests và tên lớp kiểm thử là WifiSettingTest.

Thư viện đoạn mã dành cho ô tô

Thư viện đoạn mã dành cho ô tô là một nhóm 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 các ứng dụng và dịch vụ dành cho ô tô. Công cụ 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áy chủ (máy kiểm thử) đến thiết bị chạy Android.

Bắt đầu

Trước khi bắt đầu, hãy xem lại các phần sau.

Điều kiện tiên quyết

  • Python 3.x đã được cài đặt trên máy chủ lưu trữ.
  • Thiết lập môi trường AOSP bằng các công cụ xây dựng cần thiết.
  • Thiết bị Android Automotive (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 dịch nhiều đoạn mã 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 tệp APK thu được cho thiết bị mục tiêu bằng lệnh adb install được đề cập trong phần trước.

Chạy chương trình kiểm thử

Thư viện đoạn mã hiển thị một số phương thức RPC để tương tác với hệ thống ô tô. Bạn có thể gọi các phương thức này thông qua khung Mobly từ máy chủ. Giả sử bạn đã thiết lập môi trường kiểm thử Mobly, bạn có thể sử dụng tập lệnh snippet_shell.py để mở một màn hình shell Python tương tác, trong đó 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ệnh gọi mẫu:

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ị. Bạn có thể lấy số sê-ri này bằng các 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ã dành cho ô tô bao gồm các thư viện và trình trợ giúp đoạn mã sau:

  • AutomotiveSnippet: Cung cấp các API liên quan đến hoạt động của xe, chẳng hạn như gọi điện, điều khiển âm lượng, nút cứng trên xe và tương tác với trung tâm đa phương tiện.

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

Đoạn mã Automotive và PhoneSnippet có chung một số logic. Cụ thể, bạn có thể xâm nhập vào các lệnh 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 cho biết cách thực hiện.