Wednesday, 27 January 2016

How to Start Appium Server Programmatically?

      Now let’s look on how to start Appium Server Programmatically.


So here we use two Appium classes

1.AppiumDriverLocalService

2.AppiumServiceBuilder

Exceptions can be :

1.AppiumServerHasNotBeenStartedLocallyException
2.InvalidNodeJSInstance
3.InvalidServerInstanceException

1.AppiumDriverLocalService: Here I am going to list only few simple methods which can be used with this class.

Modifier and Type
Method and description
static AppiumDriverLocalService
buildDefaultService()
static AppiumDriverLocalService
buildService(AppiumServiceBuilder builder)
boolean
isRunning()
void
start() Starts the defined appium server
void
stop() Stops this service is it is currently running.
URL
getUrl()

2.AppiumServiceBuilder: Similarly here some of the methods that can be used .

Modifier and Type
Method and description
AppiumServiceBuilder
usingAnyFreePort()Configures the appium server to start on any available port.
AppiumServiceBuilder
usingDriverExecutable(File nodeJSExecutable)
Sets which Node.js the builder will use.
AppiumServiceBuilder
usingPort(int port)
Sets which port the appium server should be started on.A value of 0 indicates that any free port may be used.
AppiumServiceBuilder
withAppiumJS(File appiumJS)
AppiumServiceBuilder
withLogFile(File logFile)
Configures the appium server to write log to the given file.

Since we need to start Appium server before testcase run lets use @BeforeClass annotation.
Try this::
@BeforeClass
AppiumDriverLocalService service = AppiumDriverLocalService.buildService(new AppiumServiceBuilder().usingAnyFreePort().usingDriverExecutable(new File("path to node")).withAppiumJS(new File("path to appium.js")));

To start the server:
service.start()

To stop the server which can be called after all execution of testcases:
service.stop()

For Ubuntu Users::
How to find path to node?
Open Terminal and type which node .If node.js is installed it will show output similar
/home/deepa/.linuxbrew/bin/node

Note :@BeforeClass and @AfterClass should be defined as static.
AppiumDriverLocalService should be static.
stop() and start() should be defined as void.

To start the server programmatically you have to remove this line in your previous program
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), cap);
and replace with
driver = new AndroidDriver(new URL(service_url),cap);
Where service_url =service.getUrl().toString();

For test with below code use this apk:APK to be downloaded for this example

Complete code:(Changed code marked in blue w.r.t First Test Case in my blog:Your First TestCase)

package com.test.helloworld;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.MobileCapabilityType;
import io.appium.java_client.remote.MobilePlatform;
import io.appium.java_client.service.local.AppiumDriverLocalService;
import io.appium.java_client.service.local.AppiumServiceBuilder;

public class AppiumTest {
   AndroidDriver driver;
   static AppiumDriverLocalService service;
   static String service_url;

   @BeforeClass
   public static void appiumServer() throws Exception {
       service = AppiumDriverLocalService.buildService(new AppiumServiceBuilder().usingPort(0).usingDriverExecutable(new File("path to node")).withAppiumJS(new File("path to appium.js")));
       service_url = service.getUrl().toString();
       service.start();
   }

   @Before
   public void testCaseSetUp() throws MalformedURLException {
       File appDir = new File("src");
       File app = new File(appDir, "app-debug.apk");
       DesiredCapabilities cap = new DesiredCapabilities();
       cap.setCapability(MobileCapabilityType.PLATFORM_NAME, MobilePlatform.ANDROID);
       cap.setCapability(MobileCapabilityType.DEVICE_NAME, "Android device");
       cap.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, "100");
       cap.setCapability(MobileCapabilityType.APP, app.getAbsolutePath());
       driver = new AndroidDriver(new URL(service_url),cap);
       //fresh installs the app everytime if fullReset to True
       cap.setCapability("fullReset", true);
   }

   @Test
   public void testHelloWorld() throws Exception {
       //find text HelloWorld and assert
       WebElement text1 = driver.findElement(By.xpath("//android.widget.TextView[@index='0']"));
       Assert.assertEquals("HelloWorld", text1.getText());
       //Click Menu and asset settings
       driver.findElementByName("More options").click();
       Assert.assertEquals("Settings", driver.findElementById("title").getText());
   }

   @After
   public void testCaseTearDown() {
       if (driver != null)
           driver.quit();
   }

   @AfterClass
   public  static  void stopServer(){
       service.stop();
   }
}

Now run the test (since I have used Android Studio here is the screenshot of the same)

Monday, 25 January 2016

Your First TestCase

After set-up now you can write your first Test case:
  
1.First create the folder->click main in app folder->Right click on the package ->Click on 'create Java Class.

2.Set Desired Capabilities:
Desired capabilities are options that can be used to customize and configure the browser session.
This tells Appium server what kind of automation we're interested in.

automationName   :which automation engine to use: Appium(default) or Selendroid
platformName     : which mobile OS              : iOS ,Android,FirefoxOS
platformVersion  : Mobile OS version            : 5.1,7.1,4.0
deviceName           :  Kind of mobile device or emulator: Galaxy S4,iPad Simulator
app                         :The absolute local path or remote URL to .ipa or .apk file:/abs/path/to/my.apkor   http://myapp.com/app.ipa(Note that this capability is not required for Android if you specify appPackage and   appActivity capabilities )
browserName       : Name of mobile web browser to automate. Should be an empty string if automating an app instead.‘Safari’ for iOS and ‘Chrome’, ‘Chromium’, or ‘Browser’ for Android
newCommandTimeout :How long (in seconds) Appium will wait for a new command from the client before assuming the client quit and ending the session:
autoLaunch        :Whether to have Appium install and launch the app automatically. Default true

There is no need to mention all the desired capabilities
Now you need to mention only:platform name
                                                  device name
                                                   app
DesiredCapabilities cap=new DesiredCapabilities();
cap.setCapability(MobileCapabilityType.PLATFORM_NAME,MobilePlatform.ANDROID);
cap.setCapability(MobileCapabilityType.DEVICE_NAME, "Android device");
cap.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, "100");
cap.setCapability(MobileCapabilityType.APP, app.getAbsolutePath());

3.Apk file
For your first program lets copy the apk file and paste in the source folder of your project.
For this example use this apk Apk file to Download

4.Next need to set the path of the apk file.
File appDir = new File("src");
File app = new File(appDir, "app-debug.apk");

5.Pass this absolute path to desired capabilities
cap.setCapability(MobileCapabilityType.APP, app.getAbsolutePath());

6.Invoke driver:
For Android : AndroidDriver
For iOS        :iOS Driver
You need to create an object for Android driver class and pass two parameter.

1.Appium server listens to localhost in port 4723(http://127.0.0.1:4723/wd/hub)
2.Pass desired capabilities to server (so pass ‘cap’ as second argument)
AndroidDriver driver;
driver=new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),cap );

7.Test Case here is:
Here we will install the app and check if there is a text HelloWorld and click on menu which shows settings.

Now open uiautomatorviewer (navigate to tools folder and type uiautomatorviewer)and find the elements unique identifier.

In Appium you have to do trial and error to locate the elements.

a)Here HelloWorld can be found using Xpath .
Screenshot from 2016-01-25 19:34:50.png
//To find the HelloWorld
WebElement text1 = driver.findElement(By.xpath("//android.widget.TextView[@index='0']"));
//Assert the text displayed is same
Assert.assertEquals("HelloWorld", text1.getText());

b)Click on  Menu Object identifier(here Menu is found using content-description).Screenshot from 2016-01-25 19:35:28.png
driver.findElementByName("More options").click();

c)Settings (On Menu click Settings should be displayed).This is checked using Assert statements.
Screenshot from 2016-01-25 19:36:00.png
Assert.assertEquals("Settings",driver.findElementById("title").getText());

8)Use JUnit or TestNG framework.
Here we are using JUnit Test framework
JUnit test framework which uses annotations to identify methods that specify a test.
Some of the most used annotations:
@Test                       : The @Test annotation identifies a method as a test method.
@Test(timeout=100) : Fails if the method takes longer than 100 milliseconds.
@Before                    : This method is executed before each test.
@After                       : This method is executed after each test.
@BeforeClass           : This method is executed once, before the start of all tests.Method
                                    annotated with this should be defined as static.
@AfterClass              : This method is executed once, after all tests have been finished.Method
                                    annotated with this should be defined as static.
@Ignore                    : Ignores the test method.                                          

9)Here is the snippet of the code

Before executing the testcase(pass the capabilities to the appium server hosted on local server on port 4723).You can change the port to any free port.

@Before
public void testCaseSetUp() throws MalformedURLException {
  File appDir = new File("src");
  File app = new File(appDir, "app-debug.apk");
  DesiredCapabilities cap = new DesiredCapabilities();
  cap.setCapability(MobileCapabilityType.PLATFORM_NAME, MobilePlatform.ANDROID);
  cap.setCapability(MobileCapabilityType.DEVICE_NAME, "Android device");
  cap.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, "100");
  cap.setCapability(MobileCapabilityType.APP, app.getAbsolutePath());
  driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), cap);
  cap.setCapability("fullReset", true);
}

After testcase is executed(quit the driver)
@After
public void testCaseTearDown()
{
  if (driver != null)
      driver.quit();
}

Testcase:1.Check Hello world is displayed
  2.Click on Menu
  3.Check ‘Settings’ is displayed
@Test
public void testHelloWorld() throws Exception {
  //find text HelloWorld and assert
  WebElement text1 = driver.findElement(By.xpath("//android.widget.TextView[@index='0']"));
  Assert.assertEquals("HelloWorld", text1.getText());

  //Click Menu and asset settings
  driver.findElementByName("More options").click();
  Assert.assertEquals("Settings", driver.findElementById("title").getText());
}

10.Complete code
package com.test.helloworld;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.MobileCapabilityType;
import io.appium.java_client.remote.MobilePlatform;
public class AppiumTest {
  AndroidDriver driver;
  @Before
  public void testCaseSetUp() throws MalformedURLException {
      File appDir = new File("src");
      File app = new File(appDir, "app-debug.apk");
      DesiredCapabilities cap = new DesiredCapabilities();
      cap.setCapability(MobileCapabilityType.PLATFORM_NAME, MobilePlatform.ANDROID);
      cap.setCapability(MobileCapabilityType.DEVICE_NAME, "Android device");
      cap.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, "100");
      cap.setCapability(MobileCapabilityType.APP, app.getAbsolutePath());
      driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), cap);
      cap.setCapability("fullReset", true);
  }
  @Test
  public void testHelloWorld() throws Exception {
      //find text HelloWorld and assert
      WebElement text1 = driver.findElement(By.xpath("//android.widget.TextView[@index='0']"));
      Assert.assertEquals("HelloWorld", text1.getText());
      //Click Menu and asset settings
      driver.findElementByName("More options").click();
      Assert.assertEquals("Settings", driver.findElementById("title").getText());
  }
  @After
  public void testCaseTearDown()
  {
      if (driver != null)
          driver.quit();
  }
}

11.How to run the TestCase:
a)Set the build variant to unit test
b)Type appium on terminal and start the server
c)Right click on TestClass and Click on Run

Build variant Set-up


Appium server start
Screenshot from 2016-01-25 23:24:50.png

Appium logs after test executed
                                                                                                                                                            
Screenshot from 2016-01-25 23:25:42.png
Android Studio Terminal after testcases executed
Screenshot from 2016-01-25 23:26:10.png
Done!!!!!!!