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

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

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

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

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

التصميم العالي المستوى لإطار عمل Spectatio

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

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

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

البنية

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

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

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

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

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

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

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

وحدة تنفيذ مساعد التطبيق هي جوهر إطار عمل Spectatio. يحتوي هذا الملف على الرمز البرمجي لوظائف المساعد المحدّدة في واجهة مساعد التطبيق، وهي مطلوبة لاختبار التطبيقات على جهاز متوافق مع السيارة. يحتوي كل تطبيق على عملية تنفيذ خاصة به، مثل SettingHelperImpl و DialHelperImpl، اللتين تستخدمهما اختبارات Automotive لاختبار التطبيقات. لمزيد من المعلومات وقائمة بعمليات التنفيذ، يُرجى الاطّلاع على وظائف تنفيذ مساعد التطبيق في مشروع Android المفتوح المصدر (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، ويجب أن يحتوي على معلومات حول تغييرات واجهة المستخدم لجهاز DUT فقط. تستخدم بقية عناصر واجهة المستخدم قيم الإعدادات التلقائية المتوفّرة في إطار العمل.

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

يوضِّح نموذج ملف إعداد 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 حيث يتم تجاهل الإعدادات التلقائية واستخدام الإعدادات على الجهاز الخاضع للاختبار. في هذا المثال:

  • يُطلق على إعدادات الإنترنت اسم الشبكة والإنترنت على الأجهزة المرجعية والاتصال على الجهاز قيد الاختبار.

  • تتوفّر إعدادات التاريخ والوقت في الإعدادات > التاريخ والوقت للأجهزة المرجعية وفي الإعدادات > النظام > التاريخ والوقت لجهاز الاختبار.

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

‫PRESS
LONG_PRESS
CLICK
LONG_CLICK
CLICK_IF_EXIST
HAS_UI_ELEMENT_IN_FOREGROUND
SCROLL_TO_FIND_AND_CLICK
SCROLL_TO_FIND_AND_CLICK_IF_EXIST
SWIPE_TO_FIND_AND_CLICK
SWIPE_TO_FIND_AND_CLICK_IF_EXIST

بالنسبة إلى أنواع 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.

البدء

قبل البدء، راجِع الأقسام التالية.

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

  • يجب أن يكون الإصدار 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 إذا كانت هناك أجهزة متعددة متصلة.

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

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

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

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

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