Spectatio: إطار عمل اختبار السيارات

Spectatio هو إطار عمل اختباري مفتوح المصدر تم تطويره لاختبار نظام التشغيل Android Automotive (AAOS) على الأجهزة الحقيقية والافتراضية. توفّر Spectatio واجهات برمجة تطبيقات لاختبار التطبيقات على جهاز سيارة، وهي حلّ قابل للتوسيع والتطوير ويُستخدَم للتحقّق من قدرة نظام التشغيل AAOS وتطبيقاته وأداءها.

التصميم العالي المستوى

إطار عمل Spectatio قابل للتكيّف والتوسيع لتنفيذات مختلفة لواجهة مستخدم AAOS. ويُستخدَم لاختبار قدرات نظام التشغيل AAOS على أجهزة الأجهزة والمحاكيات والبيئات الافتراضية.

يوضّح الشكل التالي التصميم العام لإطار عمل Spectatio.

التصميم العام لإطار عمل Spectatio

الشكل 1: تصميم عالي المستوى لإطار عمل Spectatio

يستند إطار عمل Spectatio إلى UI Automator، ويقدّم مجموعة من واجهات برمجة التطبيقات لإنشاء اختبارات واجهة المستخدم التي تتفاعل مع تطبيقات المستخدم والنظام على نظام التشغيل AAOS. تستخدم اختبارات السيارات واجهات برمجة التطبيقات التي يوفّرها إطار عمل Spectatio للاختبار، ما يجعل هذه الاختبارات مستقلة عن الجهاز قيد الاختبار (DUT) وقابلة للتطوير لاختبار الأجهزة المتنوعة، إذا كان ذلك متاحًا.

يوضّح الشكل 1 أنّ إطار عمل Spectatio ينقسم إلى وحدات استنادًا إلى تطبيقات مرجعية، مثل Dialer وMedicenter و"الإعدادات" باستخدام واجهات وأدوات مساعدة خاصة بالتطبيقات، ما يجعله قابلاً للتوسّع بسهولة للتطبيقات الجديدة. يعيد إطار عمل Spectatio استخدام فئات مساعدي المعايير والفوائد الشائعة. فئة المساعدة العادية هي الفئة الرئيسية لجميع دوال مساعد التطبيقات وتوفر الوظائف العادية الخاصة بالجهاز أو التي تنطبق على جميع التطبيقات. توفّر فئات الخدمات المساعدة برامج خدمات مثل قراءة الملفات أو كتابتها من الجهاز.

هندسة معمارية

لتوفير مجموعة من واجهات برمجة التطبيقات لإنشاء اختبارات واجهة المستخدم، ينفِّذ إطار عمل Spectatio واجهات ومساعِدين خاصّين بالتطبيق مع توسيع نطاق فئة المساعِد العادية الحالية واستيراد فئات المساعِدين في الأداة.

يوضّح الشكل 2 البنية الأساسية العالية المستوى لإطار عمل Spectatio وجميع الكيانات المشارِكة في تنفيذ واجهات برمجة التطبيقات لاختبار أحد التطبيقات.

بنية Spectatio الإطارية العالية المستوى

الشكل 2. إطار Spectatio بنية عالية المستوى

توفّر واجهة مساعد التطبيق مخططًا لتنفيذ أحد تطبيقات المساعد. ويتألف من دوال مساعدة مختلفة مطلوبة لاختبار التطبيقات. ولكل تطبيق واجهته الخاصة، مثل IAutoSettingHelper وIAutoDialHelper. لمزيد من المعلومات وقائمة بوظائف الواجهة، يُرجى الاطّلاع على وظائف واجهة مساعد التطبيق في AOSP.

تتألف فئة المساعد العادي من سمات ودوال عادية مطلوبة لإعداد الجهاز ولكنها ليست خاصة بأي تطبيق، مثل pressHome وscroll. يتم تحديد فئة المساعد العادية في AbstractAutoStandardAppHelper.java.

يستخدِم إطار العمل فئات الخدمات المساعدة. على سبيل المثال، AutoJsonUtility.java هي فئة أداة تحمّل ملف إعدادات JSON للجهاز المحدّد وتُعدِّل إعدادات إطار العمل أثناء التشغيل.

تشكّل وحدة تنفيذ مساعدة التطبيق جوهر إطار عمل Spectatio. يحتوي على تنفيذ وظائف المساعِد المحدّدة في واجهة مساعِد التطبيق، وهي مطلوبة لاختبار التطبيقات على جهاز Automotive. ولكل تطبيق طريقة تنفيذ خاصة به، مثل SettingHelperImpl و DialHelperImpl، التي تستخدمها اختبارات Automotive لاختبار التطبيقات. لمزيد من المعلومات وقائمة بالعمليات التي تم تنفيذها، يُرجى الاطّلاع على وظائف تنفيذ تطبيقات المساعِد على AOSP.

تستخدِم اختبارات السيارات وظائف تنفيذ مساعِد التطبيق لاختبار العمليات المختلفة المرتبطة بالتطبيق. استخدِم فئة 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 أثناء التشغيل لضبط التغييرات المطلوبة في واجهة المستخدم للجهاز. يتيحملف الإعدادات بتنسيق JSON عناصر واجهة المستخدم، مثل TEXT وDESCRIPTION و RESOURCE_ID، بالإضافة إلى إعدادات path، ويجب أن يحتوي فقط على معلومات حول تغييرات واجهة المستخدم لوحدة التحكّم بالجهاز. تستخدِم بقية عناصر واجهة المستخدم قيم الإعدادات التلقائية المُقدَّمة في إطار العمل.

إعدادات الجهاز التلقائية

يعرض نموذج ملف الإعدادات بتنسيق 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.

  • تتوفر إعدادات التاريخ والوقت في الإعدادات > التاريخ والوقت للأجهزة المرجعية وفي الإعدادات > النظام > التاريخ والوقت الخاصة بـ 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 تمثّل هذه السمة كائنًا يُستخدَم لإنشاء "BySelectors" في UI Automator ويختار عناصر واجهة المستخدم (الموضّحة بالتفصيل أدناه).
WORKFLOWS تسلسلات الإجراءات التي تُنفِّذ مهامًا رفيعة المستوى (موضَّحة بالتفصيل أدناه)

عناصر واجهة المستخدم

يحتوي كل عنصر من عناصر واجهة المستخدم على TYPE يحدّد ما سيبحث عنه UI Automator لتحديد العنصر (مثل معرّف المورد والنص والوصف) و قيم الضبط المرتبطة بهذا النوع. بشكل عام، عندما يحدد المساعد عنصرًا على الشاشة باستخدام هذه التهيئة، فإنه يحصل على عنصر واحد بالضبط. إذا تطابقت عناصر متعددة مع الإعداد، يتم استخدام عنصر عشوائي في الاختبار. لذلك، يجب أن تتم كتابة التهيئة (بشكل عام) بشكل خاص بما يكفي لتضييق نطاقها إلى عنصر واحد في السياق ذي الصلة.

النص

هذا هو أبسط أنواع عناصر واجهة المستخدم. يتم تحديد عنصر واجهة المستخدم من خلال النص الخاص به، ويتطلب تطابقًا تامًا.

    "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
    }

CLASS

حدِّد العنصر استنادًا إلى فئته.

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

HAS_ANCESTOR

حدد العنصر من خلال البحث عن التسلسل الهرمي للأداة في الكيانات الأصلية. يحتوي مفتاح 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"
      }
    }

MULTIPLE

تحديد العنصر استنادًا إلى شروط متعدّدة متزامنة، ويجب استيفاء كلّها

      "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

يمثّل سير العمل تسلسلاً من الإجراءات المستخدَمة لتنفيذ مهمة معيّنة، والتي قد تختلف اختلافًا كبيرًا من نوع جهاز إلى آخر، ويكون تمثيلها في الإعدادات أكثر سهولة من تمثيلها في الرمز البرمجي.

    "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 (في بعض الأحيان). بالنسبة إلى معظم الأنواع، يكون CONFIG عنصرًا يحتوي على مفتاح UI_ELEMENT تأخذ قيمته الشكل نفسه لقيمة إدخال عنصر واجهة المستخدم (راجِع أعلاه). هذه TYPE هي:

الضغط
الضغط مع الاستمرار
النقر
النقر مع الاستمرار
النقر إذا كان متوفّرًا
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

بالنسبة إلى القيم الأخرى لـ TYPE، تكون تفاصيل الضبط كما يلي:

عنصر الوصف
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 عنصر يشير إلى الحاوية التي يتم التمرير فيها، باستخدام النموذج نفسه لإعداد عنصر واجهة المستخدم (راجِع أعلاه).
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 المعنيّ لإجراء اختبار السيارات.

  • DEVICE-SERIAL: رقم التعريف التسلسلي لوحدة التحكّم بالتجربة لا يُشترط استخدام هذه المَعلمة إذا كان هناك جهاز واحد فقط متصل بالمضيف.

  • config-file-path: مَعلمة اختيارية مطلوبة فقط لتوفير إعدادات واجهة مستخدم الجهاز غير التلقائية كما هو محدّد في ملف إعدادات JSON. إذا لم يتم توفير إطار العمل، سيستخدم القيم التلقائية لتنفيذ الاختبارات.

  • PATH-FOR-BUILT-TEST-APK: المسار الذي يتم فيه إنشاء حزمة APK الاختبارية عند تنفيذ الأمر make

  • TEST-PACKAGE: اسم حزمة الاختبار

  • TEST-CLASSNAME: اسم فئة الاختبار. على سبيل المثال، بالنسبة إلى اختبار إعدادات Wi-Fi، تكون حزمة الاختبار هي android.platform.tests واسم صف الاختبار هو WifiSettingTest.

مكتبة المقتطفات المتعلّقة بالسيارات

مكتبة مقتطفات Automotive هي مجموعة من مكتبات اختبار Android لمشروع Android المفتوح المصدر (AOSP) المصمّمة للتفاعل مع التطبيقات والخدمات المتعلّقة بالسيارات. ويستفيد Spectatio من آلية مناسبة لتنفيذ طلبات الإجراءات عن بُعد (RPC) من جهاز مضيف (اختباري) إلى جهاز Android.

البدء

قبل البدء، راجِع هذه الأقسام.

المتطلّبات الأساسية

  • تثبيت Python 3.x على الجهاز المضيف.
  • إعداد بيئة AOSP باستخدام أدوات الإنشاء اللازمة
  • جهاز Android للسيارات (المحاكي أو الجهاز الفعلي) مع إمكانية الوصول إلى Adb

موسيقى مجمّعة

لتجميع المقتطفات المختلفة التي تقدّمها "مكتبة المقتطفات المتعلّقة بالسيارات"، يمكنك استخدام ملف android.bp المقدَّم. اتّباع الأوامر الواردة في القسم السابق لإنشاء حزمة APK

التفعيل

بعد تجميع مكتبات المقتطفات بنجاح، يمكنك نشر حِزم APK الناتجة على الجهاز المستهدَف باستخدام الأمر adb install المذكور في القسم السابق.

إجراء الاختبارات

تعرض مكتبات المقتطفات العديد من طرق RPC للتفاعل مع نظام المركبات. يمكن استدعاء هذه الطرق من خلال إطار عمل Mobly من المضيف الجهاز. بافتراض أنّك قد أعددت بيئة اختبار Mobly، يمكنك استخدام النص البرمجي snippet_shell.py لفتح بيئة Python تفاعلية، حيث يمكنك استدعاء طرق RPC يدويًا على الجهاز. مثال على طلب التنفيذ:

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

استبدِل <serial> بالرقم التسلسلي للجهاز، والذي يمكنك الحصول عليه باستخدام ملفadb devices إذا كانت هناك أجهزة متعددة متصلة.

المكتبات المضمّنة

تتضمن مكتبة مقتطفات Automotive مكتبات المقتطفات والعناصر التالية المساعدة:

  • AutomotiveSnippet: يوفّر واجهات برمجة تطبيقات ذات صلة بعمليات المركبات، مثل طلب الاتصال والتحكّم في مستوى الصوت والمفاتيح الثابتة للمركبة والتفاعل مع مركز الوسائط.

  • Phonesnippet: توفر واجهات برمجة التطبيقات المتعلقة بالاتصالات الهاتفية، بما في ذلك التعامل مع المكالمات، وتصفح جهات الاتصال، وعمليات الرسائل القصيرة SMS.

يتشارك AutomotiveSnippet وPhoneSnippet بعض المنطق الشائع. على وجه التحديد، يمكنك اختراق طلبات RCP ذات الصلة بالبلوتوث لإقران جهاز مركبة بجهاز هاتف. يوضّح لك هذا bt_discovery_test كيفية إجراء ذلك.