Quang phổ: Khung kiểm thử Automotive

Spectatio là một khung kiểm thử mã 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à có khả năng 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 của nền tảng này.

Thiết kế cao cấp

Khung Spectatio có thể điều chỉnh và mở rộng cho nhiều cách triển khai giao diện người dùng AAOS. Đây là công cụ 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 UI Automator, khung Spectatio cung cấp một bộ API để tạo các quy trình kiểm thử giao diện người dùng tương tác với người dùng và các ứng dụng hệ thống trên AAOS. Các kiểm thử ô tô sử dụng những API do khung Spectatio cung cấp để kiểm thử, nhờ đó, các kiểm thử này độc lập với thiết bị đang kiểm thử (DUT) và có thể mở rộng để kiểm thử nhiều thiết bị, nếu được hỗ trợ.

Hình 1 cho thấy khung Spectatio được mô-đun hoá dựa trên các ứng dụng tham chiếu như Trình quay số, 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 bạn 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ợ giúp tiêu chuẩn là lớp mẹ cho tất cả các hàm trợ giúp của ứ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 á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 từ thiết bị.

Kiến trúc

Để cung cấp một tập hợp các API nhằm tạo quy 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 trong khi 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ạ 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 để kiểm thử một ứng dụng.

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

Hình 2. Kiến trúc cấp cao của khung Spectatio.

Giao diện trợ lý ứng dụng cung cấp bản thiết kế để triển khai một trợ lý ứ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 của trình trợ giúp ứng dụng trên AOSP.

Lớp trợ giúp tiêu chuẩn bao gồm các thuộc tính và hàm tiêu chuẩn cần thiết cho quá trình 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ợ giúp tiêu chuẩn được xác định trong AbstractAutoStandardAppHelper.java.

Khung này sử dụng các lớp 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ác cấu hình khung trong thời gian chạy.

Mô-đun triển khai trình trợ giúp ứng dụng là cốt lõi của khung Spectatio. Nó chứa quá trình triển khai cho các hàm trợ giúp được xác định trong giao diện trợ giúp ứng dụng, đây là những hàm bắt buộc để kiểm thử ứng dụng trên thiết bị ô tô. Mỗi ứng dụng có một cách triển khai riêng, chẳng hạn như SettingHelperImplDialHelperImpl, được các kiểm thử Automotive 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.

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

@RunWith(AndroidJUnit4.class)
public class AutoApplicationTest {
  static HelperAccessor<IAutoApplicationHelper> autoApplicationHelper =
          new HelperAccessor<>(IAutoApplicationHelper.class);

  public AutoApplicationTest() {
    // constructor
    // Initialize any attributes that are required for the test execution
  }

  @Before
  public void beforeTest() {
    // Initial setup before each test
    // For example - open the app
    autoApplicationHelper.open();
  }

  @After
  public void afterTest() {
    // Cleanup after each test.
    // For example - exit the app
    autoApplicationHelper.exit();
  }

  @Test
  public void testApplicationFeature() {
    // Test
    // For example - Test if app is open
    assertTrue("Application is not open.", autoApplicationHelper.isOpen());
  }
}

Tuỳ chỉnh

Khung Spectatio không phụ thuộc vào giao diện người dùng của thiết bị, vì vậy, bạn có thể mở rộng quy mô để kiểm thử các thiết bị có giao diện người dùng và phần cứng đa dạ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 mặc định, khung này sử dụng một tệp cấu hình JSON tại thời gian chạy để đặt các thay đổi mong muốn về giao diện người dùng cho thiết bị. Tệp cấu hình JSON hỗ trợ các phần tử trê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ử còn lại trên giao diện người dùng sẽ dùng các giá trị cấu hình mặc định có 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ị một 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ế

Đoạn mã mẫu sau đây minh hoạ một ví dụ về tệp cấu hình JSON, trong đó các chế độ cài đặt mặc định sẽ 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 các thiết bị tham chiếu và Kết nối trên DUT.

  • Bạn có thể tìm thấy chế độ cài đặt ngày và giờ tại phần Cài đặt > Ngày và giờ đối với các thiết bị tham chiếu và tại phần Cài đặt > Hệ thống > Ngày và giờ đối với DUT.

// Default configuration file
{
    ....
    "SECURITY_SETTINGS_SCROLL_ELEMENT": {
      "TYPE": "RESOURCE_ID",
      "VALUE": "fragment_container",
    },
    ....
}

// JSON configuration file for non-reference device
{
    ....
    "SECURITY_SETTINGS_SCROLL_ELEMENT": {
      "TYPE": "RESOURCE_ID",
      "VALUE": "car_ui_recycler_view"
    },
    ....
}

Khi tệp cấu hình JSON đã sẵn sàng, tệp này sẽ được cung cấp trong thời gian chạy như minh hoạ trong khối mã sau:

# Push The JSON configuration file to the device
adb -s DEVICE-SERIAL push PATH-OF-JSON-FILE /data/local/tmp/runtimeSpectatioConfig.json

Trong lệnh này:

  • DEVICE-SERIAL: Mã nhận dạng nối tiếp của DUT. Bạn không bắt buộc phải 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 đó ở 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 dùng nút hay cử chỉ để di chuyể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 UI Automator `BySelectors` 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 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 phần tử trên giao diện người dùng đều có một TYPE chỉ định những gì UI Automator sẽ tìm kiếm để xác định phần tử (chẳng hạn như mã nhận dạng tài nguyên, văn bản và nội dung mô tả) và các giá trị cấu hình được liên kết với loại đó. Nhìn chung, bất cứ khi nào một trợ lý xác định một phần tử trên màn hình bằng cấu hình này, trợ lý 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ử bất kỳ sẽ được dùng trong kiểm thử. Do đó, cấu hình (thường) phải được viết đủ cụ thể để thu hẹp xuống một phần tử trong ngữ cảnh có liên quan.

VĂN BẢN

Đây là loại phần tử đơn giản nhất trên giao diện người dùng. 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 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ừ 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 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 nội dung mô tả, yêu cầu phải 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ủa phần tử đó, bạn cũng có thể kiểm tra thành phần gói của mã nhận dạng đó. Khoá PACKAGE là không bắt buộc; nếu bạn bỏ qua khoá này, mọi gói sẽ khớp và hệ thống chỉ xem xét phần mã nhận dạng sau :id/.

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

NHẤP VÀ CUỘN ĐƯỢC

Xác định phần tử dựa trên việc phần tử đó có thể nhấp hoặc 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
    }

CLASS

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 tại các phần tử tổ tiên của phần tử đó. Khoá ANCESTOR giữ một đối tượng xác định phần tử gốc. Khoá DEPTH chỉ định phạm vi tìm kiếm 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 xét các phần tử con trong hệ phân cấp. 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 tìm kiếm 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"
      }
    }

MULTIPLE

Xác định phần tử dựa trên nhiều điều kiện đồng thời và tất cả các điều kiện đó 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ó văn bản Permission manager.

Workflows

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

PRESS
LONG_PRESS
CLICK
LONG_CLICK
CLICK_IF_EXIST
HAS_UI_ELEMENT_IN_FOREGROUND
SCROLL_TO_FIND_AND_CLICK
SCROLL_TO_FIND_AND_CLICK_IF_EXIST
SWIPE_TO_FIND_AND_CLICK
SWIPE_TO_FIND_AND_CLICK_IF_EXIST

Đối với các TYPE khác, thông tin chi tiết về cấu hình là:

Đối tượng Mô tả
COMMAND Một đối tượng có giá trị TEXT chứa lệnh cần thực thi.
HAS_PACKAGE_IN_FOREGROUND Một đối tượng có giá trị TEXT chứa gói.
SWIPE Bỏ qua CONFIG key cho thao tác SWIPE. 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 đợi.

Các thao tác liên quan đến việc di chuyển và vuốt cần có cấu hình bổ sung như sau:

SCROLL_CONFIG

Đối tượng Mô tả
SCROLL_ACTION USE_GESTURE hoặc USE_BUTTON
SCROLL_DIRECTION HORIZONTAL hoặc VERTICAL
SCROLL_ELEMENT Một đối tượng cho biết vùng chứa cần cuộn, sử dụng cùng một biểu mẫu như cấu hình Phần tử trên giao diện người dùng (xem ở trên).
SCROLL_FORWARD, SCROLL_BACKWARD Nút cuộn tiến và lùi (bắt buộc khi SCROLL_ACTIONUSE_BUTTON).
SCROLL_MARGIN Nếu SCROLL_ACTIONUSE_GESTURE, 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ì 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 vào. (Không bắt buộc, mặc định = 1).

SWIPE_CONFIG

Đối tượng Mô tả
SWIPE_DIRECTION TOP_TO_BOTTOM, BOTTOM_TO_TOP, LEFT_TO_RIGHT hoặc RIGHT_TO_LEFT
SWIPE_FRACTION

Một trong những trường hợp sau:

  • FULL: Cử chỉ vuốt từ cạnh màn hình này sang cạnh màn hình kia

    HOẶC
  • DEFAULT: Từ cạnh màn hình đến cạnh màn hình, 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 ở vị trí cách cạnh màn hình 5 pixel và bắt đầu ở điểm sao cho cử chỉ đó bao phủ khoảng cách đã chỉ định của màn hình.
NUMBER_OF_STEPS Số bước cần dùng để thực hiện thao tác vuốt. Hãy xem segmentSteps.

Xây dựng và thực thi

Khung Spectatio được tự động tạo trong APK kiểm thử. Để tạo 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ẫu mã sau đây cho thấy quá trình tạo, cài đặt và thực thi một APK kiểm thử.

# Build Test APK
make TEST-APK-NAME
# Install Test APK
adb -s DEVICE-SERIAL install -r PATH-FOR-BUILT-TEST-APK
# Execute Test with the JSON file
adb -s DEVICE-SERIAL shell am instrument -w -r -e debug false -e config-file-path /data/local/tmp/jsonFile.json -e class TEST-PACKAGE.TEST-CLASSNAME TEST-PACKAGE/androidx.test.runner.AndroidJUnitRunner

Trong các lệnh này:

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

  • DEVICE-SERIAL: Mã nhận dạng nối tiếp của DUT. Bạn không bắt buộc phải dùng tham số này nếu chỉ có một thiết bị kết nối với máy chủ.

  • config-file-path: Tham số không bắt buộc và chỉ cần thiết để cung cấp các 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 thi các kiểm thử.

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

  • 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ử 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 trích về ô tô

Thư viện đoạn mã Automotive là một nhóm thư viện kiểm thử Android 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ụ trên ô tô. Nó tận dụng Spectatio bằng một cơ chế thuận tiện để thực thi các lệnh gọi quy trình từ xa (RPC) từ một máy chủ (kiểm thử) đến một thiết bị chạy Android.

Bắt đầu

Trước khi bắt đầu, hãy xem 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ủ lưu trữ.
  • Thiết lập môi trường AOSP bằng các công cụ cần thiết để tạo bản dựng.
  • Mộ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. Các lệnh sau 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 kết quả vào 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ử

Các thư viện đoạn mã cung cấp 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ể dùng tập lệnh snippet_shell.py để mở một trình bao 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ị. Ví dụ về lệnh gọi:

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

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

Các thư viện đi kèm

Thư viện đoạn mã Automotive bao gồm các thư viện đoạn mã và trợ giúp sau đây:

  • 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 trên xe và tương tác với trung tâm nội dung đa phương tiện.

  • PhoneSnippet: Cung cấp các API liên quan đến điện thoại, bao gồm cả tính năng xử lý cuộc gọi, duyệt danh bạ và các 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 các lệnh gọi RCP liên quan đến Bluetooth để ghép nối một thiết bị ô tô và một thiết bị điện thoại. bt_discovery_test này cho biết cách thực hiện.