Тестирование нескольких пользователей

На этой странице описаны важные аспекты тестирования многопользовательской работы на платформе Android. Сведения о реализации многопользовательской поддержки см. в разделе Поддержка нескольких пользователей .

Пути к устройствам

В следующей таблице перечислены несколько путей к устройствам и способы их разрешения. Все значения в столбце «Путь» относятся к изолированному хранилищу, специфичному для пользователя. Хранилище Android со временем менялось; для получения дополнительной информации см. документацию по хранилищу .

Путь Системный путь (необязательно) Цель
/data/user/{userId}/{app.path} /data/data Хранилище приложений
/storage/emulated/{userId} /sdcard Общее внутреннее хранилище
/data/media/{userId} никто Медиаданные пользователя (например, музыка, видео)
/data/system/users/{userId} никто Конфигурация/состояние системы для каждого пользователя

Доступно только системным приложениям

Вот пример использования пути, специфичного для пользователя:

# to access user 10's private application data for app com.bar.foo:
$ adb shell ls /data/user/10/com.bar.foo/

взаимодействие adb между пользователями

Несколько команд adb полезны при работе с несколькими пользователями. Некоторые из них поддерживаются только в Android 9 и выше:

  • adb shell am instrument --user <userId> запускает инструментальный тест для указанного пользователя. По умолчанию используется текущий пользователь.
  • adb install --user <userId> устанавливает пакет для конкретного пользователя. Чтобы гарантировать установку пакета для всех пользователей, необходимо вызвать эту команду для каждого пользователя.
  • adb uninstall --user <userId> удаляет пакет для определённого пользователя. Вызов без флага --user позволяет удалить пакет для всех пользователей.
  • adb shell am get-current-user получает текущий (основной) идентификатор пользователя.
  • adb shell pm list users получает список всех существующих пользователей.
  • adb shell pm create-user создает нового пользователя, возвращая идентификатор.
  • adb shell pm remove-user удаляет определенного пользователя по ID.
  • adb shell pm disable --user <userId> отключает пакет для определенного пользователя.
  • adb shell pm enable --user <userId> включает пакет для определенного пользователя.
  • adb shell pm list packages --user <userId> выводит список пакетов ( -e для включённых, -d для отключённых) для определённого пользователя. По умолчанию всегда выводится список для системного пользователя.

Следующая информация помогает объяснить, как adb ведет себя с несколькими пользователями:

  • adb (точнее, демон adbd ) всегда запускается от имени системного пользователя (ID пользователя = 0) независимо от текущего пользователя . Поэтому пути к устройствам, зависящие от пользователя (например, /sdcard/ ), всегда определяются как путь к системному пользователю. Подробнее см. в разделе «Пути к устройствам» .

  • Если пользователь по умолчанию не указан, каждая подкоманда adb будет использовать другого пользователя. Рекомендуется получить идентификатор пользователя с помощью am get-current-user , а затем явно использовать --user <userId> для любой команды, которая его поддерживает. Явные флаги пользователя поддерживались только для всех команд до Android 9.

  • Доступ к путям /sdcard вторичных пользователей запрещен, начиная с Android 9. Подробную информацию о том, как извлечь файлы во время тестирования, см. в разделе Поставщик контента для многопользовательских данных .

Поставщик контента для многопользовательских данных

Поскольку adb работает от имени системного пользователя, а данные в Android 9 и выше находятся в изолированной среде, для отправки или получения тестовых данных от несистемного пользователя необходимо использовать контент-провайдеров. Это не обязательно, если:

  • adbd работает как root (через adb root ), что возможно только при использовании сборок userdebug или usereng .

  • Вы используете ITestDevice от Trade Federation (Tradefed) для загрузки или извлечения файлов, в этом случае используйте пути /sdcard/ в вашей тестовой конфигурации (например, см. исходный код для pushFile в NativeDevice.java ).

Если поставщик контента запущен во вторичном пользователе, доступ к нему можно получить с помощью команды adb shell content указав соответствующие имя user , uri и другие параметры.

Обходной путь для разработчиков приложений

Взаимодействуйте с тестовыми файлами, используя adb content и экземпляр ContentProvider вместо команд push или pull .

  1. Создайте экземпляр ContentProvider , размещенный в приложении, который может предоставлять и хранить файлы там, где это необходимо. Используйте внутреннее хранилище приложения.
  2. Используйте команды read или write adb shell content для отправки или извлечения файлов.

Обходной путь для медиа-файлов

Чтобы сохранить медиафайлы в разделе «Media» на SD-карте, используйте публичные API MediaStore . Например:

# push MVIMG_20190129_142956.jpg to /storage/emulated/10/Pictures
# step 1
$ adb shell content insert --user 10 --uri content://media/external/images/media/ --bind _display_name:s:foo.jpg

# step 2
$ adb shell content query --user 10 --projection _id --uri content://media/external/images/media/ --where "_display_name=\'foo.jpg\'"

# step 3
$ adb shell content write --user 10 --uri content://media/external/images/media/8022 < MVIMG_20190129_142956.jpg

Установить поставщика универсального контента

Установите и используйте существующий поставщик контента, который считывает и записывает файлы по указанному пользователем пути /sdcard .

Соберите TradefedContentProvider.apk из исходного кода с помощью команды make TradefedContentProvider :

```
# install content provider apk
$ adb install --user 10 -g TradefedContentProvider.apk

# pull some_file.txt
$ adb shell content read --user 10 --uri content://android.tradefed.contentprovider/sdcard/some_file.txt > local_file.txt

# push local_file.txt
$ adb shell content write --user 10 --uri content://android.tradefed.contentprovider/sdcard/some_file.txt < local_file.txt
```

Поддержка многопользовательской версии Торговой федерации

Tradefed — официальная тестовая среда для Android. В этом разделе описываются некоторые встроенные функции Tradefed для многопользовательских тестовых сценариев.

Проверки статуса

Средства проверки состояния системы (SSC) запускаются до целевых подготовителей, а их очистка выполняется после этих подготовителей.

UserChecker определён явно для помощи разработчикам при тестировании нескольких пользователей. Он отслеживает, изменил ли тест состояние пользователей на устройстве (например, создал ли пользователь, не удалив его при удалении). Кроме того, если задан user-cleanup , он автоматически пытается выполнить очистку после теста, при этом предоставляя полезные сведения об ошибках для исправления теста.

<system_checker class="com.android.tradefed.suite.checker.UserChecker" >
    <option name="user-cleanup" value="true" />
</system_checker>

Подготовитель целей

Подготовители целей обычно используются для настройки устройства с определённой конфигурацией. В случае многопользовательского тестирования подготовители могут использоваться для создания пользователей определённого типа, а также для переключения на других пользователей.

Для устройств, у которых нет дополнительного пользователя, можно использовать CreateUserPreparer для создания и переключения на дополнительного пользователя в AndroidTest.xml . По завершении теста подготовка возвращается к предыдущему состоянию и удаляет дополнительного пользователя.

<target_preparer
  class="com.google.android.tradefed.targetprep.CreateUserPreparer" >
</target_preparer>

Если нужный тип пользователя уже существует на устройстве, используйте SwitchUserTargetPreparer для переключения на существующего пользователя. Типичные значения для user-type включают system или secondary .

<target_preparer
  class="com.android.tradefed.targetprep.SwitchUserTargetPreparer">
    <option name="user-type" value="secondary" />
</target_preparer>

Тесты, управляемые хостом

В некоторых случаях тесту требуется переключать пользователей внутри test . Не делайте этого из фреймворка тестирования на стороне устройства, например UI Automator , поскольку процесс тестирования может быть прерван в любой момент. Вместо этого используйте фреймворк тестирования на стороне хоста, например, Host-driven test framework от Tradefed , который предоставляет доступ к ITestDevice , позволяя выполнять любые необходимые действия с пользователем.

Используйте UserChecker (описанный в разделе «Проверки состояния ») для тестов, управляемых хостом, которые изменяют состояние пользователя, поскольку он гарантирует, что тест правильно очистит после себя.