Параллельное выполнение Monkeyrunner на устройствах

Я пытаюсь использовать monkeyrunner для настройки нескольких планшетов, подключенных к одному и тому же компьютеру. Код работает нормально для 1 планшета, но в тот момент, когда я пытаюсь запустить его на нескольких планшетах, все взрывается.

Вот код, который вызывает файл Python monkeyrunner. mr1.py — это файл monkeyrunner, который я пытаюсь запустить.

import sys

import util
import threading
import commands
class myThread (threading.Thread):
    def __init__(self, threadID, deviceId,env_path):
        self.threadID = threadID
        self.deviceId = deviceId
        self.path = env_path
        threading.Thread.__init__(self)
    def run(self):
        print "Starting " + self.deviceId
        ret = commands.getstatusoutput(self.path+"monkeyrunner mr1.py "+self.deviceId)
        print ret
        print "Exiting " + self.deviceId

def main():
    connected_devices = util.get_connected_devices()
    count = 0
    path = "/Users/ad/Desktop/android-sdk-macosx/tools/"
    for device in connected_devices:
        thread = myThread(count,device[0],path)
        thread.start()
        count = count + 1


if __name__ == "__main__":
    main()

Я наткнулся на этот пост в блоге, в котором описывается состояние гонки в monkeyrunner. Я не уверен, что именно это вызывает проблему.

http://distributedreasoner.blogspot.com/2011/06/android-monkeyrunner-and-google-adb.html

Я также пытался использовать библиотеку MAML, упомянутую в сообщении блога выше, но мне так и не удалось заставить monkeyrunner выполняться симуляционно на нескольких устройствах. Вот реальный код мартышек.

import sys
import maml
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice



deviceId = sys.argv[1]

# Connects to the current device, returning a MonkeyDevice object
device = MonkeyRunner.waitForConnection(10.0,deviceId)

packagename = "com.android.settings"
classname =    "com.android.settings.DisplaySettings" #SecuritySettings" #".DisplaySettings" 
componentname = packagename + "/" + classname 
device.startActivity(component=componentname) 
maml.click(device,1088,300)
MonkeyRunner.sleep(0.4)
maml.click(device,864,361)
MonkeyRunner.sleep(0.4)
maml.click(device,612,621)
MonkeyRunner.sleep(0.5)
device.press ('KEYCODE_HOME', 'DOWN_AND_UP')

print "Exiting for device !" + deviceId

Основываясь на вопросе Commonsware, я заменил код многопоточности следующим последовательным кодом, и, похоже, он работает нормально, но, очевидно, это не самая идеальная ситуация.

for device in connected_devices:
        print device[0]
        ret = commands.getstatusoutput(path+"monkeyrunner mr1.py "+device[0])
        print ret

Поскольку Android не позволяет программно изменять настройки местоположения/языка и т. д., а мне нужно настроить многие планшеты для изменения настроек, непосредственным вариантом было использование MonkeyRunner. Пара замечаний: я открыт для других инструментов, которые я мог бы использовать, кроме Monkeyrunner, для решения этой проблемы. Любая помощь по этой проблеме будет принята с благодарностью.


person smk    schedule 19.11.2012    source источник
comment
Вы пытаетесь запустить его на нескольких планшетах последовательно или одновременно? Что именно вы имеете в виду, говоря, что все это взрывается?   -  person CommonsWare    schedule 20.11.2012
comment
Одновременно. Под всеми взрывами я подразумеваю, что ничего не происходит. Например, в коде monkeyrunner, который я вставил, он должен сначала открыть настройки «Дисплей», а затем нажать «Автоповорот экрана», а затем изменить режим сна на «Всегда включен». Когда я запустил его на 2 устройствах, подключенных к моему компьютеру, я заметил, что открылись только настройки дисплея. Других щелчков не было. Опять же, это не совсем то же самое поведение каждый раз, когда я запускаю скрипт. Иногда некоторые клики работают на 1 устройстве, но не на другом.   -  person smk    schedule 20.11.2012
comment
Кстати, я предполагаю, что планшет находится в альбомной ориентации.   -  person smk    schedule 20.11.2012


Ответы (1)


Какие настройки вы пытаетесь изменить? язык может быть выполнен в вашем приложении, если он единственный.

public void setLocale(Locale locale, Instrumentation inst){
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    inst.getTargetContext().getResources().updateConfiguration(config, inst.getTargetContext().getResources().getDisplayMetrics());
}

Все ли ваши планшеты имеют уровень API 16+ (jely bean?), если это так, вы можете посмотреть http://developer.android.com/tools/testing/testing_ui.html

Наконец, если вы все еще хотите сделать это с помощью Monkey runner, я бы порекомендовал получить все ваши устройства в одном потоке, а затем передавать каждое устройство в каждый поток отдельно.

Python не является моей специальностью, и у меня нет доступа/знаний ко всем библиотекам, которые вы используете (может быть, я мог бы сделать это на Java для вас?), но я думаю, что это может работать лучше, это что-то вроде:

class myThread (threading.Thread):
    def __init__(self, device):
        self.device = device
        threading.Thread.__init__(self)

    def run(self):
        packagename = "com.android.settings"
        classname = "com.android.settings.DisplaySettings"
        componentname = packagename + "/" + classname
        self.device.startActivity(component=componentname)
        maml.click(self.device, 1088, 300)
        MonkeyRunner.sleep(0.4)
        maml.click(self.device, 864, 361)
        MonkeyRunner.sleep(0.4)
        maml.click(self.device, 612, 621)
        MonkeyRunner.sleep(0.5)
        self.device.press('KEYCODE_HOME', 'DOWN_AND_UP')


def main():
    connected_devices = util.get_connected_devices()
    count = 0
    devices = []
    for deviceId in connected_devices:
        devices[count] = MonkeyRunner.waitForConnection(10.0, deviceId[0])
        count = count + 1
    for device in devices:
        thread = myThread(device)
        thread.start()


if __name__ == "__main__":
    main()

в основном разница в том, как я сказал выше, вы получаете все устройства последовательно, а затем последовательно вызываете каждый поток с устройством, которое вы получили. Имеет ли это смысл?

person Paul Harris    schedule 19.11.2012
comment
Да, я знаю, что некоторые настройки можно сделать программно, но мне нужно изменить 1) службы определения местоположения 2) языки и ввод и безопасность. Это нельзя сделать программно - верно? - person smk; 20.11.2012
comment
если вы все еще хотите сделать это с помощью Monkey runner, я бы порекомендовал завладеть всеми вашими устройствами в одном потоке, а затем передать каждое устройство каждому потоку отдельно. - Я новичок в python, но разве я не этим занимаюсь? в цикле for device в connect_devices? - person smk; 20.11.2012
comment
Я буду честен, вам будет трудно делать некоторые из этих вещей с помощью MonkeyRunner, даже если вы справитесь с этой проблемой, потому что я ожидаю, что ваши планшеты имеют разные пользовательские интерфейсы, например. их делают разные люди. Это означает, что у них наверняка разные координаты для всего. Возможно, вам будет лучше ограничить это тестирование эмулятором, на котором вы можете легко выполнять нужные вам действия, и использовать планшеты для тестирования других вещей. - person Paul Harris; 20.11.2012
comment
Моя ситуация следующая. Это на 1 раз. И мы заранее знаем, что будет около 2 тысяч новых планшетов и все одного типа. - person smk; 20.11.2012
comment
Вы знаете какая у них версия андроида? - person Paul Harris; 20.11.2012
comment
Вы, сэр, мой герой. Использование инструмента uiautomator сработало очень хорошо. Я разговаривал со своим магнатом и считаю, что это должен быть JB. Так что я надеюсь, что я хорошо. - person smk; 20.11.2012