Part 5. Creating your First Proper Test

Creating your First Proper Test

Introduction

In this section, we will create our first proper test scenario. In this test scenario we will launch the Artistry app, tap the ‘Pablo Picasso’ button and then select to see more info for the ‘Guernica’ painting at the top.

We will then assert that we see the correct additional info for the ‘Guernica’ painting.

Let’s get started 😀

Creating the Cucumber Scenario

When creating our BDD scenarios, we want to keep them simple and write them in a declarative style, sticking simply to the business logic, rather than writing them in an imperative style.  A great article on this can be found at http://itsadeliverything.com/declarative-vs-imperative-gherkin-scenarios-for-cucumber.

  1. Right-click on the src/test/resources/features directory, select ‘New’ –> ‘File’ and create a file called something like ‘NavigationScenarios.feature’
  2. Open up the ‘NavigationScenarios.feature’ file and add the following test scenario. We can also add a Cucumber tag again (e.g ‘@Iphone8’) either above the ‘Scenario’ (to apply to the specific scenario) or above the ‘Feature’ (to apply to all scenarios within the feature)…
    @Iphone8
    Feature: Navigation Scenarios
      As a user of Artistry, I can navigate around the Artistry app
    
      Scenario: 01. View more info for the 'Guernica' painting
        Given the Artistry app user is viewing paintings by Pablo Picasso
        When the user views more info for Guernica painting
        Then the user sees
         | Guernica is a                |
         | mural-sized oil painting     |
         | powerful anti-war paintings  |

    We can verify that the text we are asserting on the ‘Pablo Picasso’ screen is correct by navigating to that screen in our Appium Desktop session and clicking on the ‘Guernica’ button to see more info 🙂

If you’ve been following all the blog posts in this series, you will notice that we have reused an existing step in this scenario, such as;

  • Then the user sees

The other undefined step definitions will be highlighted as being undefined still.

Creating the Undefined Step Definitions

  1. Highlight some of the ‘Given the Artistry app user is viewing paintings by Pablo Picasso”‘ step in IntelliJ until a yellow light bulb icon appears next to it
  2. Click the yellow light bulb icon and select ‘Create step definition’ –> ‘NavigationSteps (steps)’
    • An undefined step definition should be automatically added to ‘NavigationSteps’ like below…
      • If ‘NavigationSteps (steps)’ is not listed, choose one that is listed then cut and paste the step definition in to the ‘NavigationSteps’ class. It should look similar to below…
        package steps;
        
        import cucumber.api.PendingException;
        import io.cucumber.java.en.Given;
        
        public class NavigationSteps extends Page {
        
            @Given("^I am viewing paintings by Pablo Picasso$")
            public void iAmViewingPaintingsByPabloPicasso() throws Throwable {
                // Write code here that turns the phrase above into concrete actions
                throw new PendingException();
            }
        }
  3. Highlight some of the ‘When the user views more info for Guernica painting’ step in IntelliJ until a yellow ligh tbulb icon appears next to it
  4. Click the yellow light bulb icon and select ‘Create step definition’ –> ‘PaintingSteps (steps)’
    • An undefined step definition should be automatically added to ‘PaintingSteps’ like below…
      • If ‘PaintingSteps (steps)’ is not listed, choose one that is listed then cut and paste the step definition in to the ‘PaintingSteps’ class. It should look similar to below…
        package steps;
        
        import cucumber.api.PendingException;
        import io.cucumber.java.en.When;
        
        public class PaintingSteps extends Page {
        
            @When("^I view more info for Guernica painting$")
            public void iViewMoreInfoForGuernicaPainting() throws Throwable {
                // Write code here that turns the phrase above into concrete actions
                throw new PendingException();
            }
        }

Creating the Test Methods

navToPabloPicasso() Method

We will now create test methods in Java for each of our undefined steps.

Because we are taken to a new ‘Pablo Picasso’ screen when we tap the Pablo Picasso button on the base screen, we should create a new page class for the ‘Pablo Picasso’ tab screen.

  1. Right-click on the ‘pages’ package, select ‘New’ –> ‘Java Class’ and create a class file called ‘PabloPicassoPage’
  2. Open up the ‘PabloPicassoPage’ class and edit it so it looks like below (we want it to inherit from BasePage, as that is where we navigate to the page/screen from. We also want to add a Logger to the page)…
    package pages;
    
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    public class PabloPicassoPage extends BasePage {
    
        private static Logger log = LogManager.getLogger(PabloPicassoPage.class.getName());
    }
    

    Because we have already added an IOSElement for the ‘Pablo Picasso’ button on the BasePage, we can simply write a method to click on that element and take us to the new PabloPicassoPage we made 🙂

  3. Open up the ‘BasePage’ class in the ‘pages’ package again and add the following method that clicks on the ‘Pablo Picasso’ button and returns an instance of the PabloPicassoPage class…
    public PabloPicassoPage navToPabloPicasso() {
        btnPabloPicasso.click();
        log.info(":: We navigate to the Pablo Picasso screen");
        return instanceOf(PabloPicassoPage.class);
    }

viewMoreInfoGuernica() Method

We will now add our void click method to see more info for the Guernica painting. Because this action occurs on the PabloPicassoPage, that is the class where we will add this method.

  1. If we inspect the ‘Guernica’ button in Appium Inspector we can see that it has an Accessibility ID of ‘Guernica’…
    Let’s add an @iOSFindBy annotation and IOSElement for this ‘Guernica’ button 🙂
  2. Open up the ‘PabloPicassoPage’ class in the ‘pages’ package and add the following IOSElement in the top of the class, the whole thing should look like below…
    package pages;
    
    import io.appium.java_client.ios.IOSElement;
    import io.appium.java_client.pagefactory.iOSFindBy;
    
    public class PabloPicassoPage extends BasePage {
        
        @iOSFindBy(accessibility = "Guernica")
        private IOSElement btnGuernica;
    }
  3. Now let’s add the following void click method to click on the ‘Guernica’ button and display the additional info of the painting. Add the following method inside the ‘PabloPicassoPage’ class…
    public void viewMoreInfoGuernica() {
        btnGuernica.click();
        log.info(":: We select to view more info for the 'Guernica' painting");
    }

    The whole thing should look like below…

    package pages;
    
    import io.appium.java_client.ios.IOSElement;
    import io.appium.java_client.pagefactory.iOSFindBy;
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    public class PabloPicassoPage extends BasePage {
    
        private static Logger log = LogManager.getLogger(PabloPicassoPage.class.getName());
    
        @iOSFindBy(accessibility = "Guernica")
        private IOSElement btnGuernica;
    
        public void viewMoreInfoGuernica() {
            btnGuernica.click();
            log.info(":: We select to view more info for the 'Guernica' painting");
        }
    }

Connecting the Step Definitions to the Test methods

We will now call the test methods from their appropriate step definitions.

  1. Open up the ‘ReturnClickSteps’ class again, and refactor the “And I tap on Pablo Picasso” step so it initialises the page (in this case ‘BasePage’) with the correct IOS elements rendered and then calls the ‘navToPabloPicasso()’ method, like below (also remove the Throwable that will never be thrown)…
    @Given("^the Artistry app user is viewing paintings by Pablo Picasso$")
    public void iAmViewingPaintingsByPabloPicasso() {
        instanceOf(BasePage.class).navToPabloPicasso();
    }
  2. Open up the ‘PaintingSteps’ class again, and refactor the “When the user views more info for Guernica painting” step so it initialises the page (in this case ‘PabloPicassoPage’) with the correct IOS elements rendered and then calls the ‘viewMoreInfoGuernica()’ method, like below (also remove the Throwable that will never be thrown)…
    @When("^the user views more info for Guernica painting$")
    public void iViewMoreInfoForGuernicaPainting() {
        instanceOf(PabloPicassoPage.class).viewMoreInfoGuernica();
    }

Running the Test Scenario

Running the Test

  1. Open up ‘BaseScenarios.feature’ file and make sure you have the ‘@Iphone8’ tag at the top of the feature file or above each test scenario you want to run
  2. Right-click on the test scenario and run it

It should pass successfully 😀

In the next section, we will create static methods we can use as wrapper methods to keep our code nice and clean 😀