Android TV App Testing with Appium: The Ultimate GuideAndroid TV App Testing with Appium: The Ultimate Guide

Mastering Automation of Android TV Apps With Appium

March 20, 2023
 by 
Rohan SinghRohan Singh
Rohan Singh

Introduction

In the wake of the 2014 introduction of Android TV by Google and the subsequent release of tvOS by Apple in 2015, the market for Android TV app testing and development has exploded. With numerous companies racing to create their TV apps, it's clear that there is a significant demand for high-quality products in this arena. Testing Android TV apps is similar to mobile app development in many ways, and comprehensive QA processes are essential to delivering a top-notch user experience. As Over-The-Top (OTT) content delivery has grown in popularity, the ability to perform Android TV automation testing using Appium has become an increasingly important skill for automation testers to possess.

Read: Using Appium for Automated Testing of Roku TV Apps

How Is Android TV App Testing Different from Android Mobile App Testing?

Appium testing for Android TV requires knowledge of remote-control functions due to the lack of touch input. Testing is similar to smartphones, involving identifying elements, interacting with them, modifying attributes, and verifying output. However, Android TV has platform-specific factors such as a landscape orientation and apps designed for video playback, requiring testers to adapt their strategies accordingly.

This blog is a comprehensive guide to automating Android TV app testing, covering everything from connecting your computer to your smart TV to automating key actions like search and video playback.

Related Blog: What Appium Users Need to Know about Android Activities and Intents

How Should You Prepare Your Testing Setup?

Let's look at the initial steps you need to consider before starting your test automation.

1. Activate Developer Options on Android TV

To begin testing Android fire TV with Appium, the first step is to enable Developer options on the TV. This is necessary to connect the TV to a computer for testing purposes. Enabling Developer options on an Android TV is similar to doing so on an Android smartphone.

To enable Developer options for Android TV app testing using Appium, follow these steps:

  • Click on the 'Settings' icon
  • Navigate to 'Device Preferences'
  • Select 'About'
  • Find the 'Build Option' and click on it until a message appears stating that "you are now a developer"
  • Go back to 'Device Preferences' and scroll to the bottom
  • Select 'Developer Options'
  • Locate the 'USB Debugging' option and enable it
  • Once you have enabled the 'Developer Options,' you can connect your computer to the TV and start testing your Android TV app using Appium
Related Blog: Running arbitrary ADB commands via Appium

2. Get the Necessary Information from the Smart TV

To connect a smart TV with a computer for Android TV app testing using Appium, you only need the IP address of the TV. However, obtaining the Device Name, Platform Name, and Platform Version is also useful, as you will need them for your automation script. Here are the steps to follow:

  • Click on the 'Settings' icon
  • Choose 'Additional Settings'
  • Go to 'Device Preferences'
  • Click on 'About'
  • Obtain the Device Name, Platform Name, and Platform Version
  • Look for the 'Status' option (Network) in 'About'
  • Click on it and find the IP Address of the Android TV

By following these steps, you can easily obtain the necessary information to connect your fire TV with Appium.

3. Ensure Your Smart TV Is Connected to Your Computer

To connect your computer to the Android TV for Appium testing, follow these steps:

  • Open Command Prompt
  • Enter the command "adb connect"
  • After entering the command, a list of connected devices will be displayed in Command Prompt

It is crucial that you should have completed all the necessary Appium setups on your laptop before initiating the adb command. Following these steps, you can connect your computer to your smart TV for Appium testing.

How Can You Automate Your Android TV App Tests Using Appium?

Testing an OTT platform involves a complex set of tasks, including testing core functionality, UI and UX, subscriptions, and more. In this automation guide, we focus on automating the core functionality tests. Let's explore the steps. 

Related Blog: Automating System Apps with Appium

1. App Launch

To begin automating your Android TV app testing, launching the app you want to test on your Smart TV is essential. 


public class LionsGateDemo {
	public static AppiumDriver driver;
	public static WebDriverWait wait;
   public static void main(String[] args) throws IOException, InterruptedException {
    	try {
        	//Set the Desired Capabilities
        	DesiredCapabilities caps = new DesiredCapabilities();
   	//Set the Smart TV Name
        	caps.setCapability("deviceName", "Redmi TV");
   	//Set the Smart TV Platform
        	caps.setCapability("platformName", "Android");
   	//Set the Smart TV platform version
        	caps.setCapability("platformVersion", "11");
   	//Set the App package and app activity details
        	caps.setCapability("appPackage", "com.xiaomi.lionsgateplay.videoapp");
            caps.setCapability("appActivity", "com.parsifal.starz.ui.features.splash.SplashActivity");
            caps.setCapability("unicodeKeyboard", true);
            caps.setCapability("resetKeyboard", true);
            caps.setCapability("noReset", "true");
        	driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), caps);
            driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        	System.out.println(">>>>  APP launched::::");
        	wait = new WebDriverWait(driver, 30);

It's essential to use the exact name of your Smart TV which appears in the menu to prevent errors. This step is crucial in Appium testing for smart TV.

2. App Navigation

When automating apps of Android fire TV with Appium, it's essential to remember that these devices don't have touchscreens, so all navigation must be done through the remote controller. 

To achieve this, UiAutomator can interact with the remote in a specific manner, providing a command for each interaction during the automation process.


fun back() = device.pressBack()
fun menu() = device.pressMenu()
fun home() = device.pressHome()
fun playPause() = device.pressKeyCode(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)
 
// D-Pad Controls:
fun left() = device.pressDPadLeft()
fun right() = device.pressDPadRight()
fun down() = device.pressDPadDown()
fun up() = device.pressDPadUp()
fun select() = device.pressDPadCenter()

3. Execution of Remote Actions

In Appium testing for Android TV, it's important to keep track of which element is currently in focus since you'll be simulating button clicks from a remote control. 

Once you've mastered automating TV remote actions, you can use them to automate other actions, such as browsing the platform or turning on subtitles.


// To press the Up button
    	((PressesKey) driver).longPressKey(new KeyEvent(AndroidKey.DPAD_UP));
    	((PressesKey) driver).longPressKey(new KeyEvent(AndroidKey.DPAD_UP));
	// To Press the Center button
    	((PressesKey) driver).longPressKey(new KeyEvent(AndroidKey.DPAD_CENTER));
	// To Press the Down button
    	((PressesKey) driver).longPressKey(new KeyEvent(AndroidKey.DPAD_DOWN));
    	// To Press the Center button
    	((PressesKey) driver).longPressKey(new KeyEvent(AndroidKey.DPAD_CENTER));
    	System.out.println("None option inside the subtitle is selected");
    	Thread.sleep(5000);
    	// To Press the Up button
    	((PressesKey) driver).longPressKey(new KeyEvent(AndroidKey.DPAD_UP));
    	((PressesKey) driver).longPressKey(new KeyEvent(AndroidKey.DPAD_UP));
    	// To Press the Center button
    	((PressesKey) driver).longPressKey(new KeyEvent(AndroidKey.DPAD_CENTER));
   	// To Press the Up button
        ((PressesKey) driver).longPressKey(new KeyEvent(AndroidKey.DPAD_UP));
  	// To Press the Center button
    	((PressesKey) driver).longPressKey(new KeyEvent(AndroidKey.DPAD_CENTER));
    	System.out.println("English option inside the subtitle is selected");
    	Thread.sleep(5000);
   	// To Press the Right button for Forward the video
    	((PressesKey) driver).longPressKey(new KeyEvent(AndroidKey.DPAD_RIGHT));
    	((PressesKey) driver).longPressKey(new KeyEvent(AndroidKey.DPAD_RIGHT));
    	((PressesKey) driver).longPressKey(new KeyEvent(AndroidKey.DPAD_RIGHT));
    	System.out.println("Forwarding is done successfully");
    	System.out.println("Remote action done");
	}
}

4. Selection of Elements

In Android TV app testing, selecting elements is done in the same way as manual testing. First, we must find the element, move the focus to it, and then select it. This process can be achieved using Appium for Android apps.

To ensure successful navigation in the Android TV app, we need to implement several additional methods for determining the focus state.

a. The first method is "focused," which returns the currently focused element.


val focused: UiObject2? get() =
      device.findObject(By.focused(true))

b. The second method is "isFocused," which checks if a particular element is focused.


fun isFocused(selector: BySelector): Boolean =
          device.findObject(selector)?.isFocused ?: false

c. Some elements are not focusable but might contain a focused element inside them. For such cases, we can use the "hasFocus" method.


fun hasFocus(selector: BySelector): Boolean =
          device.findObject(selector.hasDescendant(By.focused(true)))
             	 != null

To select an element on a Smart TV, the first step is to move the focus onto it. This can be tricky when automating the process. It's important to build an optimal path for moving the focus to the element, as this will make navigation through the app faster and more efficient. There are different approaches to finding the path to the element, and we will discuss them in this section.

1. Identifying an element in a column

When searching for an element in a column, keep in mind the following:

  • Navigation is only possible in the up or down direction
  • The element could already be in focus
  • The element could be located above or below the currently focused element
  • It is important to determine if the end of the column has been reached
  • The element may not be present in the column at all

We can develop a straightforward algorithm for locating an element in an Android TV app column by considering the above factors.


fun findInColumn(by: BySelector) {
 var isEndReached = falsewhile (!isFocused(by)) {
  val previous: UiObject2? = focused
  moveFocus(isEndReached)
  val current: UiObject2? = focused
 
  if (previous == current) {
   if (isEndReached) {
	throw RuntimeException("Element $by was not found")
   }
   isEndReached = true
  }
 }
 println("Element $by was found")
 select()
}
 
fun moveFocus(isEndReached: Boolean) =
        	if (isEndReached) up() else down()

We iterate through the elements in the column and check if the element is currently focused. We compare the previously focused element with the current one to determine if the end of the column has been reached. If the end is reached twice, meaning all elements have been inspected, an exception is thrown.

2. Locating an element in a row

To search for an element within a row, we can apply similar principles as those used for column lookup. The algorithm for row lookup will be almost identical to that of column lookup, with the only necessary modification being to adjust the moveFocus method.


fun moveFocus(isEndReached: Boolean) =
                    	if (isEndReached) left() else right()

Using this method, we will examine elements located on the currently focused element's left and right sides.

3. Discovering an element in a grid

The vertical grid presents the most significant challenge for element lookup, as we must navigate in three directions - left, right, and down - to locate the desired element.

Considerations before initiating the search process:

  • Start from the upper left/right element to avoid backtracking.
  • Inspect all elements in a row before moving to the next one.
  • Change direction at the end of each row.
  • In asymmetrical grids, inspect both bottom elements of the last row.

This is how our algorithm would work schematically:


1  -> 2  -> 3  -> 4  -> 5
                    	        	    |
                    	        	    v
6  <- 7  <- 8  <- 9  <- 10
|
v
11 -> 12 -> 13 -> 14 -> 15
   <-    <-	<-	<-
|
v
16 -> 17 -> 18

In the provided schema, when the 15th element is reached, and isEndReached is triggered, we will backtrack to the 11th element and move down to search the last incomplete row.

Here is what the actual implementation would look like:


fun findInGrid(by: BySelector) {
 var isMovingRight = truevar previous: UiObject2? = nullvar current: UiObject2?
 var isEndReached = false
 
 while (!isFocused(by)) {
  moveFocus(isMovingRight)
  current = focused
 
  if (current == previous) {
   down()
   isMovingRight = !isMovingRight
   current = focused
 
   if (current == previous) {
	if (isEndReached) {
 	throw RuntimeException("Element $by was not found!")
	} else {
 	isEndReached = true
	}
   }
  }
  previous = current
 }
 println("Element $by was found!")
 select()
}
 
fun moveFocus(isMovingRight: Boolean) =
                  	if (isMovingRight) right() else left()

For Appium on Android, the implementation is similar to findInColumn, focusing on switching rows once the first row ends. Test developers must inspect both sides of the last row for asymmetrical grids before raising exceptions.

5. Utilizing the Search Feature

In Appium testing for Android TV, we'll automate the user journey to navigate to the search bar. It's important to note that the steps may differ based on the app or platform being tested. 

We can verify the accuracy of our automation script by comparing the results obtained through automation with manual input, using Appium for Android testing.


// Finding & Clicking button One
        	WebElement buttonOne = driver.findElement(By.xpath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.LinearLayout[1]/android.widget.LinearLayout[2]/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.ImageView"));
            wait.until(ExpectedConditions.elementToBeClickable(buttonOne));
        	buttonOne.click();
   	// Find & Click the bIcon
      	  WebElement bIcon = driver.findElement(By.xpath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.LinearLayout[1]/android.widget.LinearLayout[2]/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.TextView"));
            wait.until(ExpectedConditions.elementToBeClickable(bIcon));
        	bIcon.click();
        	wait.until(ExpectedConditions.elementToBeClickable(bIcon));
        	bIcon.click();
 
// Locate the Search Bar
        	WebElement searchBox = driver.findElement(By.id("com.xiaomi.lionsgateplay.videoapp:id/lb_search_text_editor"));
// Enter the values in the Search input textbox
       	searchBox.sendKeys("a");
// Store the Movie name in a webelement
        	WebElement firstMovieName = driver.findElement(By.xpath("//androidx.recyclerview.widget.RecyclerView[@content-desc='Top results for: a']/android.widget.FrameLayout[1]/android.widget.ImageView"));
 
// Wait for the movie to become clickable and then click to open it
                    	wait.until(ExpectedConditions.elementToBeClickable(firstMovieName));
        	firstMovieName.click();
// Store our expected Movie name in the STRING
        	String movieName = "Amores Perros";
 
// Finding Actual Movie name 
        	WebElement OutputMovieName = driver.findElement(By.id("com.xiaomi.lionsgateplay.videoapp:id/titleText"));
// Get and Store our Actual Movie name in String
        	String OutComeMovie = OutputMovieName.getText();
        	System.out.println(OutComeMovie);
//Verify Actual and expected Movie name by using if condition
        	if (movieName.equals(OutComeMovie)) {
     	       System.out.println("Both are same name");
        	}
    	} catch (Exception e) {
        	e.printStackTrace();
    	}

6. Playing A Video

After completing the search operation, the next step is to automate the selection of a movie from the search results. We have provided a sample code to assist you in doing so. 

It's important to note that these concepts can be applied not only to playing a video from search results but also from the home screen or elsewhere. It's simply a matter of updating the XPath to suit your needs.


// Finding Play button
    	WebElement playButton = driver.findElement(By.xpath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.LinearLayout[2]/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.FrameLayout[1]/android.widget.FrameLayout/android.widget.TextView"));
    	playButton.isDisplayed();
// Wait for the Playbutton to be clickable and Click the Playbutton
    	wait.until(ExpectedConditions.elementToBeClickable(playButton));
    	playButton.click();
    	System.out.println("Play button is selected ");

How Headspin Can Optimize Your Appium-Based Android TV App Testing Strategy

HeadSpin offers comprehensive solutions for Android TV app testing using Appium, making the mobile app development and testing process faster and more efficient. The HeadSpin Platform provides a one-stop-shop solution for testing Smart TV app experiences, including the ability to capture QoE and streaming performance KPIs.

With HeadSpin, you can:

  • Automate Smart TV testing to improve efficiency
  • Drive revenue growth and enhance user engagement
  • Utilize a unified platform for all your NFR and functional testing requirements for Smart TVs and apps
  • Test on real Smart TVs to resolve issues faster

Integrating Appium with HeadSpin's Platform can streamline the entire CI/CD process, create robust Appium scripts with ease, reduce the complexity of test frameworks, and support parallel testing on OTT devices.

Conclusion

In conclusion, understanding the basics of Smart TV app testing using Appium is crucial for effective OTT automation. Utilizing these concepts effectively can help you expand your testing capabilities. A recommended best practice is to run your tests on multiple Smart TV devices simultaneously to receive faster feedback and reduce the resources required for issue resolution. 

If you are looking for a comprehensive solution for Android TV app testing, try the Appium-integrated HeadSpin Platform. HeadSpin's one-stop-shop solution for Smart TV app testing helps you streamline your testing process and ensure a perfect digital experience for your users.

Book a trial.

FAQs

Q1. How can I use Appium to automate apps?

Ans: To automate an Android app with Appium:

  • Set APK path, package, and launch activity in Android settings.
  • Connect your phone to your PC and turn on USB debugging.
  • Open Command Prompt.

Q2. How are Appium automation test cases written?

Ans: To create a new Java project in Eclipse and add project dependency files for Selenium Standalone and Appium Client Library, follow these steps:

  • Launch Eclipse and right-click on Package Explorer.
  • Select New Java Project and enter a project name, then click Finish.
  • Add a folder to the project for the dependency files that you have downloaded.

Q3. What are the television remote's test cases?

Ans: Test cases for a TV remote control include:

  • Verify the presence of all buttons, including 0 to 9, volume, channel up-down, and audio-video functionality buttons.
  • Verify the functionality of the power ON-OFF button.
  • Verify the remote control is specific to a particular TV set model number.
Share this

Mastering Automation of Android TV Apps With Appium

4 Parts