Saturday, July 25, 2026

Mobile Automation - Creating scalable device farms using open source technologies

 Introduction:

In our consumer driven society, with the leverage of advanced technologies, businesses are in cut-throat competition with growing demands of faster releases of contents, apps and software patches. In the era of continuous integration, continuous delivery, automation and AI, it is of paramount interest for the businesses to ensure "continuous quality" in their releases. Since it is not possible for humans to verify and validate everything simultaneously in a coherent fashion, we are heavily dependent on test automation.

Some pressing challenges in Mobile automation:
  • Purchasing physical mobile devices -> it will lead to capital expenditure
  • Mobile test automation tools -> they are excellent, but incurs license costs which perhaps impact the operational expenditure. Not only that, businesses often needs to pay additionally for professional support. Often businesses need to wait to get any new feature added in the tool exclusively to support their needs.
  • Using Cloud based device farms -> they are excellent, but using cloud based device farms may not reduce the operational expenses of a business. For large businesses, it may offer a trade off but for smaller businesses it may be costlier.
  • Outsourcing -> a brilliant idea when the businesses are not having any internal IT teams, or they do not have existing capability, or they want to externalize the delivery risk.

Why to use open source technologies for Mobile Automation?

Well, if you have read the introduction, by now you have a clear idea of why to use open source technologies. The most crucial factors are:
  • it comes free of cost
  • supports a wide array of mobiles OS (Android & iOS) and devices to a great extent
  • with right skills it is easy to set up. Using open source technologies are not a "rocket" science, so whoever is really interested in upskilling themselves, they can learn it quickly
  • using containerization, it is scalable to an enterprise grade. But that will incur good amount of infrastructure and specialized personnel costs (i.e. Security Specialists, DevOps engineers)
  • the open source communities are very active and provides a lot of help and support whenever needed

Architectural overview of our first solution - using device emulator running on host machine / connecting physical devices

In our present architecture, we are going to run Appium server inside Docker Desktop, while our device emulator will be running in the host machine. So, we need to use TCPIP to establish connection between the Appium Server container's ADB and our host machines device emulator ADB. 

image courtesy: Gemini AI

Remember, you can also connect your physical android devices to the Host Machine using USB and use that devices UDID to run tests directly on that device.

If you want to scale up execution in multiple physical devices, then you can create multiple copies of your test scripts. In each scripts, expose unique Appium Server, System Port and mpegServerPort,  and update the unique UDID of the connected devices.

Infrastructure needs and software installations

First, you need to ensure that you have the right infrastructure available. The machine you are using should have at least 8 GB RAM, 5 to 12 core CPU, at least 20 - 50 GB of free Disk Space, a good graphics card (optional in Windows machine), high speed internet connection. Windows 10/11 users, you need to ensure you have WSL2 installed and enabled virtualization. Linux/MacOS, users to concentrate on Virtual Machine Platform and KVM acceleration following available instructions over the internet. 

























Second, you need to install the required softwares:
  1. Docker Desktop / Podman (In this article, I am covering only Docker Desktop)
  2. Android Studio - latest version is recommended
  3. IntelliJ / Eclipse
  4. Open JDK 17.0 or Open JDK 21.0 (Remember to set JAVA_HOME and adding it to Environment Variable)
Third, verify installed softwares quickly by doing the following:
  • Run CMD as Administrator, type "java --version" -> Ensure it returns correct java version
  • In the same CMD window type "docker --version" -> Ensure it returns correct docker version
  • In the same CMD window type "docker ps" -> Ensure the command does not return any errors
  • Open IntelliJ, ensure it is opening. Then go to its terminal window and type "java --version" -> Ensure it is returning right java version

  • Open Android Studio and verify that you are able to see "More Actions" link
  • Click on it, and in the drop down menu you will see "Virtual Device Manager"
  • Click on it, and it should open "Device Manager" window





Creating virtual device emulator and ADB set up

Now you are ready to begin your adventure. In this article we will deal with Virtual Mobile Emulator devices only in Windows 11, but the set up will work on real mobile devices if you connect it to your system using USB.

You can create a virtual emulator device from the Device Emulator window, you may have noticed in the previous screenshot that I have created a device named "Small Phone". Once you create the device, run it and within a minute or two you will see the device emulator window in your screen. I am not covering it in detail, you can find guides on how to create emulator devices in the internet.

Run CMD as administeator, navigate to this path: c:/users/<your user profile>/appData/local/android/sdk/platform-tools
Execute this commad: 
adb devices

Your emulator device should get listed as follows:


In the CMD window, execute below commands:
1. adb tcpip 5555
2. adb connect localhost:5555
3. adb devices



Creating a Java project for mobile automation

You can create a Java Test project in IntelliJ or in your choice of IDE using either Gradle or Maven as a build tool. We are going to use TestContainers in Java to dynamically run the Appium container (Appium Server) as part of our test script. Add below dependencies (in this example I am using Maven):

<dependencies>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>2.0.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java</artifactId>
<version>3.7.1</version>
<scope>compile</scope>
</dependency>
<!-- Source: https://mvnrepository.com/artifact/io.appium/java-client -->
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>10.1.1</version>
<scope>test</scope>
</dependency>
</dependencies>

You can refer the below class file code which runs the test in the emulator device using appium server container in the host machine. You must focus on the code that creates the appium container and the UiAutomator2 capabilities that I have used. You may not have come across any code so far where everything is kept under the same hood for easy understanding of Appium container's environment variables and the needed capabilities of UiAutomator2.

Remember:
  1.  Copying the adbkey and adbkey.pub files to the container is necessary. You can access these files in your machine under c:/users/<your user profile>/.android folder.
  2. Run Docker Desktop engine in your host machine before running the test class
  3. Ensure your device emulator is running in your host machine
*********************************************************************

import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testcontainers.Testcontainers;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.MountableFile;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;

public class MobileTrial {
    public static void main(String[] args) throws IOException, InterruptedException {
        Testcontainers.exposeHostPorts(5555, 5037, 8200);
        GenericContainer<?> appiumServerContainer = new GenericContainer<>("appium/appium:latest")
                .withExposedPorts(4723,8200)
                .withPrivilegedMode(true)
                .withAccessToHost(true)
                .withEnv("REMOTE_ADB", "true")
                .withEnv("ANDROID_DEVICES", "host.testcontainers.internal:5555")
                .withEnv("APPIUM_ADDITIONAL_PARAMS", "--relaxed-security --allow-insecure=*:chromedriver_autodownload")
                .withCopyFileToContainer(MountableFile.forHostPath("c:/users/<put your user directory>/.android/adbkey"), "/home/androidusr/.android/adbkey")
                .withCopyFileToContainer(MountableFile.forHostPath("c:/users/<put your user directory>/.android/adbkey.pub"), "/home/androidusr/.android/adbkey.pub")
                .withCopyFileToContainer(MountableFile.forHostPath("c:/users/<put your user directory>/.android/adbkey"), "/root/.android/adbkey")
                .withCopyFileToContainer(MountableFile.forHostPath("c:/users/<put your user directory>/.android/adbkey.pub"), "/root/.android/adbkey.pub")
                .waitingFor(Wait.forHttp("/status").forPort(4723).withStartupTimeout(Duration.ofMinutes(2)));

        appiumServerContainer.start();
        String appium_server_url = "http://" + appiumServerContainer.getHost() + ":" + appiumServerContainer.getMappedPort(4723);
        System.out.println("Appium server url: " + appium_server_url+"/status");

        DesiredCapabilities caps = new DesiredCapabilities();

        caps.setCapability("appium:automationName", "UiAutomator2");
        caps.setCapability("platformName", "Android");
        caps.setCapability("browserName", "Chrome");
        caps.setCapability("appium:deviceName", "Android Emulator");
        caps.setCapability("appium:udid", "host.testcontainers.internal:5555");
        caps.setCapability("appium:platformVersion", "15");
        caps.setCapability("appium:chromedriverConnectHost", "127.0.0.1");
        caps.setCapability("appium:chromedriverConnectPort", 8200);
        caps.setCapability("appium:systemPort", 8200);
        caps.setCapability("appium:automatedChromedriverDownload", true);
        caps.setCapability("appium:ignoreHiddenApiPolicyError", true);
        caps.setCapability("appium:relaxedSecurity", true);
        caps.setCapability("appium:noSign", true);
        caps.setCapability("appium:amStartWithCleanRules", true);
        caps.setCapability("appium:noReset", true);
        caps.setCapability("appium:clearDeviceLogsOnStart", true);
        caps.setCapability("appium:skipUnlock", true);
        caps.setCapability("appium:appWaitDuration", 60000);
        caps.setCapability("appium:suppressKillServer", true);
        caps.setCapability("appium:enforceAppInstall", true);
        caps.setCapability("appium:uninstallAppiumServer", true);
        caps.setCapability("appium:uiautomator2ServerLaunchTimeout", 60000);
        try {
            AndroidDriver driver = new AndroidDriver(new URL(appium_server_url), caps);
            driver.get("https://www.saucedemo.com/");
            System.out.println(driver.getTitle());
            driver.quit();
        }catch(Exception e){
            System.out.println(appiumServerContainer.getLogs());
        }
    }
}

*********************************************************************************

Architectural overview of our second solution - using device emulators running in Test Containers

Coming soon...

Saturday, August 24, 2024

Test Automation Strategy for Oracle Forms application running in Citrix servers

 Context:

There are many product based applications developed using Oracle Forms and Java thick-client architecture, and most of them are accessible via Citrix (varies from Organization to Organization). Some products have stringent security access policies, and their product owners (Organizations) generally do not allow installing any test automation tools in their product's host server. They provide access to their products only through multi-channel Citrix layers. Example: Oracle Health EHR. These put a lot of limitation to the Test Architect/Principal Engineer/Test Manager, whose given task is to prepare test automation strategy for these types of product applications.

Strategy:

First step is to have a series of dialogues with the organization who owns the product to work out any possibility of getting the required test automation tools installed in the test server of the product. Due to complexity of multi channel Citrix layers, we may need to install some test automation agents at each layer. For example, UiPath remote runtime and OpenText UFT's Citrix Plugin. In case of Robot Framework, we need Python, PIP and all supported libraries to be installed on the Citrix server. Same applies to Test Complete tool.

Second step, if we are at this point, then definitely we did not get much support from the product's owner organization, so we need to rely on relatively unpopular test automation approach, which is Image Recognition. There are many trendy test automation tools that provide image recognition capability. Following are some important factors to consider:

1. Does the existing tools in my organization's inventory have image based testing capabilities?

2. Do we have any budget allocated to your project plan for procuring any new test automation tool? (i.e. Eggplant, a renowned tool for Image Based testing that comes with licensing. UiPath Computer Vision may look appealing, but it has license costs associated and you may need to override the default OCR library, in case the text search and extraction does not fit your need.)

3. Are there Open Source tools that can fit your existing Test Automation ecosystem? (For example: if your company's test automation ecosystem does not use Java or Python backed hybrid test automation frameworks, then you cannot easily integrate SikuliX or Open-CV).

Answer to this question will lead to:

a. How long does it take to build a test framework from scratch to use these open source libraries? 

b. Do we have the required skills within our existing talent pool?

c. Do we have any budget allocated to hire an expert (Contract / Permanent Role)?

d. How long will be the learning curve?

Third step, how are you going to build a repository of Ui Object's images? This is the most important question, since, many of the Oracle forms have common Ui Objects and if you follow kind of page object model (POM), then you will end up building a huge repository that will contain duplicate images. So, defining an image capture strategy is quintessential. Capture an Ui Object's image in such a way that the same could be reusable across the application. 

Fourth step, how are you going to identify the objects uniquely in the Ui? Sometimes, you may find, some Ui Object's are repetitive in the forms. Example, there could be two fields with label "First name", under two different sections on the same form. In these cases a conceptual strategy of an anchor comes into play. For example, we could use the section headers as unique anchors to define a reduced region (to the left, right, top or bottom from the anchor image) on the screen in which we should search for an image for uniqueness.

Final step, how we are going to sale our strategy to the project stakeholders? While creating the test automation strategy, always keep in mind, the amount of efforts invested on test automation should  reduce the manual test efforts gradually, once it is rolled out for usage. This ROI factor always determines the fate of test automation activities.

I hope this is helpful to you, please share your opinions in the comments section. Always refer to the official websites of the tools mentioned in this article.

Wednesday, May 1, 2024

Interview preparation series Java: Are you not getting interview and/or coding test invites?

Are you not getting interview and/or coding test invites? 

These days it is pretty common. So, first of all, I would advice, consider reviewing your CV/Resume. Kindly do not exaggerate listing your skills, by copying from others. The technical panels are smart to judge how much truth is in it. Focus on elaborating on your role, job duties and some of the key challenges that you may have faced in the projects that you have been a part of, your professional achievements and certifications. My advice to freshers is they should put focus on their academic projects, and challenges faced in executing them and the certifications.

Now, if you get an invite for interview/coding test with a very short notice, how much prepared do you think you are? 

If you are among a small set of lucky candidates who received the interview/coding test invites, you still are in a competition.Thus, you need smart preparation to compete fairly, which includes a lot of coding practice on a regular basis. Below are my recommendations for preparing well:

Java:

1. Thoroughly study and memorize the functions under java.lang.Math package. You may ask why? Because over past 10 years, most of the coding tests ask require you to solve either a mathematical or a numerical problem. So without having a solid command over Math package, you can't solve most of the problems.

2. Focus on Java 8 onward features and coding styles. These days Java 6 style coding is old-fashioned and the industry trends follow Functional programming, including asynchronous functions (lamda), bi-functions and its use in stream() operations. In some of the online coding tests, you will be asked to only write the missing part of the code in a method. If you are not familiar with the aforementioned concepts, then you may miss an opportunity to score, because sometimes the asks will be very simple, but by the time you realize it, the opportunity will turn into a lost opportunity.

3. Thoroughly study and memorize the functions under java.util.Stream package. You may ask why? Again, most coding tests moved to Java 8 and above syntax. So, the expectation is to solve problems using stream() operations. Practice using Array, Strings, charArray, collections, (i.e. List, Set) and map. The idea is to determine whether you are familiar with the java data-structure and collections framework or not, and if you can apply it whenever appropriate in a programming context. 

4. Bitwise operations, sometimes most neglected by the students and professionals, however Bitwise operations are very important to master if you are a Java developer or going to become one. Brush up the bitwise operations and practice the number conversions including Octal, Hexadecimal and Binary numbers, bitwise shift operations, XOR operations. This topic always finds its place either in the online coding test or in the interview process.

5. You might have learned about Data-Structures: Stack, Queue, Dequeue, LinkedList, Tree etc. Do you know when to use it to solve a programming problem? Have you tried using the built-in data-structures in Java in any of your academic or professional code? Being honest with yourself, if you feel you are not comfortable with applying Data-structures, then revisit the concepts, look out for programming practice problems and set out sometime everyday to do practice for at least an hour.

6. None of the programming is complete without its File operations, and Java is not an exception. So please read through java.io.File package, memorize the functions and its parameters, and understand when to use which technique to read and write to files. The interviewers are sometimes more interested in understanding how much you know about the file operation efficiencies.

7. Without DB connection, a standalone program does not deliver value. So, you need to master JDBC connection and Spring Boot alternatives. In the interviews, you may expect questions on DB operations with respect to microservices development. So, getting yourself familiar with MySQL, Postgre, MongoDB will help a lot.

8. Exception handling and debugging is an integral part of any programming language. So, you should be able to tackle questions around efficient ways of handling errors and exceptions, including raising custom exceptions.

Mobile Automation - Creating scalable device farms using open source technologies

 Introduction: In our consumer driven society, with the leverage of advanced technologies, businesses are in cut-throat competition with gro...