Spectatio: 자동차 테스트 프레임워크

Spectatio는 실제 장치와 가상 장치에서 Android Automotive OS(AAOS)를 테스트하기 위해 개발된 오픈 소스 테스트 프레임워크입니다. Spectatio는 자동차 기기에서 앱을 테스트하기 위한 API를 제공하며 AAOS와 해당 앱의 기능과 성능을 확인하는 데 사용되는 확장 가능하고 확장 가능한 솔루션입니다.

높은 수준의 디자인

Spectatio 프레임워크는 다양한 AAOS UI 구현에 맞게 조정 및 확장이 가능합니다. 기기 하드웨어, 에뮬레이터, 가상화된 환경에서 AAOS의 기능과 성능을 테스트하는 데 사용됩니다.

다음 그림은 Spectatio 프레임워크의 상위 수준 디자인을 설명합니다.

Spectatio 프레임워크 고급 디자인

그림 1. Spectatio 프레임워크 상위 수준 디자인.

UI Automator를 기반으로 구축된 Spectatio 프레임워크는 AAOS에서 사용자 및 시스템 앱과 상호작용하는 UI 테스트를 빌드하기 위한 API 세트를 제공합니다. 자동차 테스트는 테스트를 위해 Spectatio 프레임워크에서 제공하는 API를 사용하므로 이러한 테스트는 테스트 중인 장치(DUT)와 독립적이며 지원되는 경우 다양한 장치를 테스트하도록 확장 가능합니다.

그림 1은 Spectatio 프레임워크가 앱별 인터페이스와 도우미를 사용하여 Dialer, Medicenter 및 설정과 같은 참조 앱을 기반으로 모듈화되어 새로운 앱에 대해 쉽게 확장 가능하다는 것을 보여줍니다. Spectatio 프레임워크는 공통 표준 및 유틸리티 도우미 클래스를 재사용합니다. 표준 도우미 클래스는 모든 앱 도우미 기능의 상위 클래스이며 기기별로 또는 앱 전체에 적용 가능한 표준 기능을 제공합니다. 유틸리티 도우미 클래스는 장치에서 파일을 읽거나 쓰는 등의 유틸리티를 제공합니다.

건축학

UI 테스트를 구축하기 위한 API 세트를 제공하기 위해 Spectatio 프레임워크는 기존 표준 도우미 클래스를 확장하고 유틸리티 도우미 클래스를 가져오는 동시에 앱별 인터페이스와 도우미를 구현합니다.

그림 2는 Spectatio 프레임워크의 상위 수준 아키텍처와 앱 테스트를 위한 API 구현과 관련된 모든 엔터티를 보여줍니다.

Spectatio 프레임워크 상위 수준 아키텍처

그림 2. Spectatio 프레임워크 상위 수준 아키텍처.

앱 도우미 인터페이스는 앱 도우미 구현을 위한 청사진을 제공합니다. 앱 테스트에 필요한 다양한 도우미 기능으로 구성되어 있습니다. 각 앱에는 IAutoSettingHelperIAutoDialHelper 와 같은 자체 인터페이스가 있습니다. 자세한 내용과 인터페이스 기능 목록은 AOSP의 앱 도우미 인터페이스 기능을 참조하세요.

표준 도우미 클래스는 기기 설정에 필요하지만 pressHomescroll 과 같이 앱에 국한되지 않는 표준 속성과 함수로 구성됩니다. 표준 도우미 클래스는 AbstractAutoStandardAppHelper.java 에 정의되어 있습니다.

유틸리티 도우미 클래스는 프레임워크에서 사용됩니다. 예를 들어 AutoJsonUtility.java 는 지정된 장치 JSON 구성 파일을 로드하고 런타임 시 프레임워크 구성을 업데이트하는 유틸리티 클래스입니다.

앱 도우미 구현 모듈은 Spectatio 프레임워크의 핵심입니다. 여기에는 자동차 장치에서 앱을 테스트하는 데 필요한 앱 도우미 인터페이스에 정의된 도우미 기능에 대한 구현이 포함되어 있습니다. 각 앱에는 앱 테스트를 위해 자동차 테스트에서 사용되는 SettingHelperImplDialHelperImpl 과 같은 자체 구현이 있습니다. 자세한 내용과 구현 목록은 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 프레임워크는 장치 UI와 독립적이므로 다양한 UI 및 하드웨어를 사용하여 장치를 테스트하기 위해 확장 가능합니다. 이러한 확장성을 달성하기 위해 Spectatio는 참조 장치를 기반으로 하는 기본 장치 구성을 사용합니다. 기본이 아닌 장치 구성을 지원하기 위해 프레임워크는 런타임 시 JSON 구성 파일을 사용하여 장치에 대해 원하는 UI 변경 사항을 설정합니다. JSON 구성 파일은 path 설정과 함께 TEXT , DESCRIPTIONRESOURCE_ID 와 같은 UI 요소를 지원하며 DUT의 UI 변경 사항에 대한 정보만 포함해야 합니다. 나머지 UI 요소는 프레임워크에 제공된 기본 구성 값을 사용합니다.

기본 장치 구성

다음 샘플 JSON 구성 파일은 사용 가능한 장치 구성과 해당 기본값을 보여줍니다.

샘플 JSON 구성 파일을 표시하려면 여기를 클릭하세요.

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

대체 장치 구성

다음 코드 샘플은 기본 설정이 DUT의 설정으로 재정의되는 JSON 구성 파일의 예를 보여줍니다. 이 예에서는 다음과 같습니다.

  • 인터넷 설정의 이름은 참조 장치의 네트워크 및 인터넷 , 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의 일련 ID입니다. 호스트에 하나의 장치만 연결된 경우에는 이 매개변수가 필요하지 않습니다.

  • PATH-TO-JSON-FILE : 호스트 머신에 있는 JSON 파일의 경로입니다.

구성 형식

구성에는 다음 키와 값을 포함하는 5개의 최상위 개체가 있습니다.

물체 설명
PACKAGES 해당 앱이 포그라운드에 있을 때를 결정하는 데 사용되는 다양한 앱의 기본 패키지를 설명하는 개체입니다.
ACTIONS 다양한 작업에 대한 작업 유형 및 매개변수를 나타내는 개체입니다. 예를 들어 스크롤할 때 버튼이나 동작을 사용할지 여부입니다.
COMMANDS 다양한 작업을 수행하는 명령을 지정하는 개체입니다.
UI_ELEMENTS UI 요소를 선택하는 UI Automator `BySelectors`를 구성하는 데 사용되는 개체입니다(자세한 내용은 아래 설명 참조).
WORKFLOWS 높은 수준의 작업을 수행하는 일련의 작업입니다(아래에 자세히 설명되어 있음).

UI 요소

각 UI 요소에는 UI Automator가 요소(예: 리소스 ID, 텍스트, 설명)를 식별하기 위해 검색할 내용과 해당 유형과 관련된 구성 값을 지정하는 TYPE 있습니다. 일반적으로 도우미가 이 구성을 사용하여 화면의 요소를 식별할 때마다 정확히 하나의 요소를 가져옵니다. 여러 요소가 구성과 일치하는 경우 임의의 요소가 테스트에 사용됩니다. 따라서 구성은 (일반적으로) 관련 컨텍스트에서 하나의 요소로 범위를 좁힐 수 있도록 구체적으로 작성되어야 합니다.

텍스트

이는 가장 간단한 UI 요소 유형입니다. UI 요소는 텍스트로 식별되며 정확히 일치해야 합니다.

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

TEXT_CONTAINS

지정된 VALUE 일치할 요소의 텍스트 어딘가에만 나타나야 한다는 점을 제외하면 TEXT 와 동일합니다.

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

설명

정확한 일치가 필요한 콘텐츠 설명 속성으로 요소를 식별합니다.

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

RESOURCE_ID

리소스 ID로 요소를 식별하고 선택적으로 해당 ID의 패키지 구성 요소도 확인합니다. PACKAGE 키는 선택 사항입니다. 생략하면 모든 패키지가 일치하며 :id/ 다음의 ID 부분만 고려됩니다.

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

클릭 가능, 스크롤 가능

클릭 가능 또는 스크롤 가능 여부에 따라 요소를 식별합니다. 이는 매우 광범위한 요소 유형이며 일반적으로 다른 요소 유형의 범위를 좁히는 데 도움이 되는 MULTIPLE 에서만 사용해야 합니다. FLAG 키는 선택사항이며 기본값은 true 입니다.

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

수업

클래스를 기반으로 요소를 식별합니다.

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

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

다수의

모두 충족되어야 하는 여러 동시 조건을 기반으로 요소를 식별합니다.

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

이 예에서 구성은 깊이 2 에 하위 항목이 있고 Permission manager 텍스트가 있는 RelativeLayout 을 식별합니다.

워크플로우

워크플로는 특정 작업을 수행하는 데 사용되는 일련의 작업을 나타냅니다. 이는 장치 유형마다 충분히 다를 수 있으며 코드보다 구성으로 표현하는 것이 더 유연합니다.

    "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 요소 항목과 동일한 형식을 취하는 UI_ELEMENT 키가 있는 객체입니다(위 참조). 해당 유형은 다음과 같습니다.

누르다
길게 누르세요
딸깍 하는 소리
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 SWIPE 작업에는 CONFIG key 생략합니다. SWIPE_CONFIG 만 사용합니다.
WAIT_MS 대기할 시간(밀리초)이 포함된 TEXT 값이 있는 개체입니다.

스크롤 및 스와이프 관련 작업에는 다음과 같은 추가 구성이 필요합니다.

SCROLL_CONFIG

물체 설명
SCROLL_ACTION USE_GESTURE 또는 USE_BUTTON
SCROLL_DIRECTION HORIZONTAL 또는 VERTICAL
SCROLL_ELEMENT UI 요소 구성과 동일한 형식을 사용하여 스크롤할 컨테이너를 나타내는 개체입니다(위 참조).
SCROLL_FORWARD , SCROLL_BACKWARD 앞으로 및 뒤로 스크롤 버튼( SCROLL_ACTIONUSE_BUTTON 인 경우 필요)
SCROLL_MARGIN SCROLL_ACTIONUSE_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 로 설정하여 Android.bp 파일에 지정된 Wi-Fi 설정을 테스트합니다. APK 이름은 자동차 테스트Android.bp 파일에서 찾을 수 있습니다.

  • DEVICE-SERIAL : DUT의 일련 ID입니다. 하나의 장치만 호스트에 연결된 경우에는 이 매개변수가 필요하지 않습니다.

  • config-file-path : JSON 구성 파일 에 지정된 대로 기본이 아닌 장치 UI 구성을 제공하는 데만 필요한 선택적 매개변수입니다. 제공되지 않은 경우 프레임워크는 테스트 실행에 기본값을 사용합니다.

  • PATH-FOR-BUILT-TEST-APK : make 명령 실행 시 테스트 APK가 빌드되는 경로입니다.

  • TEST-PACKAGE : 테스트 패키지의 이름입니다.

  • TEST-CLASSNAME : 테스트 클래스의 이름입니다. 예를 들어 Wi-Fi 설정 테스트의 경우 테스트 패키지는 android.platform.tests 이고 테스트 클래스 이름은 WifiSettingTest 입니다.

자동차 조각 라이브러리

자동차 스니펫 라이브러리는 자동차 앱 및 서비스와 상호작용하도록 설계된 Android 오픈소스 프로젝트(AOSP)용 Android 테스트 라이브러리 세트입니다. 호스트(테스트) 시스템에서 Android 기반 장치로 원격 프로시저 호출(RPC)을 실행하기 위한 편리한 메커니즘과 함께 Spectatio를 활용합니다.

시작하다

시작하기 전에 다음 섹션을 검토하세요.

전제조건

  • 호스트 시스템에 Python 3.x가 설치되어 있습니다.
  • 필요한 빌드 도구를 사용하여 AOSP 환경을 설정합니다.
  • adb 액세스 권한이 있는 Android 자동차 기기(에뮬레이터 또는 실제 기기)

편집

Automotive Snippet Library에서 제공하는 다양한 스니펫을 컴파일하려면 제공된 android.bp 파일을 사용할 수 있습니다. APK를 컴파일하려면 이전 섹션의 명령을 따르세요.

전개

스니펫 라이브러리를 성공적으로 컴파일한 후 이전 섹션에서 언급한 adb install 명령을 사용하여 결과 APK를 대상 기기에 배포합니다.

테스트 실행

코드 조각 라이브러리는 자동차 시스템과 상호 작용하기 위한 여러 RPC 메서드를 노출합니다. 이러한 메소드는 호스트 시스템에서 Mobly 프레임워크를 통해 호출할 수 있습니다. Mobly 테스트 환경이 설정되어 있다고 가정하면 snippet_shell.py 스크립트를 사용하여 장치에서 RPC 메서드를 수동으로 호출할 수 있는 대화형 Python 셸을 열 수 있습니다. 호출 예시:

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

<serial> 장치 일련번호로 바꾸세요. 여러 장치가 연결된 경우 adb 장치로 얻을 수 있습니다.

포함된 라이브러리

자동차 조각 라이브러리에는 다음 조각 라이브러리와 도우미가 포함되어 있습니다.

  • AutomotiveSnippet: 전화 걸기, 볼륨 제어, 차량 하드 키, 미디어 센터 상호 작용 등 차량 작동과 관련된 API를 제공합니다.

  • PhoneSnippet: 통화 처리, 연락처 검색, SMS 작업 등 전화 통신 관련 API를 제공합니다.

Automotive 스니펫과 PhoneSnippet은 몇 가지 공통 논리를 공유합니다. 특히, 자동차와 전화 장치를 페어링하기 위해 Bluetooth 관련 RCP 호출을 침입할 수 있습니다. 이 bt_discovery_test 는 방법을 보여줍니다.