Добрый вечер. У нас тут подходит к концу перевод Appium Essentials. Что уже пройдено:
- Глава 1, в которой мы разбираемся, что тут и как
- Глава 2 про установку и настройку всего необходимого для работы
- Глава 3, где мы изучаем, что такое Appium GUI
- Глава 4 о том, как можно локализовать элементы в мобильном приложении
- Глава 5, где мы, наконец-то автоматизируем приложения, но пока только на эмуляторах
В этой главе:
- Автоматизируем набор номера на устройстве Android
- Автоматизируем форму регистрации на Android
- Используя Chrome, залогинимся на Gmail
- iOS. Автоматизируем Body Mass Index (BMI)
- Автоматизация гибридных приложений на устройствах iOS
- iOS. Автоматизация веб-приложений
Перед стартом
Перед началом работы, еще раз убедимся, что все настроено:
Требования для Android | Требования для iOS |
Java (версии 7 и выше) | Mac OS (версии 10.7 и выше) |
Android SDK API, версии 17 и выше | Xcode (версии 4.6.3 и выше; рекомендуется 5.1) |
Устройство с Android | Профиль iOS [эти и другие непонятные слова объясняются ниже] |
Браузер Chrome на устройстве | Устройство iOS |
Eclipse [или Idea] | Приложение SafariLauncher |
TestNG | ios-webkit-debug-proxy |
Appium сервер | Java (версии 7 и выше) |
Клиентская библиотека Appium (у нас все еще Java) | Eclipse [или Idea] |
Selenium Server и Java-библиотека WebDriver | TestNG |
Приложение Apk Info app | Selenium Server и Java-библиотека WebDriver |
Appium сервер | |
Клиентская библиотека Appium (у нас все еще Java) |
Убедитесь, что на устройстве Android включен режим разработчика и разрешена отладка оп USB.
Чтобы проверить, что девайс подключен, введите в командную строку
adb devices
Вы получите список Android-устройств. Если нет, попробуйте перезапустить adb-сервер:
adb kill-server
adb start-server
Desired capabilities для Android для нативных и гибридных приложений
В главе 1 мы обсудили, какие есть опции и зачем они. Так что здесь, перейдем сразу к коду.
Сначала, импортируем пакеты:
import java.io.File;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.remote.MobileCapabilityType;
Теперь DC:
DesiredCapabilities caps = new DesiredCapabilities();
File app=new File("path of the apk");//чтобы определить путь до apk
caps.setCapability(MobileCapabilityType.APP,app);//если приложение уже установлено, эти две опции не нужны
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4");//версия Android
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");//Имя OS
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "Moto X");//здесь указывается имя устройства
caps.setCapability(MobileCapabilityType.APP_PACKAGE, "имя пакета вашего приложения(можете получить его, используя apk info app)");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY, "активити, которую нужно будет запустить (получить так же через apk info app)");
Desired capabilities для Android для веб-приложений
При работе с веб-приложениями, некоторые опции, указанные выше, нам не понадобятся: APP, APP PACKAGE и APP ACTIVITY, поскольку мы работаем с браузером.
Сперва, импортируем пакеты:
import java.io.File;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.remote.MobileCapabilityType;
Теперь DC:
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4");//версия Android
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");//Имя OS
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "Moto X");//здесь указывается имя устройства
caps.setCapability(MobileCapabilityType.BROWSER_NAME, "Chrome"); //чтобы запустить Chrome
Мы закончили с конфигурацией, теперь можно инициализировать драйвер.
Импорт:
import io.appium.java_client.android.AndroidDriver;
import java.net.URL;
Инициализация:
AndroidDriver driver = new AndroidDriver (new URL("https://127.0.0.1:4723/wd/hub"), caps);//указываем адрес, где запущен Appium-сервер
Все готово для работы с устройством Android.
Разбираемся с provisional profile, SafariLauncher и ios-webkit-debug-proxy
Прежде чем настраивать драйвер для iOS, нужно выполнить несколько шагов.
Provisional profile
Профиль нужен для того, чтобы ставить свои приложения на устройства iOS. Для этого нужно присоединиться к программе iOS Developer Program
После регистрации, посетите эту страницу, чтобы сгенерировать профиль.
Этот профиль нужно будет установить и на девайс:
- Скачайте сгенерированный профиль
- Подключите iOS устройство к Mac
- Откройте Xcode (версии 6) и перейдите в меню Window -> Devices
- Вызовите контекстное меню для подключенного устройства и кликните на Show Provisional Profiles…
- Нажмите +, выберите скаченный профиль, нажмите Done
Приложение SafariLauncher и ios-webkit-debug-proxy
SafariLauncher используется для запуска браузера Safari на устройстве. Нужно собрать и задеплоить SafariLauncher на устройство iOS, чтобы работать с браузером Safari:
- Скачайте исходники
- Запустите Xcode и откройте проект SafariLauncher
- Выберите устройство для деплоя и нажмите кнопку build
- Затем нужно будет заменить SafariLauncher в Appium.dmg; для этого необходимо:
- Вызвать контекстное меню для Appium.dmg
- Кликнуть на Show Package Contents и перейти в Contents/Resources/node_modules/appium/build/SafariLauncher
- Разархивировать SafariLauncher.zip
- Перейти в submodules/SafariLauncher/build/Release-iphoneos и замените приложение SafariLauncher своим.
- Заархивируйте submodules и переименуйте в SafariLauncher.zip
Теперь нужно поставить ios-webkit-debug-proxy на Mac, чтобы установить соединение и получить доступ к web-view. Чтобы поставить прокси, можете использовать brew и выполнить команду
brew install ios-webkit-debug-proxy
.
Desired capabilities для iOS для нативных и гибридных приложений
В главе 1 мы обсудили, какие есть опции и зачем они. Так что здесь, перейдем сразу к коду.
Сначала, импортируем пакеты:
import java.io.File;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.remote.MobileCapabilityType;
Теперь DC:
DesiredCapabilities caps = new DesiredCapabilities();
File app=new File("path of the .app");
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "8.1");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");//
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "iPad");//
caps.setCapability("udid","Id реального устройства");//UDID
Desired capabilities для iOS для веб-приложений
Некоторые из опция нам не понадобятся. К этим опциям относятся: APP, APP PACKAGE и APP ACTIVITY. Теперь к делу.
Сначала, импортируем пакеты:
import java.io.File;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.remote.MobileCapabilityType;
Теперь DC:
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "8.1");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"iPad");
caps.setCapability("udid","UDID вашего устройства");
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Safari"); //чтобы запустить Safari
Мы закончили с конфигурацией, теперь можно инициализировать драйвер.
Импорт:
import io.appium.java_client.ios.IOSDriver;
import java.net.URL;
Инициализация:
IOSDriver driver = new IOSDriver (new URL("https://127.0.0.1:4723/wd/hub"),caps); //Адрес, где Appium-сервер
Все готово для работы с устройством iOS.
Теперь можно добавить TestNG и попробовать запустить все вместе:
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.remote.MobileCapabilityType;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class TestAppIication {
IOSDriver driver;
@BeforeClass //этот метод выполняется перед каждым тестом
public void setUp() throws MalformedURLException{
DesiredCapabilities caps = new DesiredCapabilities();
File app=new File("path of the .app");
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "8.1");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"iPad");
caps.setCapability("udid","UDID вашего устройства");
caps.setCapability(MobileCapabilityType.BROWSER_NAME, "Safari");//в случае, если работаем с веб-приложением
driver = new IOSDriver (new URL("https://127.0.0.1:4723/wd/hub"), caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
public void testExample(){
//здесь шаги теста
}
@AfterClass
public void tearDown(){
driver.closeApp();
//driver.quit(); //в случае, если работаем с веб-приложением
}
}
Автоматизация нативных приложений
Нативные приложения на Android
В случае с автоматизацией Android, сработает тот же код, что и в предыдущей главе (тестировали на эмуляторе), только нужно удалить информацию про avd.
Давайте разберем пример набора номера на Android:
- Установите следующие desired capabilities, для запуска приложения dialer
caps.setCapability(MobileCapabilityType.APP_PACKAGE, "com.android.dialer"); caps.setCapability(MobileCapabilityType.APP_ACTIVITY, "com.android.dialer.DialtactsActivity");
- Теперь нужно найти dial pad. Искать будем по AccessibityId
WebElement dialPad= driver.findElementByAccessibilityId("dial pad"));
- Клик
dialPad.click();
- Нужно найти клавиши с цифрами. Задействуем немного логики, чтобы найти клавиши 0-9 по name и кликнем каждую из них
for(int n=0;n<10;n++){ driver.findElement(By.name(""+n+"")).click(); }
- В данном случае, мы используем некорректный номер телефона, так что телефон никуда не позвонит
- Давайте найдем кнопку вызова. Искать будем по AccessibilityId:
WebElement dial= driver.findElementByAccessibilityId("dial"));
- Клик:
dial.click();
- Весь скрипт, с использованием TestNG, будет выглядеть вот так:
public class TestAppIication { AndroidDriver driver; @BeforeClass public void setUp() throws MalformedURLException{ DesiredCapabilities caps = new DesiredCapabilities(); caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4"); caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android"); caps.setCapability(MobileCapabilityType.DEVICE_NAME,"Moto X");//I am using Moto X as Real Device caps.setCapability(MobileCapabilityType.APP_PACKAGE, "com.android.dialer"); caps.setCapability(MobileCapabilityType.APP_ACTIVITY, "com.android.dialer.DailtactsActivity"); driver = new AndroidDriver (new URL("https://127.0.0.1:4723/wd/hub"), caps); driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS); } @Test public void testExample(){ WebElement dialPad=driver.findElementByAccessibilityId("dial pad"); dialPad.click(); for(int n=0;n<10;n++){ driver.findElement(By.name(""+n+"")).click(); } WebElement dial=driver.findElementByAccessibilityId("dial"); dial.click(); } @AfterClass public void tearDown(){ driver.closeApp(); } }
Нативные приложения на iOS
Здесь мы поработаем с калькулятором BMI
Мы рассчитаем индекс массы тела по весу и росту. Для этого, делаем следующее:
- Установите следующие desired capabilities, для запуска приложения
File app=new File("/Users/mhans/appium/ios/BmiCalc.app");//You can change it with your app address caps.setCapability(MobileCapabilityType.APP,app);//To set the app path
- Теперь нужно найти поля ввода роста и веса. Будем искать по Xpath
WebElement height=driver.findElement(By.xpath("(//UIATextField)[2]")); WebElement weight=driver.findElement(By.xpath("(//UIATextField)[4]"));
- Ищем кнопку calculate. Используем name:
WebElement calculateBMI=driver.findElement(By.name("Calculate BMI"));
- Указываем рост
height.sendKeys("1.82");
- Указываем вес
weight.sendKeys("75");
- Считаем индекс
calculateBMI.click();
- Весь скрипт, с использованием TestNG, будет выглядеть вот так:
public class TestAppIication { IOSDriver driver; @BeforeClass public void setUp() throws MalformedURLException{ File app=new File("/Users/mhans/appium/ios/BmiCalc.app");//You can change it with your app address DesiredCapabilities caps = new DesiredCapabilities(); caps.setCapability(MobileCapabilityType.APP,app); caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "8.1"); caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS"); caps.setCapability(MobileCapabilityType.DEVICE_NAME,"iPad"); caps.setCapability("udid","Real Device Id "); driver = new IOSDriver (new URL("https://127.0.0.1:4723/wd/hub"), caps); driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS); } @Test public void testExample(){ WebElement height=driver.findElement(By.xpath("(//UIATextField)[2]")); height.sendKeys("1.82"); WebElement weight=driver.findElement(By.xpath("(//UIATextField)[4]")); weight.sendKeys("75"); WebElement calculateBMI=driver.findElement(By.name("Calculate BMI")); calculateBMI.click(); } @AfterClass public void tearDown(){ driver.closeApp(); } }
Автоматизация веб приложений
Веб приложения на Android
Для примера, рассмотрим страницу авторизации в Gmail. В этом разделе, мы посмотрим, как запустить Chrome на реальном устройстве, перейти по нужному адресу, передать логин/пароль и нажать SignIn
- Установите следующие desired capabilities, для запуска Chrome
caps.setCapability(MobileCapabilityType.BROWSER_NAME, "Chrome");
- Теперь нужно указать адрес
driver.get("https://www.gmail.com");
- Нужно найти элемент username. Используем локатор name
WebElement username=driver.findElement(By.name("Email"));
- Передаем значение
username.sendKeys("test");
- Теперь, нужно найти элемент password. Используем локатор name
WebElement password=driver.findElement(By.name("Passwd"));
- Передаем значение
password.sendKeys("test");
- Ищем кнопку SignIn. Используем локатор name
WebElement signIn=driver.findElement(By.name("signIn"));
- Клик
signIn.click();
- Весь скрипт, с использованием TestNG, будет выглядеть вот так:
public class TestAppIication { AndroidDriver driver; @BeforeClass public void setUp() throws MalformedURLException { DesiredCapabilities caps = new DesiredCapabilities(); caps.setCapability(MobileCapabilityType.BROWSER_NAME, "Chrome"); caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4"); caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android"); caps.setCapability(MobileCapabilityType.DEVICE_NAME,"Moto X"); driver = new AndroidDriver (new URL("https://127.0.0.1:4723/wd/hub"), caps); driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS); } @Test public void testExample(){ driver.get("https://www.gmail.com"); WebElement username=driver.findElement(By.name("Email")); username.sendKeys("test"); WebElement password=driver.findElement(By.name("Passwd")); password.sendKeys("test"); WebElement signIn=driver.findElement(By.name("signIn")); signIn.click(); } @AfterClass public void tearDown(){ driver.quit(); } }
Веб приложения на iOS
Для примера, рассмотрим страницу поиска в Google. В этом разделе, мы посмотрим, как запустить браузер на реальном устройстве, перейти по нужному адресу, передать строку для поиска и нажать Search
- Установите следующие desired capabilities, для запуска Safari
caps.setCapability(MobileCapabilityType.BROWSER_NAME, "Safari");
- Теперь нужно указать адрес
driver.get("https://www.google.com");
- Нужно найти элемент searchBox. Используем локатор name
WebElement searchBox=driver.findElement(By.name("q"));
- Передаем значение
searchBox.sendKeys("Appium for mobile automation");
- Перед запуском скрипта, нам нужно будет включить прокси командой:
ios_webkit_debug_proxy -c 2e5n6f615z66e98c1d07d22ee09658130d345443:27753 –d
Замените 2e5n6f615z66e98c1d07d22ee09658130d345443 на UDID вашего девайса. Порт должен быть 27753
- Убедитесь, что Web Inspector включен (Settings | Safari | Advanced) и SafariLauncher установлен на ваш девайс
- Весь скрипт, с использованием TestNG, будет выглядеть вот так:
public class TestAppIication { IOSDriver driver; @BeforeClass public void setUp() throws MalformedURLException{ DesiredCapabilities caps = new DesiredCapabilities(); caps.setCapability(MobileCapabilityType.BROWSER_NAME, "Safari"); caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "8.1"); caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS"); caps.setCapability(MobileCapabilityType.DEVICE_NAME, "iPad"); caps.setCapability("udid","Real Device Identifier"); driver = new IOSDriver (new URL("https://127.0.0.1:4723/wd/hub"), caps); driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS); } @Test public void testExample(){ driver.get("https://www.google.com"); WebElement searchBox=driver.findElement(By.name("q")); searchBox.sendKeys("Appium for mobile automation"); } @AfterClass public void tearDown(){ driver.quit(); } }
Автоматизация гибридных приложений
Гибридные приложения на Android
Для примера, будем работать с Hybridtestapp
Для работы с гибридными приложениями, нужно выполнить изменения, указанные здесь. В нашем приложении Hybridtestapp, они уже применены.
В примере попробуем заполнить форму в приложении:
- Установите следующие desired capabilities, для запуска гибридного приложения
File app=new File("C:\Appium_test\HybridtestApp.apk");// (On window platform) caps.setCapability(MobileCapabilityType.APP,app); caps.setCapability(MobileCapabilityType.APP_PACKAGE, "com.example.hybridtestapp"); caps.setCapability(MobileCapabilityType.APP_ACTIVITY, "com.example.hybridtestapp.MainActivity");
- Теперь нужно сменить контекст, чтобы работать с WebView
Set<String> contexts = driver.getContextHandles(); for (String context : contexts) { System.out.println(context); //выводим список контекстов }
- Переключаем
driver.context("WEBVIEW_com.example.hybridtestapp");
или
driver.context((String) contextNames.toArray()[1]);
- После перехода в WebView, нам нужно найти поле ввода First Name. Искать будем по локатору name
WebElement firstName=driver.findElement(By.name("fname")); firstName.sendKeys("test");
- И Last Name
WebElement lastName=driver.findElement(By.name("lname")); lastName.sendKeys("test");
- Таким образом заполняем остальные поля
WebElement age=driver.findElement(By.name("age")); age.sendKeys("26"); WebElement username=driver.findElement(By.name("username")); username.sendKeys("appiumTester"); WebElement password=driver.findElement(By.id("psw")); password.sendKeys("appium@123");
- И кликаем на копку Register
WebElement registerButton=driver.findElement(By.id("register")); registerButton.click();
- Весь скрипт, с использованием TestNG, будет выглядеть вот так:
public class TestAppIication { AndroidDriver driver; @BeforeClass public void setUp() throws MalformedURLException{ File app=new File("C:\Appium_test\HybridtestApp.apk"); caps.setCapability(MobileCapabilityType.APP,app); DesiredCapabilities caps = new DesiredCapabilities(); caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4"); caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android"); caps.setCapability(MobileCapabilityType.DEVICE_NAME, "Moto X"); caps.setCapability(MobileCapabilityType.AUTOMATION_NAME, "Appium");//Используйте Selendroid если версия android ниже 4.4 caps.setCapability(MobileCapabilityType.APP_PACKAGE, "com.example.hybridtestapp"); caps.setCapability(MobileCapabilityType.APP_ACTIVITY, "com.example.hybridtestapp.MainActivity"); driver = new AndroidDriver (new URL("https://127.0.0.1:4723/wd/hub"), caps); driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS); } @Test public void testExample(){ Set<String> contexts = driver.getContextHandles(); for (String context : contexts) { System.out.println(context); } driver.context((String) contexts.toArray()[1]); WebElement firstName=driver.findElement(By.name("fname")); firstName.sendKeys("test"); WebElement lastName=driver.findElement(By.name("lname")); lastName.sendKeys("test"); WebElement age=driver.findElement(By.name("age")); age.sendKeys("26"); WebElement username=driver.findElement(By.name("username")); username.sendKeys("appiumTester"); WebElement password=driver.findElement(By.id("psw")); password.sendKeys("appium@123"); WebElement registerButton=driver.findElement(By.id("register")); registerButton.click(); } @AfterClass public void tearDown(){ driver.closeApp(); } }
Гибридные приложения на iOS
Пример будем рассматривать на приложении WebViewApp
Пробуем работать с приложением:
- Установите следующие desired capabilities, для запуска гибридного приложения
File app=new File("/Users/mhans/appium/ios/WebViewApp.app"); caps.setCapability(MobileCapabilityType.APP,app);
- Теперь нужно найти поле ввода и указать нужный адрес
WebElement editBox=driver.findElement(By.className("UIATextField")); editBox.sendKeys("www.google.com");
- Ищем и кликаем кнопку Go
WebElement goButton=driver.findElement(By.name("Go")); goButton.click();
- Теперь нужно сменить контекст, чтобы работать с WebView
Set<String> contexts = driver.getContextHandles(); for (String context : contexts) { System.out.println(context); }
- Переключаем
driver.context("WEBVIEW_com.example.testapp");
или
driver.context((String) contextNames.toArray()[1]);
- Все. Можем работать со страницей google. Пробуем открыть кладку Images:
WebElement images=driver.findElement(By.linkText("Images")); images.click();
- Перед запуском всего теста, нужно включить прокси
ios_webkit_debug_proxy -c <UDID >:27753 –d
Порт должен быть 27753
- Весь скрипт, с использованием TestNG, будет выглядеть вот так:
public class TestAppIication { IOSDriver driver; @BeforeClass public void setUp() throws MalformedURLException{ DesiredCapabilities caps = new DesiredCapabilities(); File app=new File("/Users/mhans/appium/ios/WebViewApp.app"); caps.setCapability(MobileCapabilityType.APP,app); caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "8.1"); caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS"); caps.setCapability(MobileCapabilityType.DEVICE_NAME, "iPad"); caps.setCapability("udid","Real Device Identifier"); driver = new IOSDriver (new URL("https://127.0.0.1:4723/wd/hub"), caps); driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS); } @Test public void testExample(){ WebElement editBox=driver.findElement(By.className("UIATextField")); editBox.sendKeys("https://www.google.com"); WebElement goButton=driver.findElement(By.name("Go")); goButton.click(); Set<String> contexts = driver.getContextHandles(); for (String context : contexts) { System.out.println(context); } driver.context((String) contexts.toArray()[1]); WebElement images=driver.findElement(By.linkText("Images")); images.click(); } @AfterClass public void tearDown(){ driver.closeApp(); } }
Вот и все. У нас осталась последняя глава, в которой мы посмотрим, как имитировать специфичные, для мобильной платформы, пользовательские действия.
Автор: EreminD