Spectatio: چارچوب تست خودرو

Spectatio یک چارچوب تست منبع باز است که برای آزمایش سیستم عامل Android Automotive (AAOS) در دستگاه های واقعی و مجازی توسعه یافته است. Spectatio API هایی را برای آزمایش برنامه ها در دستگاه خودرو ارائه می دهد و راه حلی قابل گسترش و مقیاس پذیر است که برای تأیید قابلیت و عملکرد AAOS و برنامه های آن استفاده می شود.

طراحی سطح بالا

چارچوب Spectatio برای پیاده سازی های مختلف AAOS UI قابل انطباق و گسترش است. برای آزمایش قابلیت و عملکرد AAOS بر روی سخت افزار دستگاه، شبیه سازها و محیط های مجازی استفاده می شود.

شکل زیر طراحی سطح بالای چارچوب Spectatio را توضیح می دهد.

طراحی سطح بالا چارچوب Spectatio

شکل 1. طراحی سطح بالا چارچوب Spectatio.

چارچوب Spectatio که در بالای UI Automator ساخته شده است، مجموعه‌ای از APIها را برای ساخت تست‌های UI ارائه می‌کند که با کاربر و برنامه‌های سیستم در AAOS تعامل دارند. تست‌های خودرو از API‌های ارائه‌شده توسط چارچوب Spectatio برای آزمایش استفاده می‌کنند، که این تست‌ها را مستقل از دستگاه تحت آزمایش (DUT) و مقیاس‌پذیر برای آزمایش دستگاه‌های مختلف، در صورت پشتیبانی می‌کند.

شکل 1 نشان می‌دهد که چارچوب Spectatio بر اساس برنامه‌های مرجع مانند Dialer، Medicenter و Settings با استفاده از رابط‌ها و کمک‌کننده‌های خاص برنامه، مدولار شده است و به راحتی برای برنامه‌های جدید قابل گسترش است. چارچوب Spectatio از کلاس‌های کمکی استاندارد و کاربردی مجدد استفاده می‌کند. کلاس کمکی استاندارد، کلاس والد برای همه توابع کمکی برنامه است و عملکردهای استانداردی را ارائه می‌کند که مخصوص دستگاه هستند یا در بین برنامه‌ها قابل اجرا هستند. کلاس های کمکی ابزارهایی مانند خواندن یا نوشتن فایل ها از دستگاه را ارائه می دهند.

معماری

برای ارائه مجموعه‌ای از APIها برای ساخت تست‌های UI، چارچوب Spectatio رابط‌ها و کمک‌های مخصوص اپلیکیشن را پیاده‌سازی می‌کند، در حالی که کلاس کمکی استاندارد موجود را گسترش می‌دهد و کلاس‌های کمکی ابزار را وارد می‌کند.

شکل 2 معماری سطح بالای چارچوب Spectatio و تمام نهادهای درگیر در اجرای APIها برای آزمایش یک برنامه را نشان می دهد.

معماری سطح بالا چارچوب Spectatio

شکل 2. معماری سطح بالا چارچوب Spectatio.

رابط برنامه کمکی طرحی را برای اجرای یک برنامه کمکی ارائه می دهد. این شامل توابع کمکی مختلفی است که برای آزمایش برنامه ها مورد نیاز است. هر برنامه رابط مخصوص به خود را دارد، مانند IAutoSettingHelper و IAutoDialHelper . برای اطلاعات بیشتر و لیستی از عملکردهای رابط، به توابع رابط کمکی برنامه در AOSP مراجعه کنید.

کلاس کمکی استاندارد شامل ویژگی‌ها و عملکردهای استانداردی است که برای راه‌اندازی دستگاه مورد نیاز هستند، اما مختص هیچ برنامه‌ای نیستند، مانند pressHome و scroll . کلاس کمکی استاندارد در AbstractAutoStandardAppHelper.java تعریف شده است.

کلاس های کمکی توسط فریمورک استفاده می شود. به عنوان مثال، AutoJsonUtility.java یک کلاس ابزار است که فایل پیکربندی JSON دستگاه داده شده را بارگیری می کند و پیکربندی های چارچوب را در زمان اجرا به روز می کند.

ماژول اجرای برنامه کمکی هسته چارچوب Spectatio است. این شامل پیاده سازی برای توابع کمکی تعریف شده در رابط برنامه کمکی است که برای آزمایش برنامه ها در یک دستگاه خودرو مورد نیاز است. هر برنامه پیاده‌سازی خاص خود را دارد، مانند SettingHelperImpl و DialHelperImpl که توسط تست‌های Automotive برای آزمایش برنامه‌ها استفاده می‌شوند. برای اطلاعات بیشتر و لیستی از پیاده سازی ها، به توابع پیاده سازی کمک کننده برنامه در AOSP مراجعه کنید.

Automotive Tests از توابع اجرای برنامه کمکی برای آزمایش عملیات مختلف مرتبط با برنامه استفاده می کند. از کلاس HelperAccessor برای دسترسی به توابع پیاده سازی کمک کننده برنامه استفاده کنید.

کد زیر راه اندازی، پاکسازی و اجرای یک نمونه تست خودرو را نشان می دهد.

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

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

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

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

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

سفارشی سازی

چارچوب Spectatio مستقل از رابط کاربری دستگاه است، بنابراین برای آزمایش دستگاه‌هایی با رابط‌های کاربری و سخت‌افزار متنوع، مقیاس‌پذیر است. برای دستیابی به این مقیاس پذیری، Spectatio از تنظیمات پیش فرض دستگاه بر اساس دستگاه مرجع استفاده می کند. برای پشتیبانی از پیکربندی‌های غیر پیش‌فرض دستگاه، چارچوب از یک فایل پیکربندی JSON در زمان اجرا استفاده می‌کند تا تغییرات UI مورد نظر را برای دستگاه تنظیم کند. یک فایل پیکربندی JSON از عناصر رابط کاربری مانند TEXT ، DESCRIPTION ، و RESOURCE_ID به همراه تنظیمات path پشتیبانی می‌کند و باید فقط حاوی اطلاعات مربوط به تغییرات UI برای DUT باشد. بقیه عناصر UI از مقادیر پیکربندی پیش فرض ارائه شده در چارچوب استفاده می کنند.

تنظیمات پیش فرض دستگاه

نمونه فایل پیکربندی JSON زیر پیکربندی های دستگاه موجود و مقادیر پیش فرض آنها را نشان می دهد.

برای نمایش نمونه فایل پیکربندی JSON اینجا را کلیک کنید

    {
        "SETTINGS": {
                "APPLICATION_CONFIG": {
                        "SETTINGS_TITLE_TEXT": "Settings",
                        "SETTINGS_PACKAGE": "com.android.car.settings",
                        "SETTINGS_RRO_PACKAGE": "com.android.car.settings.googlecarui.rro",
                        "OPEN_SETTINGS_COMMAND": "am start -a android.settings.SETTINGS",
                        "OPEN_QUICK_SETTINGS_COMMAND": "am start -n com.android.car.settings/com.android.car.settings.common.CarSettingActivity"
                },
                "QUICK_SETTINGS": {
                        "OPEN_MORE_SETTINGS": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "toolbar_menu_item_1",
                                "PACKAGE": "com.android.car.settings"
                        },
                        "NIGHT_MODE": {
                                "TYPE": "TEXT",
                                "VALUE": "Night mode"
                        }
                },
                "DISPLAY": {
                        "PATH": "Settings > Display",
                        "OPTIONS": [
                                "Brightness level"
                        ],
                        "BRIGHTNESS_LEVEL": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "seekbar",
                                "PACKAGE": "com.android.car.settings"
                        }
                },
                "SOUND": {
                        "PATH": "Settings > Sound",
                        "OPTIONS": [
                                "Media volume",
                                "Alarm volume"
                        ]
                },
                "NETWORK_AND_INTERNET": {
                        "PATH": "Settings > Network & internet",
                        "OPTIONS": [
                        ],
                        "TOGGLE_WIFI": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "master_switch",
                                "PACKAGE": "com.android.car.settings"
                        }
                },
                "BLUETOOTH": {
                        "PATH": "Settings > Bluetooth",
                        "OPTIONS": [
                        ],
                        "TOGGLE_BLUETOOTH": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "car_ui_toolbar_menu_item_switch",
                                "PACKAGE": "com.android.car.settings"
                        }
                },
                "APPS_AND_NOTIFICATIONS": {
                        "PATH": "Settings > Apps & notifications",
                        "OPTIONS": [
                        ],
                        "SHOW_ALL_APPS": {
                                "TYPE": "TEXT",
                                "VALUE": "Show all apps"
                        },
                        "ENABLE_DISABLE_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "car_ui_toolbar_menu_item_text",
                                "PACKAGE": "com.android.car.settings"
                        },
                        "DISABLE_BUTTON_TEXT": {
                                "TYPE": "TEXT",
                                "VALUE": "Disable"
                        },
                        "ENABLE_BUTTON_TEXT": {
                                "TYPE": "TEXT",
                                "VALUE": "Enable"
                        },
                        "DISABLE_APP_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "DISABLE APP"
                        },
                        "FORCE_STOP_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Force stop"
                        },
                        "OK_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "OK"
                        },
                        "PERMISSIONS_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "Permissions"
                        },
                        "ALLOW_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Allow"
                        },
                        "DENY_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Deny"
                        },
                        "DENY_ANYWAY_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Deny anyway"
                        }
                },
                "DATE_AND_TIME": {
                        "PATH": "Settings > Date & time",
                        "OPTIONS": [
                                "Automatic date & time",
                "Automatic time zone"
                        ],
                        "AUTOMATIC_DATE_AND_TIME": {
                                "TYPE": "TEXT",
                                "VALUE": "Automatic date & time"
                        },
                        "AUTOMATIC_TIME_ZONE": {
                                "TYPE": "TEXT",
                                "VALUE": "Automatic time zone"
                        },
                        "SET_DATE": {
                                "TYPE": "TEXT",
                                "VALUE": "Set date"
                        },
                        "SET_TIME": {
                                "TYPE": "TEXT",
                                "VALUE": "Set time"
                        },
                        "SELECT_TIME_ZONE": {
                                "TYPE": "TEXT",
                                "VALUE": "Select time zone"
                        },
                        "USE_24_HOUR_FORMAT": {
                                "TYPE": "TEXT",
                                "VALUE": "Use 24-hour format"
                        },
                        "OK_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "toolbar_menu_item_0",
                                "PACKAGE": "com.android.car.settings"
                        },
                        "NUMBER_PICKER_WIDGET": {
                                "TYPE": "CLASS",
                                "VALUE": "android.widget.NumberPicker"
                        },
                        "EDIT_TEXT_WIDGET": {
                                "TYPE": "CLASS",
                                "VALUE": "android.widget.EditText"
                        }
                },
                "USERS": {
                        "PATH": "Settings > Users",
                        "OPTIONS": [
                                "Guest"
                        ]
                },
                "ACCOUNTS": {
                        "PATH": "Settings > Accounts",
                        "OPTIONS": [
                                "Automatically sync data"
                        ],
                        "ADD_ACCOUNT": {
                                "TYPE": "TEXT",
                                "VALUE": "ADD ACCOUNT"
                        },
                        "ADD_GOOGLE_ACCOUNT": {
                                "TYPE": "TEXT",
                                "VALUE": "Google"
                        },
                        "SIGN_IN_ON_CAR_SCREEN": {
                                "TYPE": "TEXT",
                                "VALUE": "Sign in on car screen"
                        },
                        "GOOGLE_SIGN_IN_SCREEN": {
                                "TYPE": "TEXT",
                                "VALUE": "Sign in to your Google Account"
                        },
                        "ENTER_EMAIL": {
                                "TYPE": "CLASS",
                                "VALUE": "android.widget.EditText"
                        },
                        "ENTER_PASSWORD": {
                                "TYPE": "CLASS",
                                "VALUE": "android.widget.EditText"
                        },
                        "NEXT_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Next"
                        },
                        "DONE_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Done"
                        },
                        "REMOVE_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Remove"
                        },
                        "REMOVE_ACCOUNT_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Remove Account"
                        }
                },
                "SYSTEM": {
                        "PATH": "Settings > System",
                        "OPTIONS": [
                                "About", "Legal information"
                        ],
                        "ABOUT_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "About"
                        },
                        "RESET_OPTIONS_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "Reset options"
                        },
                        "LANGUAGES_AND_INPUT_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "Languages & input"
                        },
                        "DEVICE_MODEL": {
                                "TYPE": "TEXT",
                                "VALUE": "Model"
                        },
                        "ANDROID_VERSION": {
                                "TYPE": "TEXT",
                                "VALUE": "Android version"
                        },
                        "ANDROID_SECURITY_PATCH_LEVEL": {
                                "TYPE": "TEXT",
                                "VALUE": "Android security patch level"
                        },
                        "KERNEL_VERSION": {
                                "TYPE": "TEXT",
                                "VALUE": "Kernel version"
                        },
                        "BUILD_NUMBER": {
                                "TYPE": "TEXT",
                                "VALUE": "Build number"
                        },
                        "RECYCLER_VIEW_WIDGET": {
                                "TYPE": "CLASS",
                                "VALUE": "androidx.recyclerview.widget.RecyclerView"
                        },
                        "RESET_NETWORK": {
                                "TYPE": "TEXT",
                                "VALUE": "Reset network"
                        },
                        "RESET_SETTINGS": {
                                "TYPE": "TEXT",
                                "VALUE": "RESET SETTINGS"
                        },
                        "RESET_APP_PREFERENCES": {
                                "TYPE": "TEXT",
                                "VALUE": "Reset app preferences"
                        },
                        "RESET_APPS": {
                                "TYPE": "TEXT",
                                "VALUE": "RESET APPS"
                        },
                        "LANGUAGES_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "Languages"
                        },
                        "LANGUAGES_MENU_IN_SELECTED_LANGUAGE": {
                                "TYPE": "TEXT",
                                "VALUE": "Idiomas"
                        }
                },
                "SECURITY": {
                        "PATH": "Settings > Security",
                        "OPTIONS": [
                        ],
                        "TITLE": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "car_ui_toolbar_title",
                                "PACKAGE": "com.android.car.settings.googlecarui.rro"
                        },
                        "CHOOSE_LOCK_TYPE": {
                                "TYPE": "TEXT",
                                "VALUE": "Choose a lock type"
                        },
                        "LOCK_TYPE_PASSWORD": {
                                "TYPE": "TEXT",
                                "VALUE": "Password"
                        },
                        "LOCK_TYPE_PIN": {
                                "TYPE": "TEXT",
                                "VALUE": "PIN"
                        },
                        "LOCK_TYPE_NONE": {
                                "TYPE": "TEXT",
                                "VALUE": "None"
                        },
                        "CONTINUE_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Continue"
                        },
                        "CONFIRM_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Confirm"
                        },
                        "ENTER_PASSWORD": {
                                "TYPE": "CLASS",
                                "VALUE": "android.widget.EditText"
                        },
                        "PIN_PAD": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "pin_pad",
                                "PACKAGE": "com.android.car.settings"
                        },
                        "ENTER_PIN_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "key_enter",
                                "PACKAGE": "com.android.car.settings"
                        },
                        "REMOVE_BUTTON": {
                                "TYPE": "TEXT",
                                "VALUE": "Remove"
                        }
                }
        },
        "PHONE": {
                "APPLICATION_CONFIG": {
                        "DIAL_PACKAGE": "com.android.car.dialer",
                        "PHONE_ACTIVITY": "com.android.car.dialer/.ui.TelecomActivity",
                        "OPEN_DIAL_PAD_COMMAND": "am start -a android.intent.action.DIAL"
                },
                "IN_CALL_VIEW": {
                        "DIALED_CONTACT_TITLE": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "user_profile_title",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "DIALED_CONTACT_NUMBER": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "user_profile_phone_number",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "END_CALL": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "end_call_button",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "MUTE_CALL": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "mute_button",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "SWITCH_TO_DIAL_PAD": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "toggle_dialpad_button",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "CHANGE_VOICE_CHANNEL": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "voice_channel_view",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "VOICE_CHANNEL_CAR": {
                                "TYPE": "TEXT",
                                "VALUE": "Car speakers"
                        },
                        "VOICE_CHANNEL_PHONE": {
                                "TYPE": "TEXT",
                                "VALUE": "Phone"
                        }
                },
                "DIAL_PAD_VIEW": {
                        "DIAL_PAD_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "Dial Pad"
                        },
                        "DIAL_PAD_FRAGMENT": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "dialpad_fragment",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "DIALED_NUMBER": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "title",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "MAKE_CALL": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "call_button",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "DELETE_NUMBER": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "delete_button",
                                "PACKAGE": "com.android.car.dialer"
                        }
                },
                "CONTACTS_VIEW": {
                        "CONTACTS_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "Contacts"
                        },
                        "CONTACT_INFO": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "call_action_id",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "CONTACT_NAME": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "title",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "CONTACT_DETAIL": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "show_contact_detail_id",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "ADD_CONTACT_TO_FAVORITE": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "contact_details_favorite_button",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "SEARCH_CONTACT": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "menu_item_search",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "CONTACT_SEARCH_BAR": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "car_ui_toolbar_search_bar",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "SEARCH_RESULT": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "contact_name",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "CONTACT_SETTINGS": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "menu_item_setting",
                                "PACKAGE": "com.android.car.dialer"
                        },
                        "CONTACT_ORDER": {
                                "TYPE": "TEXT",
                                "VALUE": "Contact order"
                        },
                        "SORT_BY_FIRST_NAME": {
                                "TYPE": "TEXT",
                                "VALUE": "First name"
                        },
                        "SORT_BY_LAST_NAME": {
                                "TYPE": "TEXT",
                                "VALUE": "Last Name"
                        },
                        "CONTACT_TYPE_WORK": {
                                "TYPE": "TEXT",
                                "VALUE": "Work"
                        },
                        "CONTACT_TYPE_MOBILE": {
                                "TYPE": "TEXT",
                                "VALUE": "Mobile"
                        },
                        "CONTACT_TYPE_HOME": {
                                "TYPE": "TEXT",
                                "VALUE": "Home"
                        }
                },
                "CALL_HISTORY_VIEW": {
                        "CALL_HISTORY_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "Recents"
                        },
                        "CALL_HISTORY_INFO": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "call_action_id",
                                "PACKAGE": "com.android.car.dialer"
                        }
                },
                "FAVORITES_VIEW": {
                        "FAVORITES_MENU": {
                                "TYPE": "TEXT",
                                "VALUE": "Favorites"
                        }
                }
        },
        "NOTIFICATIONS": {
                "APPLICATION_CONFIG": {
                        "OPEN_NOTIFICATIONS_COMMAND": "service call statusbar 1"
                },
                "EXPANDED_NOTIFICATIONS_SCREEN": {
                        "NOTIFICATION_VIEW": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "notification_view",
                                "PACKAGE": "com.android.systemui"
                        },
                        "CLEAR_ALL_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "clear_all_button",
                                "PACKAGE": "com.android.systemui"
                        },
                        "STATUS_BAR": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "car_top_navigation_bar_container",
                                "PACKAGE": "com.android.systemui"
                        },
                        "APP_ICON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "app_icon",
                                "PACKAGE": "com.android.systemui"
                        },
                        "APP_NAME": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "header_text",
                                "PACKAGE": "com.android.systemui"
                        },
                        "NOTIFICATION_TITLE": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "notification_body_title",
                                "PACKAGE": "com.android.systemui"
                        },
                        "NOTIFICATION_BODY": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "notification_body_content",
                                "PACKAGE": "com.android.systemui"
                        },
                        "CARD_VIEW": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "card_view",
                                "PACKAGE": "com.android.systemui"
                        }
                }
        },
        "MEDIA_CENTER": {
                "APPLICATION_CONFIG": {
                        "MEDIA_CENTER_PACKAGE": "com.android.car.media",
                        "MEDIA_ACTIVITY": "com.android.bluetooth/com.android.bluetooth.avrcpcontroller.BluetoothMediaBrowserService"
                },
                "MEDIA_CENTER_SCREEN": {
                        "PLAY_PAUSE_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "play_pause_stop",
                                "PACKAGE": "com.android.car.media"
                        },
                        "NEXT_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "skip_next",
                                "PACKAGE": "com.android.car.media"
                        },
                        "PREVIOUS_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "skip_prev",
                                "PACKAGE": "com.android.car.media"
                        },
                        "SHUFFLE_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "overflow_on",
                                "PACKAGE": "com.android.car.media"
                        },
                        "PLAY_QUEUE_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "play_queue",
                                "PACKAGE": "com.android.car.media"
                        },
                        "MINIMIZED_MEDIA_CONTROLS": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "minimized_playback_controls",
                                "PACKAGE": "com.android.car.media"
                        },
                        "TRACK_NAME": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "title",
                                "PACKAGE": "com.android.car.media"
                        },
                        "TRACK_NAME_MINIMIZED_CONTROL": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "minimized_control_bar_title",
                                "PACKAGE": "com.android.car.media"
                        },
                        "BACK_BUTTON": {
                                "TYPE": "DESCRIPTION",
                                "VALUE": "Back"
                        }
                },
                "MEDIA_CENTER_ON_HOME_SCREEN": {
                        "PLAY_PAUSE_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "play_pause_stop",
                                "PACKAGE": "com.android.car.carlauncher"
                        },
                        "NEXT_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "skip_next",
                                "PACKAGE": "com.android.car.carlauncher"
                        },
                        "PREVIOUS_BUTTON": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "skip_prev",
                                "PACKAGE": "com.android.car.carlauncher"
                        },
                        "TRACK_NAME": {
                                "TYPE": "RESOURCE_ID",
                                "VALUE": "title",
                                "PACKAGE": "com.android.car.carlauncher"
                        }
                }
        }
}
  

تنظیمات دستگاه جایگزین

نمونه کد زیر نمونه‌ای از فایل پیکربندی JSON را نشان می‌دهد که در آن تنظیمات پیش‌فرض توسط تنظیمات DUT لغو می‌شوند. در این مثال:

  • تنظیمات اینترنت شبکه و اینترنت در دستگاه های مرجع و اتصال در DUT نامیده می شوند.

  • تنظیمات تاریخ و زمان در Settings > Date and time برای دستگاه های مرجع و در Settings > System > Date and time برای DUT در دسترس هستند.

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

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

هنگامی که فایل پیکربندی JSON آماده است، همانطور که در بلوک کد زیر نشان داده شده است، در زمان اجرا ارائه می شود:

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

در این دستور:

  • DEVICE-SERIAL : شناسه سریال DUT. اگر فقط یک دستگاه به میزبان متصل باشد، این پارامتر مورد نیاز نیست.

  • PATH-TO-JSON-FILE : مسیر فایل JSON در دستگاه میزبان.

فرمت پیکربندی

پنج شی سطح بالا در پیکربندی وجود دارد، با کلیدها و مقادیر زیر:

شیء توضیحات
PACKAGES یک شی که بسته اصلی را برای برنامه های مختلف توصیف می کند، که برای تعیین زمانی که آن برنامه در پیش زمینه است استفاده می شود.
ACTIONS یک شی که انواع و پارامترهای عملکرد را برای اقدامات مختلف نشان می دهد. به عنوان مثال، اینکه آیا از دکمه ها استفاده کنید یا از یک حرکت برای پیمایش.
COMMANDS شی ای که دستوراتی را مشخص می کند که اعمال مختلفی را انجام می دهد.
UI_ELEMENTS شیء مورد استفاده برای ساخت UI Automator «BySelectors» که عناصر UI را انتخاب می کند (در جزئیات در زیر توضیح داده شده است).
WORKFLOWS دنباله ای از اقداماتی که وظایف سطح بالا را انجام می دهند (به تفصیل در زیر توضیح داده شده است).

عناصر رابط کاربری

هر عنصر UI دارای TYPE است که مشخص می کند UI Automator برای شناسایی عنصر (مانند شناسه منبع، متن و توضیحات) و مقادیر پیکربندی مرتبط با آن نوع به دنبال چه چیزی خواهد بود. به طور کلی، هر زمان که یک کمک کننده با استفاده از این پیکربندی، عنصری را روی صفحه شناسایی کند، دقیقاً یک عنصر را دریافت می کند. اگر چندین عنصر با پیکربندی مطابقت داشته باشند، یک عنصر دلخواه در آزمایش استفاده می شود. بنابراین، پیکربندی باید (به طور کلی) به طور خاص به اندازه کافی نوشته شود که به یک عنصر در زمینه مربوطه محدود شود.

TEXT

این ساده ترین نوع عنصر رابط کاربری است. عنصر UI با متن آن مشخص می شود و به تطابق دقیق نیاز دارد.

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

TEXT_CONTAINS

مانند TEXT ، با این تفاوت که VALUE مشخص شده فقط باید در جایی از متن عنصر برای مطابقت ظاهر شود.

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

توضیحات

عنصر را با ویژگی توصیف محتوای آن شناسایی کنید، که به تطابق دقیق نیاز دارد.

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

RESOURCE_ID

عنصر را با شناسه منبع آن شناسایی کنید، همچنین به صورت اختیاری جزء بسته آن شناسه را نیز بررسی کنید. کلید PACKAGE اختیاری است. اگر حذف شود، هر بسته با هم مطابقت دارد و تنها بخشی از شناسه زیر :id/ در نظر گرفته خواهد شد.

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

قابل کلیک، قابل پیمایش

عنصر را بر اساس قابل کلیک یا پیمایش بودن (یا غیر) شناسایی کنید. اینها انواع عناصر بسیار گسترده هستند و معمولاً باید فقط در یک MULTIPLE برای کمک به محدود کردن نوع عنصر دیگر استفاده شوند. کلید FLAG اختیاری است و به طور پیش فرض روی true است.

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

کلاس

عنصر را بر اساس کلاس آن شناسایی کنید.

    "SECURITY_SETTINGS_ENTER_PASSWORD": {
      "TYPE": "CLASS",
      "VALUE": "android.widget.EditText"
    }

دارای اجداد

با جستجوی سلسله مراتب ویجت در اجداد آن، عنصر را شناسایی کنید. کلید ANCESTOR یک شی را نگه می دارد که جد را مشخص می کند. کلید DEPTH مشخص می کند که سلسله مراتب تا چه اندازه باید به نظر برسد. DEPTH اختیاری است و مقدار پیش فرض آن 1 است.

      "SAMPLE_ELEMENT": {
      "TYPE": "HAS_ANCESTOR",
      "DEPTH": 2,
      "ANCESTOR": {
        "TYPE": "CLASS",
        "VALUE": "android.view.ViewGroup"
      }
    }

HAS_DESCENDANT

با نگاه کردن به سلسله مراتب به فرزندان آن عنصر را شناسایی کنید. کلید DESCENDANT یک شی را نگه می دارد که کودک را مشخص می کند که به دنبال آن باشد. کلید DEPTH مشخص می کند که سلسله مراتب تا چه اندازه باید به نظر برسد. DEPTH اختیاری است و مقدار پیش فرض آن 1 است.

      "SAMPLE_ELEMENT": {
      "TYPE": "HAS_DESCENDANT",
      "DEPTH": 2,
      "DESCENDANT": {
        "TYPE": "CLASS",
        "VALUE": "android.view.ViewGroup"
      }
    }

چندگانه

عنصر را بر اساس چند شرط همزمان که همه آنها باید برآورده شوند، شناسایی کنید.

      "APP_INFO_SETTINGS_PERMISSION_MANAGER": {
      "TYPE": "MULTIPLE",
      "SPECIFIERS": [
        {
          "TYPE": "CLASS",
          "VALUE": "android.widget.RelativeLayout"
        },
        {
          "TYPE": "HAS_DESCENDANT",
          "MAX_DEPTH": 2,
          "DESCENDANT": {
            "TYPE": "TEXT",
            "VALUE": "Permission manager"
          }
        }
      ]
    }

در این مثال، پیکربندی یک RelativeLayout را شناسایی می‌کند که دارای یک نسل در عمق 2 است که دارای متن Permission manager است.

گردش کار

گردش کار مجموعه ای از اقدامات مورد استفاده برای انجام یک کار خاص را نشان می دهد که ممکن است از نوع دستگاه به نوع دستگاه دیگر به اندازه کافی متفاوت باشد و برای نمایش در پیکربندی نسبت به کد انعطاف پذیرتر است.

    "WORKFLOWS": {
    "OPEN_SOUND_SETTINGS_WORKFLOW": [
      {
        "NAME": "Go to Home",
        "TYPE": "PRESS",
        "CONFIG": {
          "TEXT": "HOME"
        }
      },
      {
        "NAME": "Open Settings",
        "TYPE": "COMMAND",
        "CONFIG": {
          "TEXT": "am start -a android.settings.SETTINGS"
        }
      },
      {
        "NAME": "Open Sound Settings",
        "TYPE": "SCROLL_TO_FIND_AND_CLICK",
        "CONFIG": {
          "UI_ELEMENT": {
            "TYPE": "TEXT",
            "VALUE": "Sound"
          }
        },
        "SCROLL_CONFIG": {
          "SCROLL_ACTION": "USE_GESTURE",
          "SCROLL_DIRECTION": "VERTICAL",
          "SCROLL_ELEMENT": {
            "TYPE": "RESOURCE_ID",
            "VALUE": "car_ui_recycler_view"
          }
        }
      }
    ]
  }

هر گردش کار یک جفت کلید-مقدار است که کلید آن نام گردش کار و مقدار آرایه ای از اقدامات برای انجام است. هر کنش دارای یک NAME ، یک TYPE ، (معمولا) یک CONFIG و (گاهی) یک SWIPE_CONFIG یا SCROLL_CONFIG است. برای اکثر TYPE ها، CONFIG یک شی با یک کلید UI_ELEMENT است که مقدار آن به شکل ورودی عنصر UI است (به بالا مراجعه کنید). آن انواع عبارتند از:

را فشار دهید
LONG_PRESS
کلیک کنید
LONG_CLICK
CLICK_IF_EXIST
HAS_UI_ELEMENT_IN_FOREGROUND
SCROLL_TO_FIND_AND_CLICK
SCROLL_TO_FIND_AND_CLICK_IF_EXIST
SWIPE_TO_FIND_AND_CLICK
SWIPE_TO_FIND_AND_CLICK_IF_EXIST

برای انواع دیگر، جزئیات پیکربندی عبارتند از:

شیء توضیحات
COMMAND یک شی با مقدار TEXT حاوی دستور اجرا.
HAS_PACKAGE_IN_FOREGROUND یک شی با مقدار TEXT حاوی بسته.
SWIPE CONFIG key را برای یک عمل SWIPE حذف کنید. این فقط از SWIPE_CONFIG استفاده می کند
WAIT_MS یک شی با مقدار TEXT حاوی تعداد میلی ثانیه برای انتظار.

اقدامات مربوط به اسکرول و کشیدن انگشت به پیکربندی اضافی نیاز دارند، به شرح زیر:

SCROLL_CONFIG

شیء توضیحات
SCROLL_ACTION USE_GESTURE یا USE_BUTTON
SCROLL_DIRECTION HORIZONTAL یا VERTICAL
SCROLL_ELEMENT یک شی که نشان می دهد ظرف برای پیمایش، با استفاده از همان فرم پیکربندی عنصر UI (به بالا مراجعه کنید).
SCROLL_FORWARD ، SCROLL_BACKWARD دکمه‌های اسکرول رو به جلو و عقب (در زمانی که SCROLL_ACTION USE_BUTTON باشد ضروری است).
SCROLL_MARGIN اگر SCROLL_ACTION USE_GESTURE باشد، فاصله از لبه ظرف برای شروع و توقف کشیدنی که برای انجام اسکرول استفاده می‌شود ( اختیاری، پیش‌فرض = 10).
SCROLL_WAIT_TIME اگر SCROLL_ACTION USE_GESTURE باشد، زمان انتظار بین حرکات اسکرول هنگام جستجوی شیئی برای کلیک کردن بر حسب میلی ثانیه است. ( اختیاری، پیش فرض = 1).

SWIPE_CONFIG

شیء توضیحات
SWIPE_DIRECTION TOP_TO_BOTTOM ، BOTTOM_TO_TOP ، LEFT_TO_RIGHT ، یا RIGHT_TO_LEFT
SWIPE_FRACTION

یکی از موارد زیر:

  • FULL : حرکت اشاره را از لبه صفحه به لبه صفحه بکشید

    یا،
  • DEFAULT : لبه به لبه صفحه، با یک بافر پنج (5) پیکسل در هر طرف.

    یا،
  • THREE_QUARTER ، HALF ، یا QUARTER : حرکت انگشت پنج (5) پیکسل را از لبه صفحه به پایان می‌رساند و از نقطه‌ای شروع می‌شود که فاصله مشخص‌شده صفحه را پوشش می‌دهد.
NUMBER_OF_STEPS تعداد مراحلی که باید برای انجام کشیدن انگشت استفاده شود. segmentSteps ببینید.

بسازید و اجرا کنید

چارچوب Spectatio به طور خودکار به عنوان بخشی از APK آزمایشی ساخته می شود. برای ساختن APK آزمایشی، پایگاه کد AOSP باید در ایستگاه کاری محلی باشد. پس از ساخت APK آزمایشی، کاربر باید APK را روی دستگاه نصب کرده و آزمایش را انجام دهد.

نمونه کد زیر ساخت، نصب و اجرای یک APK آزمایشی را نشان می دهد.

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

در این دستورات:

  • TEST-APK-NAME : نام برنامه ای که باید آزمایش شود. به عنوان مثال، TEST-APK-NAME روی AndroidAutomotiveSettingsTests تنظیم کنید تا تنظیمات Wi-Fi را همانطور که در فایل Android.bp مشخص شده است آزمایش کنید. نام APK را می‌توانید در فایل Android.bp مربوطه برای تست Automotive پیدا کنید.

  • DEVICE-SERIAL : شناسه سریال DUT. اگر فقط یک دستگاه به هاست متصل باشد، این پارامتر مورد نیاز نیست.

  • config-file-path : پارامتر اختیاری که فقط برای ارائه تنظیمات رابط کاربری غیر پیش‌فرض دستگاه همانطور که در فایل پیکربندی JSON مشخص شده است، مورد نیاز است. در صورت عدم ارائه، چارچوب از مقادیر پیش فرض برای اجرای تست ها استفاده می کند.

  • PATH-FOR-BUILT-TEST-APK : مسیری که در آن APK آزمایشی هنگام اجرای دستور make ساخته می شود.

  • TEST-PACKAGE : نام بسته آزمایشی.

  • TEST-CLASSNAME : نام کلاس آزمایشی. به عنوان مثال، برای تست تنظیمات Wifi ، بسته آزمایشی android.platform.tests و نام کلاس تست WifiSettingTest است.

کتابخانه قطعه خودرو

Automotive Snippet Library مجموعه ای از کتابخانه های تست اندروید برای پروژه متن باز اندروید (AOSP) است که برای تعامل با برنامه ها و سرویس های خودرو طراحی شده است. این دستگاه از Spectatio با مکانیزمی مناسب برای اجرای تماس‌های رویه از راه دور (RPC) از یک دستگاه میزبان (تست) به یک دستگاه مجهز به اندروید بهره می‌برد.

شروع کنید

قبل از شروع، این بخش ها را مرور کنید.

پیش نیازها

  • پایتون 3.x روی دستگاه میزبان نصب شده است.
  • راه اندازی محیط AOSP با ابزارهای ساخت لازم.
  • یک دستگاه خودروی اندروید (شبیه ساز یا دستگاه فیزیکی) با دسترسی adb.

تالیف

برای کامپایل قطعه های مختلف ارائه شده توسط Automotive Snippet Library، می توانید از فایل android.bp ارائه شده استفاده کنید. دستورات بخش قبل را برای کامپایل APK دنبال کنید.

استقرار

پس از کامپایل موفقیت آمیز کتابخانه های قطعه، APK های حاصل را با استفاده از دستور adb install که در بخش قبل ذکر شد، در دستگاه مورد نظر مستقر کنید.

تست ها را اجرا کنید

کتابخانه های قطعه چندین روش RPC را برای تعامل با سیستم خودرو در معرض دید قرار می دهند. این روش ها را می توان از طریق چارچوب Mobly از ماشین میزبان فراخوانی کرد. با فرض اینکه محیط تست Mobly را تنظیم کرده اید، می توانید از اسکریپت snippet_shell.py برای باز کردن یک پوسته تعاملی پایتون استفاده کنید، جایی که می توانید به صورت دستی روش های RPC را در دستگاه فراخوانی کنید. فراخوانی مثال:

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

شماره سریال دستگاه را جایگزین <serial> کنید، که در صورت اتصال چندین دستگاه می توانید آن را با دستگاه های adb بدست آورید.

شامل کتابخانه ها

کتابخانه قطعه خودرو شامل کتابخانه‌ها و راهنماهای قطعه زیر است:

  • AutomotiveSnippet: API های مربوط به عملیات خودرو، مانند شماره گیری، کنترل صدا، کلیدهای سخت خودرو و تعامل با مرکز رسانه را ارائه می دهد.

  • PhoneSnippet: API های مربوط به تلفن، از جمله مدیریت تماس، مرور مخاطبین و عملیات پیام کوتاه را ارائه می دهد.

قطعه Automotive و PhoneSnippet منطق مشترکی دارند. به طور خاص، می‌توانید به تماس‌های RCP مرتبط با بلوتوث برای جفت کردن یک خودرو و یک دستگاه تلفن حمله کنید. این bt_discovery_test نشان می دهد که چگونه.