Mobile App Testing
Mobile App Testing: Selenium with Java and Cucumber – Insights
Introduction
Automate mobile app testing with Selenium, Cucumber & Appium. Improve test efficiency, ensure scalability, and streamline CI/CD with BDD & parallel execution.
Selenium, Cucumber, and Appium have been essential in automating mobile application testing. These tools reduce repetitive tasks and help teams ensure robust application quality. This article explores real-world scenarios, challenges faced, and best practices for implementing an efficient test automation framework.
Why We Chose Selenium, Cucumber, and Appium
Appium, built on Selenium, extends automation to mobile applications. It supports native, hybrid, and web apps on both iOS and Android, making cross-platform automation seamless. Since it provides a unified API, the learning curve remains low.
Cucumber enhances behavior-driven development (BDD), allowing technical and non-technical teams to collaborate more effectively. It uses Gherkin syntax to create human-readable test scenarios and integrates smoothly with Selenium and Appium. Our goal was to build a scalable and maintainable test automation framework, and these tools offered the ideal foundation.
Setting Up Appium with Selenium and Cucumber
We started by creating a Maven project and defining dependencies for Selenium, Cucumber, and Appium in the pom.xml
file. The setup also included configuring the Appium server and specifying device-related settings for mobile automation.
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.10.0</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>7.10.0</version>
</dependency>
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>8.4.0</version>
</dependency>
</dependencies>
To structure our tests, we used cucumberOptions
in the runner class to define feature files and step definitions. This approach ensured the framework could scale efficiently as the application evolved.
Real-World Scenarios and Challenges
One major project involved automating the PETCare/Mythings app. Our tests focused on critical functionalities, such as biometric authentication for login, appointment scheduling, and pet medical history tracking. Since the app had to perform consistently across multiple devices, UI behavior validation was a priority.
However, platform-specific locators presented a challenge. Android and iOS required different locators, which we resolved using Appium’s MobileBy
class. Managing multiple devices for parallel execution also proved complex. To solve this, we configured Appium servers with unique ports for each device.
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("platformName", "Android");
caps.setCapability("deviceName", "Pixel_5_API_30");
caps.setCapability("app", "path/to/app.apk");
caps.setCapability("automationName", "UiAutomator2");
By integrating Appium tests into Cucumber scenarios, we ensured consistent reporting and execution.
Parallel Testing in CI/CD Pipelines
To optimize test execution time, we enabled parallel execution in Cucumber using JUnit. Running device-specific scenarios in parallel significantly reduced execution time during nightly builds.
@RunWith(Cucumber.class)
@CucumberOptions(
features = "src/test/resources/features",
glue = "com.example.steps",
plugin = {"pretty", "json:target/cucumber-report.json"},
monochrome = true
)
public class TestRunner {}
However, thread safety became an issue. Since multiple tests ran concurrently, each Appium instance needed to remain isolated. We addressed this by implementing a thread-local factory for device management.
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofSeconds(2))
.ignoring(NoSuchElementException.class);
Additionally, synchronization issues led to test failures due to race conditions. Instead of using fixed delays, we incorporated FluentWait to dynamically wait for elements:
Implementing Page Object Model (POM) for Mobile Applications
To improve maintainability, we adopted the Page Object Model (POM). Each screen had a dedicated class that encapsulated locators and actions. For platform-specific actions, we extended this structure accordingly.
A sample feature file in Gherkin syntax looked as follows:
Feature: Login to PETcare App
Scenario: User logs in with valid credentials
Given the user is on the login screen
When the user enters valid credentials
And clicks the login button
Then the user should be redirected to the homepage
The corresponding step definitions were implemented in Java:
package com.example.steps;
import io.cucumber.java.en.*;
import com.example.pages.LoginPage;
public class LoginSteps {
LoginPage loginPage = new LoginPage();
@Given("the user is on the login screen")
public void userOnLoginScreen() {
loginPage.navigateToLoginScreen();
}
@When("the user enters valid credentials")
public void userEntersCredentials() {
loginPage.enterUsername("testUser");
loginPage.enterPassword("password123");
}
@And("clicks the login button")
public void clickLogin() {
loginPage.clickLoginButton();
}
@Then("the user should be redirected to the homepage")
public void verifyHomePage() {
loginPage.verifyHomePage();
}
}
This approach made test cases more readable and maintainable. Gherkin syntax ensured that even non-technical stakeholders could understand the tests. Step definitions became reusable across multiple scenarios, and locator updates were confined to the page class, reducing test maintenance efforts.
Lessons Learned and Best Practices
Planning for scalability was crucial. Modular feature files and step definitions helped organize tests by functionality, while externalizing test data in formats like JSON or Excel improved flexibility. Synchronization mechanisms were refined by avoiding hard-coded sleep statements, instead leveraging FluentWait and ExpectedConditions for more stable test execution.
Maximizing reusability played a key role in efficient automation. Implementing reusable components, including Appium factories, reporting utilities, and custom assertions, streamlined test management. Reporting was enhanced by integrating Cucumber with tools like Allure, providing actionable insights into test execution.
Conclusion
The experience of using Selenium, Cucumber, and Appium demonstrated their ability to transform mobile application testing. Features such as BDD, parallel execution, POM, and data-driven testing contributed to a scalable and robust automation framework. Whether starting or scaling automation efforts, these tools offer a solid foundation for success.
Enhance your mobile app testing with Selenium, Cucumber, and Appium for faster, more reliable automation. Our experts can help you build a scalable framework tailored to your needs. Contact us now to streamline your testing process and boost efficiency!
WRITTEN BY
February 14, 2025, Product Development Team
Top Categories
- Software Development ................... 6
- AI in Business ................... 5
- Digital Marketing ................... 3
- Business Technology ................... 3
- Pricing Strategies ................... 3