Mobile Automation Testing with Cucumber, Appium, and Allure Reporting for iOS
Introduction
Cucumber is a open-source software tool used for behavior-driven development (BDD). It defines application behavior using a plain language called “Gherkin” that customers can easily understand. It uses keywords such as “Given,” “When,” and “Then”.
Requirement for Cucumber Testing
The requirements are slightly different for Cucumber testing on iOS. Here is everything you will need:
- WebDriverAgent
- Xcode
- Appium Server
- iOS Simulator
- Appium Inspector
- iOS App
WebDriverAgent
WebDriverAgent is an open-source server for automation testing of iOS apps using Selenium and Appium. It offers a reliable solution for iOS application testing across various devices and operating system versions.
WebDriverAgent acts as a bridge between Selenium/Appium and iOS apps, which allows testers to interact with native iOS elements through code. This tool supports the execution of automated tests on both iOS devices and simulators.
“WebDriverAgent” installation.
Xcode
For iOS app development, Xcode is the integrated development environment (IDE). So, install Xcode from the Mac App Store. It includes the necessary tools and simulators for iOS app testing.
Appium Server
We need the Appium server for iOS testing. You can install it using npm (Node Package Manager) by running the command:
npm install -g appium
.
iOS Simulator
Xcode comes with in-built iOS simulators that used for testing. After installing Xcode, launch the iOS simulator from Xcode’s “Window” > “Devices and Simulators” menu.
Appium Inspector for iOS
Appium provides an Inspector tool for inspecting iOS elements during testing. You can launch it by starting the Appium server and clicking on the “Start Inspector Session” button.
iOS App
You’ll need the .app file of the iOS app you want to test. Make sure you have access to the app’s binary file for testing purposes.
Cucumber File Structure:
1. Featue file
2. BaseClass
3. Pages
4. Step-definitions
5. Locators
6. Runner Class
Project Setup in IDE
To write our test cases in Java, we need any Java-based IDE (integrated development environment) like Eclipse or IntelliJ. We can write and organize our code here.
We’ll use Eclipse to write our test cases. Open Eclipse. You’ll see a bunch of options. Click on “File”, then choose “New” and then “Other.”.
Next, type “Maven” in the search box and click enter. After that, select “Maven Project” and click on the “Next” button.
Ensure that the first checkbox labeled “Create a simple project (skip archetype selection)” is checked. This option simplifies the project creation process by skipping the selection of project archetypes. After ensuring the checkbox is selected, click on the “Next” button to proceed to the next step in creating your Maven project.
Now, give the Group ID and Artefact ID fields; it’s common practice to use the same value. This helps maintain consistency and clarity within your project structure.
Once your project is opened in Eclipse, locate the pom.xml file in the project directory. This file contains the configuration for your Maven project, including dependencies. To add the dependencies to your project.
<dependencies>
<!-- https://mvnrepository.com/artifact/com.github.appium/java-client -->
<dependency>
<groupId>com.github.appium</groupId>
<artifactId>java-client</artifactId>
<version>7.4.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hamcrest/hamcrest-all -->
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.appium/java-client -->
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>7.6.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-api -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-api</artifactId>
<version>3.141.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.qameta.allure/allure-testng -->
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-testng</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>7.2.0</version> <!-- Use the latest version -->
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-testng</artifactId>
<version>7.2.0</version> <!-- Use the same version as cucumber-java -->
<scope>test</scope>
</dependency>
</dependencies>
Feature File
To write cucumber tests, we use files with a .feature extension. In this files, “Gherkin” language is used.
Inside the “src/main/resources” directory create a new folder called “features”. This folder will contains all Cucumber feature files. In this post, we’ll test the built-in calculator app on a connected iOS simulator.
Inside the “features” folder, create a new file named “demo.feature.” This file will contain the scenarios for testing the built-in calculator app on an iOS simulator.
Each scenario in the feature file represents a specific test case. For example:
Feature: Adding two numbers in the calculator
Scenario: Adding two positive numbers
Given User opens the calculator
When User adds two numbers
Then User valid the results
BaseClass
The base class contains settings for desired capabilities and teardown code shared across multiple test cases, ensuring consistency and maintainability.
package com.baseclass;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.MobileElement;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.remote.AutomationName;
import io.appium.java_client.remote.MobileCapabilityType;
public class BaseClass {
protected static IOSDriver<MobileElement> driver;
public static void setUp () throws MalformedURLException {
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone 14 Pro Max");
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "16.4");
caps.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.IOS_XCUI_TEST);
caps.setCapability("appium:autoAcceptAlerts", "true");
caps.setCapability("appium:appWaitForLaunch", "false");
caps.setCapability("appium:autoGrantPermissions", "true");
driver = new IOSDriver <MobileElement>(new URL("http://localhost:4723/wd/hub"),caps);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
}
Locators
The locator file defines and stores the locators of elements on mobile application.
package customerApp.locators;
public class Common_locators {
public static final String Calendar = "Calendar";
public static final String Calendar_xpath = "(//XCUIElementTypeIcon[@name=\"Calendar\"])[2]";
public static final String Add_icon = "Add";
public static final String Title_field = "Title";
public static final String all_day_switch_buttton_xpath = "//XCUIElementTypeSwitch[@name=\"All-day\"]";
public static final String Add_text_xpath = "(//XCUIElementTypeButton[@name=\"Add\"])[2]";
public static final String Meeting_All_day = "Meeting, All day";
public static final String Meeting_All_day_xpath = "//XCUIElementTypeButton[@name=\"Meeting, All day\"]";
public static final String Today_xpath = "//XCUIElementTypeButton[@name=\"Today\"]";
public static final String Today = "Today";
public static final String April = "April";
public static final String year_2024 = "2024";
}
Pages
Page files represent specific pages or components within the application and include methods for interacting with various UI elements.
package customerApp.pages;
import org.openqa.selenium.By;
import com.baseClass.LibGlobal;
import customerApp.locators.Common_locators;
import io.appium.java_client.MobileElement;
import io.appium.java_client.ios.IOSDriver;
public class QuickpayPages extends LibGlobal{
public QuickpayPages(IOSDriver<MobileElement> driver) {
this.driver=driver;
}
public void login() throws InterruptedException {
implicitlyWait(30, driver);
driver.findElement(By.xpath(Common_locators.Calendar_xpath)).click();
}
public void scheduled_the_meeting() throws InterruptedException {
implicitlyWait(30, driver);
driver.findElement(By.name(Common_locators.Add_icon)).click();
driver.findElement(By.name(Common_locators.Title_field)).sendKeys(("Meeting"));
driver.findElement(By.xpath(Common_locators.all_day_switch_buttton_xpath)).click();
driver.findElement(By.xpath(Common_locators.Add_text_xpath)).click();
}
public void verify_the_calendar() throws InterruptedException {
implicitlyWait(30, driver);
try {
implicitlyWait(5, driver);
System.out.println("1");
driver.findElement(By.name(Common_locators.Meeting_All_day)).isDisplayed();
System.out.println("2");
} catch (Exception e) {
System.out.println("3");
int numberOfClicks = 2;
for (int i = 0; i < numberOfClicks; i++) {
driver.findElement(By.name(Common_locators.Today)).click();
}
driver.findElement(By.name(Common_locators.Meeting_All_day)).isDisplayed();
}
System.out.println("4");
driver.findElement(By.name(Common_locators.April)).click();
driver.findElement(By.name(Common_locators.year_2024)).click();
}
}
Step Definitions
Step definitions translate the plain-language steps in feature files into executable code, driving the actual test execution. contains step definitions that translate plain-language steps from feature files into executable code, facilitating the actual test execution.
package com.steps;
import com.baseClass.LibGlobal;
import customerApp.pages.QuickpayPages;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
public class LoginSteps extends LibGlobal{
QuickpayPages quickpay;
@Given("User open the calculator")
public void user_select_the_language() throws InterruptedException {
quickpay= new QuickpayPages (driver);
quickpay.login();
}
@When("User adds two number")
public void user_click_the_next_button() throws InterruptedException {
quickpay.scheduled_the_meeting();
}
@Then("User valid the results")
public void user_nagigate_to_home_page() throws InterruptedException {
quickpay.verify_the_calendar();
}
}
Runner Class
The RunnerClass file is responsible for orchestrating the execution of cucumber tests. It specifies the location of feature files and step definitions.
package com.runner;
import java.net.MalformedURLException;
import org.testng.annotations.BeforeClass;
import com.baseClass.BaseClass;
import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
@CucumberOptions(features="src/test/resources/features", glue={"com.steps"})
public class RunnerClass extends AbstractTestNGCucumberTests {
@BeforeClass
public void setUp() throws MalformedURLException {
BaseClass.setUp();
}
}
Now, back in the project, right-click on the com.runner.java file. Then, click on Run As > TestNG test.
After executing the Maven test for the “LoginSteps.java” file from the terminal, you’ll see the test results displayed in the console. If all test cases succeed, you’ll typically see a summary indicating that the tests passed.
After executing your Cucumber Runner class, proceed to open the command prompt or terminal on your machine. Navigate to the directory where your Allure results are stored using the cd
command. Once you're in the correct directory, input the following command to generate the Allure report:
allure serve allure-results
Overview of Allure Reporting
Allure is an open-source framework to generate detailed test reports for various testing frameworks such as Pytest, JUnit, TestNG, Cucumber, and more.
Allure Annotations
Allure offers several annotations that you can leverage to provide additional context and details in your test reports. Some of the key annotations include:
@Feature
: Describes a high-level feature being tested.@Story
: Describes a specific user story or scenario being tested.@Step
: Marks a step within a test scenario, providing detailed information about each step.@Attachment
: Allows attaching additional files or data (such as screenshots or log files) to the test report.@Description
: Gives a detailed information of a test method or scenario.@Severity
: Severity level of a test case is specified(e.g., critical, high, medium, low).@Issue
: Associated issue or bug-tracking system will connect to a test case.@Link
: Adds hyperlinks to external resources related to the test case.@Owner
: Indicates the owner or responsible person for a test case.@Tag
: Adds tags to categorize or filter test cases.@Epic
: Defines an epic or overarching theme associated with a group of test cases.
Allure report
About the Author
Eraiyanbu is a test automation engineer with extensive experience in automating web and mobile applications. His extensive experience spans planning, creating, and executing test strategies and developing test cases and procedures. He specializes in ensuring software quality through comprehensive software quality assurance testing across the software development life cycle.
About CodeStax.Ai
At CodeStax.AI, we stand at the nexus of innovation and enterprise solutions, offering technology partnerships that empower businesses to drive efficiency, innovation, and growth, harnessing the transformative power of no-code platforms and advanced AI integrations.
But what is the real magic? It’s our tech tribe behind the scenes. If you have a knack for innovation and a passion for redefining the norm, we have the perfect tech playground for you. CodeStax. Ai offers more than a job — it’s a journey into the very heart of what’s next. Join us and be part of the revolution that’s redefining the enterprise tech landscape.