NashTech Blog

Cross-Application Framework: Making Your Test Framework Plug-and-Play

Table of Contents
Cross-Application Framework

When working with multiple platforms like the web, Android API one requires a different test framework, which is difficult to maintain and time-consuming to create.

The smarter way is to build a Cross Application Automation framework, one that works across multiple applications using configuration.

In this blog, I’ll walk you through how to create a plug-and-play automation framework that can adapt to any application using just configuration changes—no code duplication required.

Tech Stack Used

  • Java – Programming language
  • Selenium – Web automation
  • Appium – Mobile automation
  • TestNG + Cucumber – BDD + test execution engine
  • Properties + ConfigLoader – Dynamic app/environment switching

Project Structure Overview

Step-by-Step Setup

1. Create BaseTest.java

This class sets up and tears down WebDriver or AppiumDriver based on app config.

public class BaseTest {
    protected WebDriver driver;

    @BeforeMethod
    public void setUp() {
        String app = System.getProperty("app", "crm"); // Check if the user has passed an app name like crm or inventory. Defaults to crm if nothing passed"
        ConfigLoader.load(app); // Loads the .properties file
        driver = DriverFactory.initDriver(); // Creates Web or Mobile driver based on platform
    }

    @AfterMethod
    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }
}

Change "crm" to "inventory" at runtime with -Dapp=inventory to switch the app under test.
No code change needed—just update the runtime parameter.

2. Create ConfigLoader.java – Dynamic Configuration

It will load the file specific app i.e crm/inventory properties file (crm.properties) from the configs folder and makes all the key-value pairs available to the rest of the framework.

public class ConfigLoader {
    private static final Properties properties = new Properties();

    public static void load(String appName) {
        try {
            FileInputStream fileInputStream= new FileInputStream("src/test/java/configs/" + appName + ".properties");
            properties.load(fileInputStream);
        } catch (IOException e) {
            throw new RuntimeException("Failed to load config file for : " + appName, e);
        }
    }

  public static String get(String key) {
        if (properties == null) {
            throw new RuntimeException("Config file not loaded. Call ConfigLoader.load(appName) first.");
        }
        return properties.getProperty(key);
    }
}

3. Create DriverFactory.java – Web or Mobile Driver

Depending on the platform set in your config, it either opens Chrome for web tests or starts Appium for Android tests.

public class DriverFactory {
    public static WebDriver initDriver() {
        String platform = ConfigLoader.get("platform");

        if (platform.equalsIgnoreCase("web")) {
            return new ChromeDriver();
        } else if (platform.equalsIgnoreCase("android")) {
            DesiredCapabilities caps = new DesiredCapabilities();
            caps.setCapability("platformName", "Android");
            caps.setCapability("deviceName", "emulator-5554");
            caps.setCapability("app", ConfigLoader.get("appPath"));
            try {
                return new AndroidDriver<>(new URL("http://localhost:4723/wd/hub"), caps);
            } catch (Exception e) {
                throw new RuntimeException("Failed to initialize Android Driver", e);
            }
        }

        throw new RuntimeException("Unsupported platform: " + platform);
    }
}

4. Create TestRunner.java – Run Cucumber + TestNG

@CucumberOptions(
    features = "src/test/java/features",
    tags="",
    glue = "step_definitions",
    monochrome = true,
    plugin = {"pretty", "html:target/cucumber-report.html"}
)
public class TestRunner extends AbstractTestNGCucumberTests {
 @Override
    @DataProvider(parallel = false)
    public Object[][] scenarios() {
        return super.scenarios();
    }
}

5. Add Feature Files – Example: crm_Login.feature

Feature: CRM Login

  Scenario: Successful login to CRM
    Given I launch the application
    When I enter username and password
    And I click on the login button
    Then I should see the home page

6. Define Test Steps (step_definitions) – Example: CRMLoginSteps.java

public class CRMLoginSteps extends BaseTest {

  @Given("I launch the application")
    public void i_launch_the_application() {
        // Code
    }

    @When("I enter username and password")
    public void i_enter_username_and_password() {
       // Code
    }

    @And("I click on the login button")
    public void i_click_on_the_login_button() {
       // Code
    }

    @Then("I should see the home page")
    public void i_should_see_the_home_page() {
         // Code
    }
}

7. Create App-Specific Config Files

crm.properties

base.url=https://crm.testapp.com
username=testuser
password=testpassword
platform=web

inventory.properties

base.url=https://inventory.testapp.com
username=testuser
password=testpassword
platform=android
appPath=/path/to/inventory.apk

8. Run the Framework

To test different apps, just pass the app name at runtime:

For CRM (web)

mvn test -Dapp=crm

For Inventory (mobile)

mvn test -Dapp=inventory

This works because platform-specific logic is handled inside DriverFactory.

9. Logging (Optional Section)

Logging helps track what’s happening inside your test run—step-by-step using Log4j or ExtentReports. It’s helpful for:

  • Debugging test failures
  • Tracing test execution
  • Knowing which platform/test ran and when

10. Reporting (Optional Section)

Reporting is how you visualize test results after execution.

  • Which tests passed/failed?
  • How long did each test take?
  • What was the browser/app/platform used?
  • What failed and why?

Conclusion

That’s about it! It is no longer necessary to develop a new framework each time a new application or project with a different platform arrangement arises. Whether it’s a mobile inventory app or a CRM web app now, all you need to do is edit a configuration file.

This framework makes things reusable, straightforward, and much simpler to manage. Additionally, instead of repeatedly recreating the same setup, your team may onboard more quickly and concentrate more on testing.

So instead of building new frameworks for each project, build once and plug everywhere. That’s the power of true cross-application adaptability.

References

https://appium.io/docs/en/latest/intro

https://www.selenium.dev/documentation/webdriver

Picture of Kajal Keshri

Kajal Keshri

Leave a Comment

Your email address will not be published. Required fields are marked *

Suggested Article

Scroll to Top