Для начала нужно установить все компоненты https://github.com/appium/appium-desktop/releases - Сам аппиум Appium https://www.oracle.com/technetwork/java/javase/downloads/2133151 - JRE JDK Дальше устанавливаем эмулятор, которым хотим пользоваться (если его еще нет), лично я использую Genymotion (Если что он бесплатный, регистрируемся и скачиваем For Personal Use) Прописываем ANDROID_HOME: Жмем правой кнопкой по "Моему компьютеру" -> Свойства -> Дополнительные параметры системы -> Переменные среды -> Создать -> Вписываем имя переменной ANDROID_HOME и путь до exe файла эмулятора -> Сохраняем. Добавление переменной среды Все те же действия проделываем для добавления еще одной переменной JAVA_HOME и путь до установленного JRE Добавление переменной среды Далее запускаем эмулятор или несколько, потом заходим в папку с эмулятором и ищем там adb.exe (он обычно или в основной папке(с основным ехе) или в папках bin или tools. Зажимаем клавишу Shift и жмем правой кнопкой мыши по пустому месту -> Выбираем "Открыть окно команд" Открыть окно команд Или же просто открываем командную строку и прописываем cd и путь до папки с adb.exe, в моем случае это cd C:\Program Files\Genymobile\Genymotion\tools Командная строка CMD Теперь вписываем команду adb devices Видим лист девайсов, если не видим лист, то перезапускаем эмуляторы или даже компьютер(Обычно помогает именно перезагрузка компьютера). (Не помогло? Такое бывает очень редко, но скорей всего это какие-то конфликты adb с вашим эмулятором, пробуем использовать другой эмулятор). После вписываем adb -s ип эмулятора shell В моем случае это выглядит так adb -s 192.168.176.102:5555 shell adb shell После этого устанавливаем нужное приложение на эмулятор и запускаем его, в консоль пишем команду dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp' Получаем данные о запущенном приложении, отсюда нам нужен PACKAGE и ACTIVITY Сохраняем эти данные они нам еще пригодятся Current Focused App Запускаем Appium и жмем Start Server Appium Далее жмем на значок лупы Appium Теперь нам нужно задать Capabilities, соответственно вписываем имя пакета, активити, platformName и deviceName - любые, autoGrantPermissions - по дефолту true ставим всегда. Самое нужное это udid - это ип нашего эмулятора. { "appPackage": "com.android.settings", "appActivity": "com.android.settings.Settings", "platformName": "Android", "autoGrantPermissions": true, "deviceName": "Android", "udid": "192.168.176.102:5555" } Capabilities Жмем Start Session и в появившемся окне жмем на глазик(для записи действий) Запись действий Appium Теперь выполняем действие. Выполнение действия через Appium Отлично, появился код этого действия, мы его можем перевести в другой язык программирования, к сожалению C# тут нету, но это не проблема, т.к. очень легко с питона можно перевести все на C# Выбор ЯП Если вдруг в приложении вылезает реклама, то жмем галочку назад driver.Navigate().Back(); Записываем все нужные нам действия. Перейдем к автоматизации через ZennoPoster Закидываем appium-dotnet-driver.dll и WebDriver.dll в Progs/ExternalAssemblies Ссылки на dll'ки appium-dotnet-driver.dll и WebDriver.dll Закидываем библиотеки в ZennoPoster Теперь создаем новый проект или открываем ваш старый, заходим в Ссылки из GAC, жмем кнопку добавить, указываем путь до наших dll'ок и жмем "ОК". Добавляем библиотеки в ZennoPoster Открываем Директивы Using и вписываем следующее: using OpenQA.Selenium; using OpenQA.Selenium.Appium; using OpenQA.Selenium.Appium.Android; using OpenQA.Selenium.Remote; Если вдруг будут в будущем какие-то ошибки связанные с WebDriver, можно будет дописать using OpenQA.Selenium.WebDriver; Директивы Using Теперь заходим в общий код и создаем несколько функций, тут вам нужно изменить только path (это путь до adb.exe в папке с эмулятором). public static string path = @"C:\Program Files\Genymobile\Genymotion\tools"; public static List<string> GetEmulators() { List<string> ips = new List<string>(); var lines = new List<string>() { @"cd "+path, "adb devices", }; string[] result = WriteCMD(lines); foreach (string r in result) { var matches = Regex.Matches(r, @"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{1,6}", RegexOptions.Singleline); foreach (Match match in matches) { ips.Add(match.Value); } } return ips; } private static string[] WriteCMD(List<string> lines) { Process process = new Process(); process.StartInfo.FileName = "cmd.exe"; process.StartInfo.RedirectStandardInput = true; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.CreateNoWindow = false; process.StartInfo.UseShellExecute = false; process.Start(); foreach (var line in lines) { process.StandardInput.WriteLine(line); process.StandardInput.Flush(); } process.StandardInput.Close(); process.WaitForExit(); return process.StandardOutput.ReadToEnd().Split('\n'); } C# код для получения Ип эмуляторов. Соответственно откуда в общем коде мы можем получить список эмуляторов так: List<string> Emulators = GetEmulators(); Или же в самом проекте создаем общий код C# и в код пишем так: List<string> Emulators = ZennoLab.OwnCode.CommonCode.GetEmulators(); Дальше вписываем Capabilities: string ip = Emulators[0]; project.SendInfoToLog(ip, true); DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.SetCapability("device", "Android"); capabilities.SetCapability("appPackage", "com.android.settings"); capabilities.SetCapability("appActivity", "com.android.settings.Settings"); capabilities.SetCapability("deviceName", "Android"); capabilities.SetCapability("platformName", "Android"); capabilities.SetCapability("udid", ip); AndroidDriver<OpenQA.Selenium.IWebElement> driver = new AndroidDriver<OpenQA.Selenium.IWebElement>(new Uri("http://127.0.0.1:4723/wd/hub"), capabilities); Соответственно тут заполняем все так же, как делали до этого в Appium'е Отлично, подключение к девайсу(девайсам) мы сделали, теперь нам надо переписать наш Python код на C# Было такое: el1 = driver.find_element_by_id("com.neenbo:id/iv_ola") el1.click() el2 = driver.find_element_by_id("com.neenbo:id/iv_sim") el2.click() el3 = driver.find_element_by_id("com.neenbo:id/iv_nao") el3.click() driver.back() el4 = driver.find_element_by_id("com.neenbo:id/iv_menu_toolbar") el4.click() el5 = driver.find_element_by_xpath("(//android.widget.ImageView[@content-desc=\"IMAGE\"])[6]") el5.click() Как это переписать? Все просто, в основном в C# все слова пишутся с большой буквы и нижнее подчеркивание "_" не используется, соответственно где было driver.find_element_by_id мы пишем driver.FindElementById Вконце всегда ставим точку с запятой ";" Перед всеми элементами пишем var, т.е. там, где было el1 мы пишем var el1 вот пример первых двух строк: var el1 = driver.FindElementById("com.neenbo:id/iv_ola"); el1.Click(); Или можно сделать проще: driver.FindElementById("com.neenbo:id/iv_ola").Click(); Так же во время переписывания кода зенка нам будет давать подсказки ZennoPoster Appium Получился вот такой код: Код C# List<string> ips = ZennoLab.OwnCode.CommonCode.GetEmulators(); // получаем ип эмуляторов в коллекцию. foreach(string ip in ips) // перебираем все строки из коллекции { DesiredCapabilities capabilities = new DesiredCapabilities(); // класс настроек capabilities.SetCapability("device", "Android"); // Любое имя capabilities.SetCapability("appPackage", "com.android.settings"); // Package capabilities.SetCapability("appActivity", "com.android.settings.Settings"); //Activity capabilities.SetCapability("deviceName", "Android"); //Любое имя capabilities.SetCapability("platformName", "Android"); //Любое имя capabilities.SetCapability("udid", ip); // адрес нашего эмулятора var driver = OpenQA.Selenium.Appium.Android.AndroidDriver<OpenQA.Selenium.Appium.Android.AndroidDriver>(new Uri("http://127.0.0.1:4723/wd/hub"), capabilities); // инициализируем эмулятор driver.StartActivity("com.neenbo", "com.neenbo.LoginActivity"); // Запускаем приложение driver.FindElementById("com.neenbo:id/iv_menu_toolbar").Click(); // Ищем элемент по ид и кликаем по нему driver.FindElementByXPath("(//android.widget.ImageView[@content-desc=\"IMAGE\"])[3]").Click(); // Ищем элемент и кликаем по нему for(int i=0;i<50;i++) // Цикл, чтобы выполнить действия 50 раз { try // Заключаем в try { } catch { } чтобы в тот момент, когда вылезет реклама нажать кнопку назад driver.Navigate().Back(); { driver.FindElementById("com.neenbo:id/iv_ola").Click(); // Ищем элемент и кликаем по нему driver.FindElementById("com.neenbo:id/iv_ola").Click(); // Ищем элемент и кликаем по нему driver.FindElementById("com.neenbo:id/iv_sim").Click(); // Ищем элемент и кликаем по нему driver.FindElementById("com.neenbo:id/iv_nao").Click(); // Ищем элемент и кликаем по нему } catch // Ловим ошибку (Ошибка будет говорить о том, что элемент не существует) { driver.Navigate().Back(); // Жмем кнопку назад } } } Совсем забыл, нужно же добавить задержки, делается в коде это так: System.Threading.Thread.Sleep(5000); // Ожидание 5 секунд (5000 миллисекунд это 5 секунд) У некоторых людей(или с некоторыми версиями dll'ок, не знаю) существует проблема в этом месте OpenQA.Selenium.Appium.Android.AndroidDriver<OpenQA.Selenium.Appium.Android.AndroidDriver>(new Uri("http://127.0.0.1:4723/wd/hub"), capabilities); // инициализируем эмулятор Самое простое решение, которое я нашел это заменить AndroidDriver на IWebDriver. IWebDriver driver = new RemoteWebDriver(new Uri("http://127.0.0.1:4723/wd/hub"), capabilities); Тогда код получается немного другой Разница в том, что вместо driver.FindElementById("com.neenbo:id/iv_ola").Click(); нужно будет писать так: driver.FindElement(By.Id("com.neenbo:id/iv_ola")).Click(); C# код List<string> ips = ZennoLab.OwnCode.CommonCode.GetEmulators(); // получаем ип эмуляторов в коллекцию. foreach(string ip in ips) // перебираем все строки из коллекции { DesiredCapabilities capabilities = new DesiredCapabilities(); // класс настроек capabilities.SetCapability("device", "Android"); //Любое имя capabilities.SetCapability("appPackage", "com.neenbo"); // Package capabilities.SetCapability("appActivity", "com.neenbo.LoginActivity"); //Activity capabilities.SetCapability("deviceName", "Android"); //Любое имя capabilities.SetCapability("platformName", "Android"); //Любое имя capabilities.SetCapability("udid", ip); // адрес нашего эмулятора IWebDriver driver = new RemoteWebDriver(new Uri("http://127.0.0.1:4723/wd/hub"), capabilities); // инициализируем эмулятор System.Threading.Thread.Sleep(25000); // Задержка 25 секунд driver.FindElement(By.Id("com.neenbo:id/iv_menu_toolbar")).Click(); // Ищем элемент и кликаем по нему System.Threading.Thread.Sleep(5000); // Задержка 5 секунд driver.FindElement(By.XPath("(//android.widget.ImageView[@content-desc=\"IMAGE\"])[3]")).Click(); // Ищем элемент и кликаем по нему System.Threading.Thread.Sleep(5000); // Задержка 5 секунд for(int i=0;i<50;i++) // Цикл, чтобы выполнить действия 50 раз { try // Заключаем в try { } catch { } чтобы в тот момент, когда вылезет реклама нажать кнопку назад driver.Navigate().Back(); { System.Threading.Thread.Sleep(5000); // Задержка 5 секунд driver.FindElement(By.Id("com.neenbo:id/iv_ola")).Click(); // Ищем элемент и кликаем по нему System.Threading.Thread.Sleep(5000); // Задержка 5 секунд driver.FindElement(By.Id("com.neenbo:id/iv_ola")).Click(); // Ищем элемент и кликаем по нему System.Threading.Thread.Sleep(5000); // Задержка 5 секунд driver.FindElement(By.Id("com.neenbo:id/iv_sim")).Click(); // Ищем элемент и кликаем по нему System.Threading.Thread.Sleep(5000); // Задержка 5 секунд driver.FindElement(By.Id("com.neenbo:id/iv_nao")).Click(); // Ищем элемент и кликаем по нему } catch // Ловим ошибку (Ошибка будет говорить о том, что элемент не существует) { driver.Navigate().Back(); // Жмем кнопку назад } } } МУЛЬТИПОТОК Итак, как все настроить и запустить мы разобрались, но код выполняется синхронно, эмуляторы работаю по порядку! Хочу чтобы все работало одновременно, что делать? - Для этого нужно немного изменить код программы, весь код который мы писали перенесем в общий код программы и будем вызывать это все через Task.Run(()=>.....) Весь наш написанный скрипт мы перенесем в отдельную функцию и в качестве параметра в нее будем передавать ип эмулятора Не забываем добавлять ссылки на библиотеки: using OpenQA.Selenium.Appium; using OpenQA.Selenium.Appium.Android; using OpenQA.Selenium.Remote; using OpenQA.Selenium; using System.Threading.Tasks; Вот часть того, что у нас получилось. Соответственно из самого проекта зенки будем вызывать функцию Start(); C# код public static async Task Start() //Для запуска работы в мультипоток { List<string> ips = GetEmulators(); // получаем ип эмуляторов в коллекцию. List<Task> Tasks = new List<Task>(); // Создаем новую коллекцию, куда будем записывать наши потоки foreach(string ip in ips) // перебираем все строки из коллекции { Tasks.Add(Task.Run(()=>StartWork(ip))); // Запускаем работу эмулятора await Task.Delay(1000); // Сделаем небольшую задержку между запуском потоков } await Task.WhenAll(Tasks);// Ждем когда все потоки завершат работу } private static async Task StartWork(string ip) { await Task.Delay(100); // Чтобы все выполнялось правильно нужен хотя бы 1 await в функции DesiredCapabilities capabilities = new DesiredCapabilities(); // класс настроек capabilities.SetCapability("device", "Android"); //Любое имя capabilities.SetCapability("appPackage", "com.neenbo"); // Package capabilities.SetCapability("appActivity", "com.neenbo.LoginActivity"); //Activity capabilities.SetCapability("deviceName", "Android"); //Любое имя capabilities.SetCapability("platformName", "Android"); //Любое имя capabilities.SetCapability("udid", ip); // адрес нашего эмулятора IWebDriver driver = new RemoteWebDriver(new Uri("http://127.0.0.1:4723/wd/hub"), capabilities); // инициализируем эмулятор System.Threading.Thread.Sleep(25000); // Задержка 25 секунд driver.FindElement(By.Id("com.neenbo:id/iv_menu_toolbar")).Click(); // Ищем элемент и кликаем по нему System.Threading.Thread.Sleep(5000); // Задержка 5 секунд driver.FindElement(By.XPath("(//android.widget.ImageView[@content-desc=\"IMAGE\"])[3]")).Click(); // Ищем элемент и кликаем по нему System.Threading.Thread.Sleep(5000); // Задержка 5 секунд for(int i=0;i<50;i++) // Цикл, чтобы выполнить действия 50 раз { try // Заключаем в try { } catch { } чтобы в тот момент, когда вылезет реклама нажать кнопку назад driver.Navigate().Back(); { System.Threading.Thread.Sleep(5000); // Задержка 5 секунд driver.FindElement(By.Id("com.neenbo:id/iv_ola")).Click(); // Ищем элемент и кликаем по нему System.Threading.Thread.Sleep(5000); // Задержка 5 секунд driver.FindElement(By.Id("com.neenbo:id/iv_ola")).Click(); // Ищем элемент и кликаем по нему System.Threading.Thread.Sleep(5000); // Задержка 5 секунд driver.FindElement(By.Id("com.neenbo:id/iv_sim")).Click(); // Ищем элемент и кликаем по нему System.Threading.Thread.Sleep(5000); // Задержка 5 секунд driver.FindElement(By.Id("com.neenbo:id/iv_nao")).Click(); // Ищем элемент и кликаем по нему } catch // Ловим ошибку (Ошибка будет говорить о том, что элемент не существует) { driver.Navigate().Back(); // Жмем кнопку назад } } } Делаем вызов нашей функции: ZennoLab.OwnCode.CommonCode.Start(); Вызов функции из общего кода Видео работы Код проекта Основные команды, которые используются в работе обычно: driver.Tap(1, 436, 694, 0); // Нажатие по координатам driver.Swipe(414, 660, 422, 1160, 0); свайп с координатов 414 660 до 422 1160 driver.FindElementById("n.android:id/Title").Text // Получение текста элемента. driver.FindElementById("n.android:id/button").Click(); // Клик по элементу driver.FindElementById("n.android:id/text").SendKeys("Привет"); // Ввод текста driver.FindElementById("n.android:id/text").Clear(); // Очистка текстового поля driver.Navigate().Back(); // Возврат назад driver.Quit(); // Закрытие сессии driver.RemoveApp("com.neenbo"); // Удаление апк (Используется имя Package driver.InstallApp(Environment.CurrentDirectory + "\\someapk.apk"); // Установка приложения(в параметрах указываем путь до приложения) Возможные проблемы: Вылетает из аккаунта - Значит открываем приложение с использованием неправильного Activity, пробуем заменить Activity Начало выдавать ошибку что устройство не найдено или не находит эмуляторы через adb devices, хотя раньше все работало - Лечим перезагрузкой девайсов или компьютера Выдает с самого начала ошибку/не находит эмуляторы - Пробуем создать эмулятор с другим андройдом, например, 7 или 8. Если не помогает, то скачиваем с гитхаба разные версии библиотек. На некоторых версиях библиотек и эмуляторов такое бывает и с этим ничего не поделать, нужно подбирать версию под себя. Не видит элементы - Увеличиваем задержки, если не помогает, то кликаем по координатам Через какое-то время в процессе работы в мультипотоке один или несколько эмуляторов отваливаются - Это нормально, аппиум не предназначен для мультипотока, используем try { } catch { } который заключаем в while(true) { } для автоматического перезапуска работы. P.s буду благодарен за + в репу
странно как эта статья не приняла участия в конкурсе на самом форуме Зенки, уверен что она была бы топовой
не надо все делать, как дамочки три действия одновременно, работаем по запросам, попутно на втором мониторе курс по зенке и добавочно ещё торгуем на криптобирже
Очень годно и подробно описано , но человеку далекому от программирования сложно) PS как поставить + в репу не разобрался xD