Запустите тест инструмента из приложения и дождитесь результата

Я разрабатываю решение автоматизации QA, которое может записывать/воспроизводить тесты QA на Android. Ключевым бизнес-требованием является отсутствие зависимости от подключенного ПК при воспроизведении записанного теста. С этой целью я пытаюсь запустить тест Instrumentation без подключенного ПК. (В частности, тест Appium UiAutomator2).

Мой текущий подход пытается запустить тест программно из моего приложения. Если бы я обычно выполнял тест с подключенного ПК, я бы использовал команду adb shell am instrument -w. Я попытался получить доступ к ADB Shell из своего приложения и запустить am instrument -w, но это приводит к ошибке, что мне не хватает разрешения INTERACT_ACROSS_USERS_FULL.

Чтобы обойти эту проблему, я пытаюсь запустить тест, используя startInstrumentation. Это успешно запускает тест. Тем не менее, тест сразу же падает. После дальнейшего расследования я проследил крах NPE: тест пытается извлечь InstrumentationRegistry.getInstrumentation.getUiAutomation(0), но это возвращает null.

Как я могу запустить тест программно и предоставить ему доступ к нужному экземпляру UiAutomation?

Вот как я начинаю тест:

public void runTest() {
    final String pm = getPackageName().replaceFirst(".test$", "");
    final InstrumentationInfo info = getInstrumentationInfo(pm);
    if (info != null) {

        final ComponentName cn = new ComponentName(info.packageName,
                info.name);

        Bundle arguments = new Bundle();
        arguments.putString("class", "io.testim.appiumwrapper.test.AppiumUiAutomator2Server");
        //cn = {io.extension.test/android.support.test.runner.AndroidJUnitRunner}
        startInstrumentation(cn, null, arguments);

    } 
}

Ответ 1

см. уровень защиты подписи - уточнение... если только пакет не будет указан в списке ключей Google, вы не сможете получить необходимое разрешение. это функция безопасности/целостности с целью ограничения того, что вредоносное ПО может сделать - и то, что вы намереваетесь сделать там, является типичным поведением вредоносного ПО - независимо от его фактического намерения; работа против системы ни к чему не приводит.

единственным способом, с помощью которого я мог бы работать с изображениями, было бы запускать команды непосредственно из эмулятора терминала или тестового приложения - против пользовательской сборки AOSP, чтобы вы могли добавить android:protectionLevel="signature" в Manifest.xml а затем потребовать android.permission.INTERACT_ACROSS_USERS_FULL. но с запасом ROM, определенно нет шансов на это. это не так, что это было бы "невозможно", но создание пользовательского ПЗУ означает совсем немного усилий, чтобы добраться туда. по крайней мере для устройств Nexus и Pixel, необходимые драйверы доступны здесь; для других устройств вам придется найти их у поставщика устройств, если они даже доступны.

хитрость заключается в том, чтобы подписать на диск с тем же ключом, что и приложение - только тогда signature разрешение уровня может быть получено - в то время как на фондовый ROM, вы бы (теоретически) нужен ключ для Google, чтобы подписать пакет. можно привести в действие одного пользователя, как описано здесь, в то время как это также доступно только для системных приложений.