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

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

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

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

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

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

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

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

يوضّح الشكل 1 أنّ إطار عمل Spectatio مصنّف إلى وحدات استنادًا إلى التطبيقات المرجعية مثل Dialer وMedicenter وSettings باستخدام واجهات ومقاييس مساعدة خاصة بالتطبيق، ما يسهّل توسيع نطاقه ليشمل التطبيقات الجديدة. يعيد إطار عمل 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: رقم التعريف التسلسلي لوحدة التحكّم بالتجربة هذه المَعلمة ليست مطلوبة إذا كا�� هناك جهاز واحد فقط متصل بالمضيف.

  • 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 تأخذ قيمته الشكل نفسه لقيمة إدخال عنصر واجهة المستخدم (راجِع أعلاه). وتشمل هذه الأنواع ما يلي:

الضغط
الضغط مع الاستمرار
النقر
النقر مع الاستمرار
النقر إذا كان متوفّرًا
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 عنصر يشير إلى الحاوية التي يتم الانتقال إليها، باستخدام النموذج نفسه لإعداد عنصر واجهة المستخدم (راجِع أعلاه).
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: رقم التعريف التسلسلي لوحدة التحكّم بالتجربة لا يُشترط استخدام هذه المَعلمة إذا كان هناك جهاز واحد فقط متصل بالمضيف.

  • 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.

البدء

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

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

  • تثبيت الإصدار 3.x من لغة Python على الجهاز المضيف
  • إعداد بيئة AOSP باستخدام أدوات الإنشاء اللازمة
  • جهاز Android Automotive (محاكي أو جهاز فعلي) يتيح الوصول إلى 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 إذا كانت هناك أجهزة متعددة متصلة.

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

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

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

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

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