Welcome back to our 3 part series of guest posts written by
Unmesh Gundecha, testing guru and author of
Selenium Testing Tools Cookbook . Read on to hear about how to use Appium, Cucumber-JVM, Jenkins, and Sauce Labs to do iOS acceptance testing.
___________________________________
Running features with Maven
Before we move forward, we need a configure class which tells Cucumber options for running these features. Add a new Java class RunCukesTest to scr/test/java/bmicalculator.test and copy following code
package bmicalculator.test;
import cucumber.junit.Cucumber;
import org.junit.runner.RunWith;
@RunWith(Cucumber.class)
@Cucumber.Options(format = {"pretty", "html:target/cucumber-html-report", "json-pretty:target/cucumber-report.json"})
public class RunCukesTest {
}
Now let’s run this feature file, in terminal navigate to the project folder and run following command
mvn test
After executing the above command, Cucumber will suggest some step definitions for missing steps as below
You can implement missing steps with the snippets below:
@Given("^I enter \"([^\"]*)\" as height$")
public void I_enter_as_height(String arg1) throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
@Given("^I enter \"([^\"]*)\" as weight$")
public void I_enter_as_weight(String arg1) throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
@Given("^I press the Calculate button$")
public void I_press_the_Calculate_button() throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
@Then("^I should see \"([^\"]*)\" as bmi and \"([^\"]*)\" as category$")
public void I_should_see_as_bmi_and_as_category(String arg1, String arg2) throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
Undefined step: Given I enter "170" as height
Undefined step: And I enter "50" as weight
Undefined step: And I press the Calculate button
Undefined step: Then I should see "17.30" as bmi and "Underweight" as category
Undefined step: Given I enter "181" as height
Undefined step: And I enter "80" as weight
Undefined step: And I press the Calculate button
Undefined step: Then I should see "24.42" as bmi and "Normal" as category
Undefined step: Given I enter "180" as height
Undefined step: And I enter "90" as weight
Undefined step: And I press the Calculate button
Undefined step: Then I should see "27.78" as bmi and "Overweight" as category
Undefined step: Given I enter "175" as height
Undefined step: And I enter "100" as weight
Undefined step: And I press the Calculate button
Undefined step: Then I should see "32.65" as bmi and "Obese" as category
1 scenario (0 passed)
16 steps (0 passed)
Implementing Step Definitions
Cucumber drives features with automated steps using step definitions. Step definitions are glue between the steps described in a Scenario to the actual automation code which drive the App either through API or User Interface. The App user interface many not be ready at this time.
While development team is busy in developing the App, let’s create place holders for the steps from sample scenario
Add new Java class Bmi_Calculator_Step_Defs to src/test/java/bmicalculator.test package and implement steps for the example feature that we are testing. We will mark them as pending with Cucumber PendingExeception() as below
package bmicalculator.test;
import cucumber.annotation.en.*;
import cucumber.runtime.PendingException;
public class Bmi_Calculator_Step_Defs {
@Given("^I enter \"([^\"]*)\" as height$")
public void I_enter_as_height(String arg1) throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
@Given("^I enter \"([^\"]*)\" as weight$")
public void I_enter_as_weight(String arg1) throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
@Given("^I press the Calculate button$")
public void I_press_the_Calculate_button() throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
@Then("^I should see \"([^\"]*)\" as bmi and \"([^\"]*)\" as category$")
public void I_should_see_as_bmi_and_as_category(String arg1, String arg2) throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
}
When this feature is executed by Cucumber, it will show these steps as pending.
Developers are done with the initial version of the App and it’s ready for testing. In the next step we will implement the steps by driving the user interface of the App using Appium and Selenium API to check the expected behavior of the application.
In this step we need to declare an instance of WebDriver class from Selenium. We will add a setup method setupLocal() which will initialize the driver instance and connect to Appium running on a local machine
private WebDriver driver;
@Before
public void setUpLocal() throws Throwable {
//Setup for running Appium test in local environment
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.BROWSER_NAME, "iOS");
capabilities.setCapability(CapabilityType.VERSION, "6.1");
capabilities.setCapability(CapabilityType.PLATFORM, "Mac");
capabilities.setCapability("app", "/Users/upgundecha/Desktop/AppExamples/BmiCalculator/build/Release-iphonesimulator/BmiCalculator.app");
//Create an instance of RemoteWebDriver and connect to the Appium server.
//Appium will launch the BmiCalc App in iPhone Simulator using the configurations specified in Desired Capabilities
driver = new RemoteWebDriver(new URL("http://0.0.0.0:4723/wd/hub"), capabilities);
}
Also implement the steps with Selenium API to interact with the application elements in following way
public void I_enter_as_height(String height) throws Throwable {
WebElement heightTextField = driver.findElement(By.name("Height"));
heightTextField.sendKeys(height);
}
@Then("^I enter \"([^\"]*)\" as weight$")
public void I_enter_as_weight(String weight) throws Throwable {
WebElement weightTextField = driver.findElement(By.name("Weight"));
weightTextField.sendKeys(weight);
}
@Then("^I press the Calculate button$")
public void I_press_the_Calculate_button() throws Throwable {
WebElement calculateButton = driver.findElement(By.name("Calculate"));
calculateButton.click();
}
@Then("^I should see \"([^\"]*)\" as bmi and \"([^\"]*)\" as category$")
public void I_should_see_as_bmi_and_Normal_as_category(String bmi, String category) throws Throwable {
WebElement bmilabel = driver.findElement(By.name("bmi"));
WebElement bmiCategorylabel = driver.findElement(By.name("category"));
//Check the calculated Bmi and Category displayed
assertEquals(bmi,bmilabel.getText());
assertEquals(category,bmiCategorylabel.getText());
}
At the end add a teardown method to close the App
public void tearDown() {
driver.quit();
}
This makes the step definitions complete. When the feature is run, Cucumber will call the Selenium API which in turn calls the Appium and steps are performed on the App’s user interface in iOS Simulator. At the end of the execution Cucumber will display results as below
1 scenario (1 passed)
16 steps (16 passed)
Come back next week to see the final post on running features in the Sauce cloud!
Read
Part 1