Chapter-2: Writing Your First Test Case - Kobiton

Chapter-2: Writing Your First Test Case

Chapter-2: Writing Your First Test Case

And now the moment you’ve been waiting for: Writing your first test case. You’ll quickly grasp the basics of Appium and see how it can be used for test automation.

We’re going to cover a lot of ground in this chapter but it will be well worth it. By the end of this chapter you’ll have grasped the basics of Appium and writing test cases.

Appium supports Native, Hybrid and Web application testing, and you can execute Appium scripts on Real Physical devices(iOS/Android), simulators(iOS) and emulators(Android).

The best thing about Appium is it has no dependency on the Mobile OS or Mobile Application, meaning you can Appium scripts can run everywhere. For Automation Testing with Appium you will just need the APK or IPA file.

Under the hood, Appium is just wrapper that translates Selenium Webdriver commands into XCUITest for iOS and UiAutomator2 for Android. XCUITest and UiAutomator2 are Test frameworks for XCode and Android Studio respectively.

Appium supports all the programming languages which Selenium supports such as Java, C#, Python, Ruby, Javascript with Node.js etc.

For the examples that follow, we will be using Java since Appium was written in Java, and you can find many resources online on Appium and Java, which makes your learning journey a little easier. In our examples we will be using a Mac, but of course you will be fine on any supported operating system.

Please make sure you followed the previous chapter and installed Appium properly. Now that Appium is installed, we’ll be installing our development environment. If you already have a development environment installed, you can skim through the steps that follow. However, it may be easier for you to follow these instructions and have your environment mimic ours for easier reference.

Note: The steps may seem a little daunting especially when you want to write a simple test case. However, this is really a one-time effort. Once your environment is configured and you’re comfortable with concepts such as dependency management, you’ll find writing the Appium scripts is a relatively straightforward task. So stay with us through this section, and it will get easier, we promise.

We will start by installing an IDE to create Java based Appium Scripts. You can either select IntelliJ IDEA or Eclipse IDE (or any IDE of your choice). We will be using IntelliJ.

To summarize, we will use the following to create our Appium Script:

  • Programming Language: Java
  • Test Framework: TestNG
  • IDE: IntelliJ IDEA
  • Project Dependency Tool: Gradle

 

There are 2 primary things to accomplish in this chapter:

  • Setup the IDE (IntelliJ IDEA).
  • Create the First Automation Test Case. Note that Appium is used to drive or control the underlying mobile application in order to perform automation on it. However, you still need some testing framework for implementation of the actual tests. We will be using the TestNG framework for this purpose.

 

Setup the IDE (IntelliJ IDEA)

In order to sethup the IDE you need to:

  • Install the intelliJ IDEA
  • Install the TestNG plugin on IntelliJ IDEA.

 

Installation of IntelliJ IDEA

 

  • Install it by dragging and dropping:

 

Figure-1: Installation of IntelliJ IDEA Community Edition.

 

  • If you are installing IntelliJ Idea first time, then you need to select the “ Do not import settings” option.

 

Figure-2: Complete the Installation.

 

  • Accept the IntelliJ IDEA Privacy Policy Agreement:

 

Figure-3: Policy Agreement.

 

  • Set your preferred theme and click on Next:

 

Figure-4: Set UI Theme.

 

  • Select the default plugins, and Finish the setup.

 

Install the TestNG plugin on IntelliJ IDEA

 

By default the TestNG plugin is installed in IntelliJ IDEA. You can check it in several ways but the best way is to check it is in Plugins.

  • Open IntelliJ Idea and click on Configure > Plugins.

 

Figure-5: Go to IntelliJ IDEA Plugins.

 

  • Type ‘testng’ and search it, if it is installed properly you can see the Right tick icon right next to ‘TestNg’ text. And if it is not installed you need to install by clicking on Install JetBrains plugin… > Search for ‘testng’ > Install it.

 

Figure-6: Check IntelliJ Plugin.

 

Create your first automation test case

We need to create a new project and than need to setup the Automation script, so we can divide this into 2 sections:

  • Create New Project.
  • Setup the Automation Case.

 

Create new project

 

  • Open IntelliJ IDEA and click on `Create New Project`

 

Figure-7: Create New Project.

 

  • Now we need to select the project configuration such as Project type, Java version, and Build tool. We can either use Maven OR Gradle, but since Gradle is more flexible we will be using that for our tutorial. However you can use Maven if you prefer (We just need to add few dependencies).

 

Figure-8: Create New Project.

 

  • Give the proper GroupId and ArtifactId(Project Name) and Version.

 

Figure-9: Enter GropuId, ArtifactId and Version.

 

NOTE: For better project management it is better to give a proper Group Id and Artifact Id.  

Visit: http://maven.apache.org/guides/mini/guide-naming-conventions.html  to learn more about it.

 

  • This is the Gradle selection dialog, If you haven’t installed Gradle explicitly it is  recommended to the Use default gradle wrapper (recommended)

 

 

Figure-10: Select ‘Use default gradle wrapper (recommended)’

 

  • Confirm all the project details and Finish the setup.

 

Figure-11: Confirm Project Details.

 

  • After the setup is finished, gradle will build the project and it may take some time (especially for the first time, because it will download the Gradle .zip file). After the sync up is done you can see the Project Directory as per the below image.

Now we are ready to add Appium dependencies and then start coding the first automation test case.

 

Figure-12: IntelliJ IDEA: Project - First Automation Test

 

Setup the automation case

The first step of any project setup is to download and link the needed libraries/files referred to as dependencies. Gradle and Maven are dependency management tools and have a large number of remote dependencies.

 

So let’s understand how Gradle works:

  • Modern software projects rarely build code in isolation. Projects reference modules for the purpose of reusing existing and proven functionality.
  • Selected versions of modules are downloaded from dedicated repositories(from remote servers)
  • And they are stored in the dependency cache to avoid unnecessary network traffic.

 

Figure-13: Gradle Build System

 

Declaring a concrete version of a dependency:

  • A typical example for such a library in a Java project is the Automation testing library which is Selenium.
  • The following code snippet declares a compile-time dependency on the Spring web module by its coordinates:

build.gradle:

sourceCompatibility = 1.8

repositories {

   mavenCentral()

}

dependencies {

   compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.14.0'

}
  • The above code snippet declares a compile-time dependency of Selenium library(.JAR file), So when you build the project Gradle will download the Selenium library having version 3.14.0 from mavenCentral(remote registry) and store it in the Gradle cache, so when you mention this same library with the same version next time on a different project, Gradle will link the library from the Gradle cache.

 

Here we need 2 dependencies:

  • Appium Java Client - Mobile Automation Appium Library.
  • TestNG - Test Framework.

Now continue to our project, open build.gradle file and add the following dependencies to the build.gradle file.

dependencies {

testCompile group: 'io.appium', name: 'java-client', version: '6.1.0'

testCompile group: 'org.testng', name: 'testng', version: '6.14.3'

}

 

NOTE-1: As we already have the TestNG plugin installed, we don’t need to mention the TestNG  dependency but to be on the safer side and so that this project can also be imported to other IDEs such as Eclipse, and to run through the command line we need to have the dependency mentioned in build.gradle.

 

NOTE-2: We will be adding the Automation script under src/test directory, so in order to link the Appium and TestNG dependencies to that directory we need to use the testCompile keyword instead of the compile keyword(which compiles the dependencies and made them accessible to src/main directory).

 

After mentioning the dependencies in the build.gradle, the project will be built and the mentioned dependencies will be downloaded, so now you can use Appium and TestNG classes inside the  test directory.

 

Figure-14: build.gradle

 

After dependency management we need to start working on our Appium script. We will start by setting the correct set of Desired Capabilities.

 

What is “Desired capabilities”?

Desired Capabilities are core to Appium. They are actually a set of keys and values sent to the Appium server to tell the server what kind of automation session should be started. There are various capabilities to modify the behavior of the server during automation.

We have a dedicated chapter on desired capabilities where we will explore them in-depth, but for the sake of getting our first case test we’ll use the following desired capabilities:

 

Android:

{

 "platformName": "Android",

 "platformVersion": "8.0",

 "app": "/Users/username/Downloads/sample.apk",

 "deviceName": "c4e3f3cda"

}

 

iOS:

{

 "platformName": "iOS",

 "platformVersion": "11.4.1",

 "app": "/Users/username/Downloads/sample.ipa",

 "deviceName": "John’s iPhone",

 "udid": "bea36e2b0262ae4b77bd3463bd462922ee935d24"

}

 

Now let’s understand these capabilities:

  • platformName- Specifies the Mobile Device Platform to use. (iOS or Android)
  • platformVersion- Mobile OS version (8.0, 11.4, 12.1)
  • app-  The absolute path to the location of the app to test, apk/ipa.(For this example it is under src/test/resource directory)
  • deviceName-  Can either refer to an actual mobile device or to an Emulator/Simulator. For Android you can find it using $ adb devices command and for iOS you may use $ instruments -s devices
  • udid- It is the Unique device identifier of the connected physical device.

 

We will look at both an Android and iOS test case. However, please review both sections even if you are not testing on a particular platform. For each, we explore a different scenario and you will be exposed to different features. If you don’t have the specific platform, just read along so that you can get the gist of what we are doing.

Android

 

  • We will look at an Android test first. After setting the valid DesiredCapabilities, we need to pass them to the AndroidDriver class along with the Appium Server URL(By default it is:  http://127.0.0.1:4723/wd/hub)

AndroidDriver is the main class we will be working with. We will create an instance of AndroidDriver and we will interact with all the UI Elements of the app using that object every time.

And as we are using the TestNG framework we will put these initialization steps before the test starts, so our code will look like this:

 

Figure-15: AndroidDriver initialization and Desired Capabilities.

 

TestNG provides annotations such as @BeforeTest, @BeforeMethod, @AfterTest, @AfterMethod, @Test etc.

In the above screenshot, @BeforeTest means that the method will be called before the test, and only once. So it is standard practice to put the AndroidDriver initialization code over there, so the object of AppiumDriver becomes accessible at the end of that method and before the test.

 

  • Now let’s create the first sample Appium Test Case.

The @Test annotation(provided by TestNG) is used to create the individual test case. So in the below code firstTest is an individual test case

@Test

public void firstTest(){}

 

  • So let’s automate a simple scenario. In the below screen we want to click(tap) on Login Screen item from list.

 

Figure-16: Android - Sample App.

 

  • After creating the test case we need to add the Appium logic to interact with the UI elements. In Appium we need each element’s locator to interact with. If you want to tap on some button, you need to find the locator of that button first and then after that you can perform a  click()  action upon it. We will be exploring locators in detail in a subsequent chapter.

This code will find the Login Screen textview locator and simply click on it:

driver.findElement(By.id("Login Screen")).click();

 

Now our First Appium Automation Script is ready to execute, below is the complete code:

import io.appium.java_client.AppiumDriver;

import io.appium.java_client.android.AndroidDriver;

import org.openqa.selenium.By;

import org.openqa.selenium.remote.DesiredCapabilities;

import org.testng.annotations.BeforeTest;

import org.testng.annotations.Test;

import java.net.MalformedURLException;

import java.net.URL;

public class AndroidSampleTest {

   public AndroidDriver driver;

   @BeforeTest

   public void setUp() throws MalformedURLException {

       String appiumServerURL = "http://127.0.0.1:4723/wd/hub";

       DesiredCapabilities dc = new DesiredCapabilities();

       dc.setCapability("platformName", "Android");

       dc.setCapability("platformVersion", "8.0");

       dc.setCapability("app", "/Users/test/Downloads/FirstAutomationTest/src/test/resources/DemoApp.apk");

       dc.setCapability("deviceName", "c4e3f3cd");

       dc.setCapability("automationName", "UiAutomator2");

       driver = new AndroidDriver(new URL(appiumServerURL), dc);

   }

   @Test

   public void firstTest() throws InterruptedException {

       driver.findElement(By.id("Login Screen")).click();

   }

}

 

  • We are ready to execute it on a real device, so follow these steps:
    • Move to the Appium Desktop Application and Start the Server.

 

  1. Figure-17: Appium Server is Running on 0.0.0.0:4723

    • Connect your Android Mobile device to your computer and check that it is connected properly by executing $ adb devices command. And also check the deviceName capability has the same name of the device which is showing up in the terminal.

 

  1. Figure-18: Android device is connected.

    • Please make sure that device screen is unlocked and that it’s connected properly. Now move to intelliJ Idea and select the test case name > Right click on it > Run ‘firstTest()’

 

Figure-19: Run the test case.

    • Observe the Test Result and confirm the navigation on your device. It was a simple test case but you’ve actually accomplished a lot! From here, you get to explore all the cool features that Appium offers.

 

  1. Figure-20: Test Result

 

Although we will be turning to iOS next, be sure to read this section even if you are not doing iOS testing. In this example, we get just a little more sophisticated with our test and also expose you to using an assert statement.

 

iOS

  • Let’s make our test case a little more sophisticated, while also looking how we can work with iOS. Again, if if you are not planning on using iOS, we suggest you read this section as we’ll be introducing new concepts applicable to both iOS and Android. For our iOS sample test case we will create a separate Test Case file named iOSSampleTest
  • As we discussed above we need to put the iOS capabilities instead of Android capabilities, and define an IOSDriver class instead of an AndroidDriver class.

 

Figure-21:iOSDriver initialization and Desired Capabilities.

 

  • After specifying the desired capabilities we can write the Automation test case.We have a sample app(.app file, which will work on iOS Simulator only) for automation. In this app there is a feature where you can add 2 integer numbers and can get the the results. So we will automate this feature.

 

Figure-22: iOS Sample Application

 

The steps to automate this would be:

        • Find the locator of TextField A and enter the value (ie. Send keys) from the keyboard.
driver.findElement(By.id("IntegerA")).sendKeys(5 + "");

 

NOTE: The sendKeys() method accepts only String parameter so we have converted the Integer value to a String by appending a blank String value.

        • Find the locator of TextField B and enter the second value from the keyboard.
driver.findElement(By.id("IntegerB")).sendKeys(10 + "");

 

        • Find the locator of ‘Compute Sum’ and click on it, so the result would be displayed below the ‘Compute Sum’ textview.
driver.findElement(By.id("ComputeSumButton")).click();

String answer = driver.findElement(By.id("Answer")).getText();

 

NOTE: The getText() method is used to get the Text(in String format) from UI Elements.

  • Get the text of  the result and compare it with the expected result, so if you enter 5 into TextField A, 10 into TextField B and when you click on ‘Compute Sum’ textview the result 15 should be displayed under ‘Compute Sum’.
Assert.assertEquals(answer, 15 + "", "Expected and Actual Result didn't match!");

 

NOTE: Assert.assertEquals(expected, actual, error_message) is a TestNG method used to compare the Expected and Actual values. This is the most important step of any test case, because this is how automation test will know whether values are being rendered on UI is correct and as expected or not. You will see us using Assertions throughout this guide.

TestNG is the Testing framework and work best with Appium(Mobile Automation) and Selenium(Website Automation), you can learn more about the TestNG Annotations and methods here: https://testng.org/doc/index.html

 

      • Below is the full  code of our test which will enter 2 values into text fields, click on ‘Compute Result’, get the result from app and compare it with  the expected result.
import io.appium.java_client.ios.IOSDriver;

import io.appium.java_client.ios.IOSElement;

import org.openqa.selenium.By;

import org.openqa.selenium.remote.DesiredCapabilities;

import org.testng.Assert;

import org.testng.annotations.BeforeTest;

import org.testng.annotations.Test;


import java.net.MalformedURLException;

import java.net.URL;


public class iOSSampleTest {

   public IOSDriver<IOSElement> driver;


   @BeforeTest

   public void setUp() throws MalformedURLException {

       String appiumServerURL = "http://127.0.0.1:4723/wd/hub";


       DesiredCapabilities dc = new DesiredCapabilities();

       dc.setCapability("platformName", "iOS");

       dc.setCapability("platformVersion", "11.4");

       dc.setCapability("app", "/Users/pratik/Downloads/FirstAutomationTest/src/test/resources/DemoApp-iPhoneSimulator.app");

       dc.setCapability("deviceName", "iPhone X");


       driver = new IOSDriver<IOSElement>(new URL(appiumServerURL), dc);

   }


   @Test

   public void secondTest() throws InterruptedException {

       int a = 5;

       int b = 10;


       driver.findElement(By.id("IntegerA")).sendKeys(a + "");

       driver.findElement(By.id("IntegerB")).sendKeys(b + "");

       driver.findElement(By.id("ComputeSumButton")).click();

       String answer = driver.findElement(By.id("Answer")).getText();

       Assert.assertEquals(answer, a + b + "", "Expected and Actual Result didn't match!");

   }

}

 

You can get this example code on our github page.

Phew! We covered a lot of material in this chapter.

We learned the following:

  • Installation of IntelliJ IDEA.
  • TestNG plugin installation on IntelliJ IDEA.
  • Setting up the Appium Project on IntelliJ IDEA.
  • Writing the first Automation Test on Android Real Device.
  • Writing the first Automation Test on iOS Simulator.

 

Along the way you learned a little bit about desired capabilities, locators and assertions. All of this is a great grounding to continue your education into the world of Automated testing and Appium.

Take a break and let’s continue our journey when you get back.

Tags:
,
No Comments

Post A Comment