Blog Details Shape

Best Strategies for Mobile Test Automation Framework Design

Naman Upadhyay
By
Naman Upadhyay
  • Feb 29, 2024
  • Clock
    8 min read
Best Strategies for Mobile Test Automation Framework Design
Contents
Join 1,241 readers who are obsessed with testing.
Consult the author or an expert on this topic.

Designing and implementing a mobile test automation framework can be challenging, as it requires careful planning, the selection of tools, and adherence to best practices.

In this blog, we will share some of the best strategies for mobile automation framework design, based on our experience and research.

Define automation objectives and scope

The first step in designing an industry-ready mobile test automation framework is to define your test automation objectives and scope. For that, you must have a clear answer to the following questions:

  • What are the main goals for implementing test automation in your project?
  • What types of mobile tests do you want to automate?
  • What are the features and functionalities of your mobile application that need to be tested?
  • How often do you need to run the automated tests?

These are some of the questions that you need to answer before you start building your framework. By defining your test automation objectives and scope, you can align your framework design with your business requirements and expectations, and avoid unnecessary automation efforts.

Choose the right automation tools and technologies

The next step is to choose the right test automation tools and technologies that suit your mobile application and framework design. There are many factors to consider when selecting test automation tools and technologies, such as:

  • The type and complexity of your mobile application (native, hybrid, or web)
  • The platforms and devices that you need to support (iOS, Android, Windows, etc.)
  • The programming languages and frameworks that you are comfortable with or prefer to use
  • The cost and availability of the test automation tools and technologies, such as licences, subscriptions, support, etc.
  • The features and functionalities that test automation tools and technologies offer, such as test recording, test execution, test reporting, test management, etc.

Here are some of the widely supported tools and technologies for mobile automation:

  1. Appium
  2. Selenium
  3. WebdriverIO
  4. Espresso
  5. Katalon Studio
  6. XCUITest

Follow the best practices and standards for mobile test automation

The third step is to following the best practices and standards for test automation, which will help you create a high-quality, consistent, and reliable automation framework.

Modular approach

Use a modular and reusable approach to design your test automation framework, by creating wrapper methods, libraries, and components that can be used across multiple test cases and scenarios.

Modular approach example:

// Create a wrapper method for clicking an element
public void clickElement(By locator) {
  driver.findElement(locator).click();
}

// Create a library class for common actions
public class CommonActions {

  // Declare and initialize the driver object
  public static AppiumDriver driver = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), new DesiredCapabilities("deviceName", "Pixel 4", "platformName", "Android", "platformVersion", "11", "appPackage", "com.example.loginapp", "appActivity", "com.example.loginapp.MainActivity", "noReset", true));

// Create a component class for a specific feature
public class ProfileComponent {

  // Declare the driver object
  private AppiumDriver driver;

  // Constructor to initialize the driver
  public ProfileComponent(AppiumDriver driver) {
    this.driver = driver;
  }

  // Method to update the profile information
  public void updateProfile(String name, String email, String phone) {

    // Use the wrapper method to click the profile link, clear and enter the name, email, and phone fields, and click the save button
    clickElement(By.linkText("Profile"));
    driver.findElement(By.id("name")).clear();
    driver.findElement(By.id("name")).sendKeys(name);
    driver.findElement(By.id("email")).clear();
    driver.findElement(By.id("email")).sendKeys(email);
    driver.findElement(By.id("phone")).clear();
    driver.findElement(By.id("phone")).sendKeys(phone);
    clickElement(By.id("save"));
  }
}
Copied!

Logger integration

Implement a custom logger that can capture and record the test execution details, such as test steps, test results, test errors, test screenshots, etc.

Implementation example:

// Import the required libraries
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;

public class BaseTest {
  // Declare the driver and logger objects

  protected AppiumDriver driver;
  protected Logger logger;
  @BeforeClass
  public void setup() {

    // Initialize the logger object and load the log4j properties file
    logger = Logger.getLogger(BaseTest.class);
    PropertyConfigurator.configure("log4j.properties");
  }
  @AfterMethod
  public void tearDown(ITestResult result) {

    // Log the test result and take a screenshot if the test failed
    if (result.getStatus() == ITestResult.FAILURE) {
      logger.error("Test failed: " + result.getName());
      File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
      FileUtils.copyFile(srcFile, new File("screenshots/" + result.getName() + ".png"));
    } else {
      logger.info("Test passed: " + result.getName());
    }

    // Quit the driver
    driver.quit();
  }
}
Copied!

Selecting a design pattern

Choose the right design pattern for your mobile application testing, such as Page Object Model, Keyword-Driven, Data-Driven, Behavior-Driven, etc., that can enhance the readability, maintainability, and scalability of your test code.

Here is an example of a simple Login BDD test scenario for a mobile app using Cucumber and Appium:

Feature: Login to the mobile app
  As a user
  I want to login to the mobile app
  So that I can use the features
  Scenario: Successful login with valid credentials
    Given I launch the mobile app
    When I enter "testuser" as the username
    And I enter "testpass" as the password
    And I tap on the login button
    Then I should see the initial screen
    And I should see a welcome message


import io.cucumber.java.en.*;
import io.appium.java_client.*;
import org.openqa.selenium.*;
import java.net.*;
public class LoginSteps {
  // Declare and initialize the driver object
  public static AppiumDriver driver = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), new DesiredCapabilities("deviceName", "Pixel 4", "platformName", "Android", "platformVersion", "11", "appPackage", "com.example.loginapp", "appActivity", "com.example.loginapp.MainActivity", "noReset", true));
@When("I enter {string} as the username")
public void i_enter_as_the_username(String username) {
  // Enter the username
  driver.findElement(By.id("com.example.loginapp:id/username")).sendKeys(username);
}
@When("I enter {string} as the password")
public void i_enter_as_the_password(String password) {
  // Enter the password
  driver.findElement(By.id("com.example.loginapp:id/password")).sendKeys(password);
}
@When("I tap on the login button")
public void i_tap_on_the_login_button() {
  // Tap on the login button
  driver.findElement(By.xpath("//android.widget.Button[@text='Login']"))
    .click();
}
@Then("I should see the home screen")
public void i_should_see_the_initial_screen() {
  // Verify the home screen
  assert(driver.findElement(By.id("com.example.loginapp:id/menu")).isDisplayed());
}
@Then("I should see a welcome message")
public void i_should_see_a_welcome_message() {
  // Verify the welcome message
  assert(driver.findElement(By.id("com.example.loginapp:id/welcome")).getText().equals("Welcome, testuser!"));
}
// Quit the driver
driver.quit();
}
Copied!

Structurize your project

Create a proper folder structure for your test code, by organizing the test files and folders according to their functionality, purpose, and hierarchy.

mobile-test-automation-framework
├── src
│   ├── main
│   │   ├── java
│   │   │   ├── config
│   │   │   │   └── Config.java
│   │   │   ├── drivers
│   │   │   │   ├── AndroidDriverManager.java
│   │   │   │   └── IOSDriverManager.java
│   │   │   ├── pages
│   │   │   │   ├── BasePage.java
│   │   │   │   ├── HomePage.java
│   │   │   │   ├── LoginPage.java
│   │   │   │   └── ProfilePage.java
│   │   │   └── utils
│   │   │       ├── Logger.java
│   │   │       ├── Reporter.java
│   │   │       └── TestUtils.java
│   │   └── resources
│   │       ├── app
│   │       │   ├── android
│   │       │   │   └── app.apk
│   │       │   └── ios
│   │       │       └── app.ipa
│   │       └── config.properties
│   └── test
│       ├── java
│       │   ├── base
│       │   │   └── BaseTest.java
│       │   ├── data
│       │   │   └── TestData.java
│       │   └── tests
│       │       ├── LoginTest.java
│       │       └── ProfileTest.java
│       └── resources
│           └── testng.xml
├── pom.xml
└── README.md

Separate test data

Final best practice is separating the test cases from the test automation framework, by storing the test data, test scripts, and test configurations in external files or databases, rather than hard-coding them in the test code. 

Implement a continuous integration and delivery pipeline

The fourth step is to implement a continuous integration and delivery pipeline that can automate the test execution and deployment processes and ensure the continuous delivery of high-quality software.

There are 5 stages of continuous integration and delivery:

  • Code analysis: A stage that checks the quality and security of the test code, using tools such as SonarQube, PMD, etc.
  • Build: A stage that compiles and packages the test code using tools such as Maven, Gradle, etc.
  • Test: A stage that runs the automated tests using tools such as Jenkins, Bamboo, etc.
  • Report: A stage that generates and publishes the test reports, using tools such as Allure, TestNG, etc.
  • Deploy: A stage that deploys the software to the target environment, using tools such as Ansible, Chef, etc.

An example of a Jenkins pipeline script using Appium and Java:

pipeline {
  agent any
  tools {
    maven 'Maven 3.6.3'
    jdk 'Java 11'
  }
  stages {
    stage('Code Analysis') {
      steps {
        echo 'Running code analysis...'
        sh 'mvn sonar:sonar'
      }
    }
    stage('Build') {
      steps {
        echo 'Building the project...'
        sh 'mvn clean install -DskipTests'
      }
    }
    stage('Test') {
      steps {
        echo 'Running the tests...'
        sh 'mvn test -DsuiteXmlFile=testng.xml'
      }
    }
    stage('Report') {
      steps {
        echo 'Generating and publishing the test report...'
        allure includeProperties: false, jdk: '', results: [[path: 'target/allure-results']]
      }
    }
    stage('Deploy') {
      steps {
        echo 'Deploying the app to the target environment...'
        sh 'ansible-playbook deploy.yml'
      }
    }
  }
}
Copied!

Use a cloud-based testing platform for cross-platform and cross-device testing

The fifth step is to use a cloud-based testing platform that can provide you with access to a large pool of real devices and browsers and enable you to perform cross-platform and cross-device testing.

However, cross-platform and cross-device testing can be challenging, as it requires a lot of resources, time, and effort to set up and maintain a physical device lab. A cloud-based testing platform can solve this problem, by offering you the following benefits:

  • You can access hundreds of real devices and browsers with different operating systems, versions, and configurations.
  • You can run your automated tests in parallel, on multiple devices and browsers, and reduce the test execution time and cost.
  • You can leverage the advanced features and functionalities of the cloud-based testing platform, such as test recording, test debugging, test analytics, test collaboration, etc.
  • You can integrate the cloud-based testing platform with your test automation tools and technologies and your continuous integration and delivery pipeline.

Here is how you can integrate a popular cloud-based platform BrowserStack with Java Appium:

  1. Set up the remote Appium WebDriver with your BrowserStack credentials and the desired capabilities for the app and device.
  2. Upload your app to BrowserStack using the REST API and get the app URL.
  3. Set the app capability to the app URL, and initialize the driver with the BrowserStack server URL.
  4. Write your test cases using Appium commands and run them on BrowserStack.
// Import the required libraries
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.net.MalformedURLException;
import java.net.URL;

public class BrowserStackTest {

  // Declare the driver object
  public static AppiumDriver driver;
  public static void main(String[] args) throws MalformedURLException {

    // Set your BrowserStack credentials
    String userName = "YOUR_USERNAME";
    String accessKey = "YOUR_ACCESS_KEY";

    // Set the desired capabilities for the app and device
    DesiredCapabilities caps = new DesiredCapabilities();
    caps.setCapability("deviceName", "Samsung Galaxy S22 Ultra");
    caps.setCapability("platformName", "Android");
    caps.setCapability("platformVersion", "12.0");
    caps.setCapability("browserstack.local", true);
    caps.setCapability("buildName", "browserstack-build-1");
    caps.setCapability("projectName", "BrowserStack Sample");

    // Upload your app to BrowserStack using the REST API and get the app URL
    String appURL = BrowserStackUploader.uploadApp(userName, accessKey, "path/to/your/app.apk");

    // Set the app capability to the app URL
    caps.setCapability("app", appURL);

    // Initialize the driver with the BrowserStack server URL and the capabilities
    driver = new AppiumDriver(new URL("https://" + userName + ":" + accessKey + "@hub-cloud.browserstack.com/wd/hub"), caps);

    // Write your test cases using Appium commands
    // For example, login to the app and verify the result
    driver.findElement(By.id("com.example.loginapp:id/username")).sendKeys("testuser");
    driver.findElement(By.id("com.example.loginapp:id/password")).sendKeys("testpass");
    driver.findElement(By.id("com.example.loginapp:id/submit")).click();
    assert(driver.findElement(By.id("com.example.loginapp:id/welcome")).isDisplayed());
    System.out.println("Login successful");

    // Quit the driver
    driver.quit();
  }
}
Copied!

Conclusion

Mobile automation framework design is a critical and complex task, that requires careful planning, selection, and implementation of the best strategies, tools, and technologies.

At Alphabin, we follow the strategies that we have shared in this blog, you can create a scalable and maintainable open-source test automation framework that can support your testing needs and goals.

Read the next chapter

Frequently Asked Questions

What factors should be considered when designing a mobile test automation framework?
FAQ Arrow

When designing a mobile test automation framework, consider the following factors:

  • Platform Compatibility: Ensure the framework supports all platforms your app will run on, such as iOS, Android, and cross-platform solutions.
  • Language and Tools: Choose programming languages and tools that align with your team’s skills and the application’s technology stack.
  • Test Scope and Types: Define the types of tests needed, such as unit, integration, UI, and performance tests, and ensure the framework can handle them.
  • Continuous Integration/Continuous Deployment (CI/CD): The framework should integrate with CI/CD pipelines for automated builds and testing.
  • Reporting and Analytics: Implement detailed reporting and analytics for test results to identify trends and issues quickly.
How do I choose the right design pattern for my project?
FAQ Arrow

Choosing the right design pattern depends on the specific needs of your project. Factors to consider include the size and complexity of the application, the skills of the test automation team, and the maintainability of the test code. It’s essential to evaluate the pros and cons of each pattern and consider how it will fit into your existing test infrastructure.

How do you ensure the scalability and maintainability of a test automation framework?
FAQ Arrow

To ensure the scalability and maintainability of our mobile test automation framework, we do the following:

  • Modular Design: Use a modular approach to allow for easy updates and additions.
  • Code Reusability: Write reusable code and create libraries for common functions to reduce redundancy.
  • Documentation: Maintain comprehensive documentation for the framework and test cases.
  • Version Control: Use version control systems to manage changes and collaborate effectively.
  • Regular Refactoring: Periodically review and refactor the code to improve efficiency and adapt to new requirements.
What are some best practices for framework design?
FAQ Arrow

Best practices for designing a test automation framework include starting with a clear understanding of the application’s requirements, selecting the right tools and technologies, and building a framework that is flexible enough to handle different types of tests. It’s also crucial to document the framework design and provide training for team members.

About the author

Naman Upadhyay

Naman Upadhyay

Naman Upadhyay, a proficient QA Engineer at Alphabin, excels in Python and React, proficiently managing diverse projects.

Known for his precision-driven approach, he delivers high-quality software solutions.

More about the author
Join 1,241 readers who are obsessed with testing.
Consult the author or an expert on this topic.
Join 1,241 readers who are obsessed with testing.
Consult the author or an expert on this topic.
No items found.