So far, we have seen how to connect the mobile device in Appium Desktop.
Now it’s time to see how we can connect the device and start testing the app using Java. Hence Java is our preferred language for this training, I will try to include code snippets for Python as well.
How to connect to Appium using Java code?
As we all know Appium will connect to any mobile device with the help of DesiredCapability. In this session we are going to discuss about how internally our Java code is communicating with Appium with the help of Appium libraries.
Have you ever worked in Selenium grid? If yes, then it will be very easy for you guys to understand the Appium design. For example, in Selenium Grid we will use DesiredCapability to help Selenium grid library to identify the nodes right? Appium also uses the same methodology. Appium server acts as a Hub and the mobiles devices/ Simulators/Emulators connected will be treated as a Node. Please go through Appium architecture in our previous Blog in case of any doubts.
How to connect device using Java code via Appium?
To access Appium from our java code, we need to include the same “DesiredCapabilities” and its attributes that we used to connect mobile with Appium desktop.
In appium desktop we used GUI, but in our java program we need to include a class called “DesiredCapabilities” form the package “org.openqa.selenium.remote. DesiredCapabilities” to identify the device connected using Key/Value pair.
Have you noticed the package name? Yes we are importing it from Selenium grid support libraries. With the help of method setCapability we can get the mobile device attributes using the interface “MobileCapabilityType”. Syntax Below,
DesiredCapabilities cap = new DesiredCapabilities();
cap.setCapability(MobileCapabilityType.PLATFORM_NAME, “Android”);
here, DesiredCapabilities is a class and we are creating a strong reference called ‘cap’.
With the help of ‘cap’ we are calling the function/Method ‘setCapability’ and invoking the interface ‘MobileCapabilityType’ which extends its parent ‘CapabilityType’.
Remember the below important facts may be helpful at the time of Interview,
- DesiredCapabilities is a class
- Parent class for DesiredCapabilities is MutableCapabilities Class
- setCapability is a method that is inherited from the class MutableCapabilities
- MobileCapabilityType is an Interface which extends org.openqa.selenium.remote.CapabilityType
Using which capabilities Appium will find the Mobile Device?
Depends on the platformName, platform version or automationName given in the capabilities, the corresponding bootstrap loader will be triggered from Appium to find the device connected. Set of basic mobile capabilities are listed below.
Below diagram illustrates how Appium communicates with device.
How to open test App using Java code?
I don’t want to showcase any Native apps like calculator or Gallery in this session, We will see some real app in order to understand the functionality. To start our test execution we can follow two approaches,
- Using Appium desktop Server
- Using Appium command line
In this article, we will figure out using Method 1: Running our test with the help of “Appium Desktop Server”. In future blogs I will let you know how to install and use “Appium command line”
What is AppiumDriver?
AppiumDriver is a Class with a parent “RemoteWebDriver” having “AndroidDriver” and “iOSDriver” as its direct subclass. It means if we declare our driver as an AppiumDriver we can either initiate it as an AndroidDriver or iOSDriver based on our need.
For executing Android based devices we will use “AndroidDriver<?>” <T extends WebElement> can be “AndroidElement”
For executing Android based devices we will use “AndroidDriver<?>” <T extends WebElement> can be “iOSElement”
Before starting with the code, Make sure Appium Desktop is running in the background. It should have initiated its Localhost with the given proxy number. Like this,
Note: Once again before running the code, make sure Appium is running in the background else your code will return an exception “org.openqa.selenium.WebDriverException” “Connection refused: connect”.
Please find the sample code for launching an Android app in Java:
In this sample code, we launched the android app in real device with a basic DesiredCapabilities. Note: TestNG annotations are used only to maintain the test.
import java.net.URL;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.remote.AutomationName;
import io.appium.java_client.remote.MobileCapabilityType;
public class Testengine {
public static AppiumDriver<?> driver;
@BeforeMethod
public void startAppium() {
try {
DesiredCapabilities cap = new DesiredCapabilities();
cap.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
cap.setCapability(MobileCapabilityType.PLATFORM_VERSION, "9");
cap.setCapability(MobileCapabilityType.DEVICE_NAME, "5642c6b9");
cap.setCapability("appActivity", "com.invoiceapp.InvoiceLaunchScreenAct");
cap.setCapability("appPackage", "com.invoiceapp");
cap.setCapability("autoLaunch", false);
cap.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 500);
cap.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.ANDROID_UIAUTOMATOR2);
driver = new AndroidDriver<AndroidElement>(new URL("http://127.0.0.1:4723/wd/hub"), cap);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void test001() {
driver.launchApp();
}
@AfterMethod
public void tearDown() {
driver.quit();
}
}
In the above code I used TestNG just to maintain the hierarchy. In the @Test annotation I’m simply trying to launch the app. No testing has been performed here. Please find the screenshot below for Appium logs, and read the logs completely to understand how it works.
Please find the sample code for launching an iOS app in Java:
import java.net.URL;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;
import io.appium.java_client.remote.AutomationName;
import io.appium.java_client.remote.MobileCapabilityType;
public class Testengine {
public static AppiumDriver<?> driver;
@BeforeMethod
public void startAppium() {
try {
DesiredCapabilities cap = new DesiredCapabilities();
cap.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");
cap.setCapability(MobileCapabilityType.PLATFORM_VERSION, "13.3");
cap.setCapability(MobileCapabilityType.DEVICE_NAME, "iOSDeviPad");
cap.setCapability("bundleId", "com.invoice.manager");
cap.setCapability("udid", "f209a1bc7c7eewf4543rweafdf96645be83fc615bfe3a");
cap.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 100);
cap.setCapability(MobileCapabilityType.AUTOMATION_NAME, "XCUITest");
driver = new IOSDriver<IOSElement>(new URL("http://127.0.0.1:4723/wd/hub"), cap);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void test001() {
driver.launchApp();
}
@AfterMethod
public void tearDown() {
//driver.quit();
}
}
In Python to Initiate Appium for an iOS application:
Please find the sample code below, to initiate Appium using Pytest framework. This will also work in UnitTest framework it’s up to you on which framework you are using. I prefer to use Pytest because it is having some advanced features when compared with UnitTest. Here also we are following the same desiredCapabilities.
In python, we use dictionary to send the DesiredCapabilities to Appium.
Points to Remember:
- The capability “Automation_Name” is optional, but it is always a good practice to mention this capability.
- UDID in iOS and Device_Name for Android are optional if we connect with only 1 device, but when it comes to multiple devices and emulators “Device_Name” is really mandatory else Appium bootloader will pick based on Platform Version.
- For Android, if we are using Emulators, it is must to mention the “AVD” capability because Appium will prefer the Emulator even if real device is connected (this happens only if both devices and emulator android version are same)
- Make sure to get the exact application activity for Android based application, else Appium will not initiate the connectivity
- Sometimes WDA (WebDriverAgent) will uninstall automatically when launching app via Appium, This happens only if we use same device in different Mac machine to perform execution. So it is always good to have a dedicated iPhones for the Mac.
Please let me know in comments whether to include Python syntax also in our blog, else we will focus only on Java.
Cheers!!
Naveen AutomationLabs
Blog Contributors:
Author: Ragavendran
Ragav, having 10+ years of testing experience on which 7 years of rich experience in automation using UFT, Selenium (Java/Python). Expertise in Web and Mobile automation testing using Appium.
https://www.linkedin.com/in/Ragavendran-Ragav
Reviewer: Naveen Khunteta
Hi Ragav,
Awesome Content..Keep it up..let’s focus on Java syntax only. Thank you so much for sharing your Knowledge.
Cheers!