Framework Setup

Creating the Maven Project

  1. Launch IntelliJ and select ‘Create New Project’
  2. Select ‘Maven’ in the left pane
    • Select the appropriate Java JDK in the ‘Project SDK’ dropdown at the top (should be the one installed previously)
    • Click ‘Next’
  3. In the ‘GroupId’ field, enter an appropriate name (e.g. “com.producttestframework”)
  4. In the ‘ArtifactId’ field, input an appropriate name (e.g. “AutomationFramework”)
  5. Click ‘Next’
  6. Give an appropriate Project Name (e.g. “ProductAutomation”) and an appropriate project location on your local machine (e.g. ~/Users/username/DevProjects/ProductAutomation)
  7. Click ‘Finish’
  8. Advance to IntelliJ IDEA –> Preferences/Settings –> Build, Execution, Deployment –> Build Tools –> Maven –> Importing (will be slightly different depending if you’re on Mac or Windows)
    • Ensure ‘Import Maven projects automatically’ is checked

Maven Dependencies

You can manage all your projects dependencies, plugins and packages by simply adding them into your Maven project’s POM.xml file 🙂

  1. Open up the POM.xml file and add the following source and target properties within the <project/> tags…
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
  2. Open up the POM.xml file and add the following dependencies within the <dependencies> tag section. If you do not see any <dependencies/> opening and closing tags, simply add them within the <project/> tags.

Please note that the latest versions may change since the date I wrote this guide.  I recommend searching for each dependency below on https://mvnrepository.com and simply copying the dependencies from there and then pasting them into your project’s POM.xml file.

Do make sure however, that you include certain information like ‘exclusions’ for JUnit in the TestNG dependency as shown in my examples below.

Cucumber Dependencies

Cucumber-Java
<dependency>
   <groupId>io.cucumber</groupId>
   <artifactId>cucumber-java</artifactId>
   <version>4.8.0</version>
   <scope>test</scope>
</dependency>
Cucumber-JVM-Deps
<dependency>
   <groupId>io.cucumber</groupId>
   <artifactId>cucumber-jvm-deps</artifactId>
   <version>1.0.6</version>
   <scope>test</scope>
</dependency>
Cucumber-TestNG
<dependency>
   <groupId>io.cucumber</groupId>
   <artifactId>cucumber-testng</artifactId>
   <version>4.8.0</version>
   <scope>compile</scope>
   <exclusions>
       <exclusion>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
       </exclusion>
   </exclusions>
</dependency>
Cucumber-Reporting
<dependency>
   <groupId>net.masterthought</groupId>
   <artifactId>cucumber-reporting</artifactId>
   <version>4.11.2</version>
</dependency>

TestNG Dependencies

TestNG
<dependency>
   <groupId>org.testng</groupId>
   <artifactId>testng</artifactId>
   <version>6.9.8</version>
   <scope>test</scope>
</dependency>

Selenium WebDriver Dependencies

Selenium Java
<dependency>
   <groupId>org.seleniumhq.selenium</groupId>
   <artifactId>selenium-java</artifactId>
   <version>3.12.0</version>
</dependency>

Appium Dependencies

Appium Java Client
<dependency>
    <groupId>io.appium</groupId>
    <artifactId>java-client</artifactId>
    <version>6.1.0</version>
</dependency>

Extra Needed Dependencies for Drivers

Google Core Libraries for Java
<dependency>
   <groupId>com.google.guava</groupId>
   <artifactId>guava</artifactId>
   <version>25.0-jre</version>
</dependency>
Gson
<dependency>
   <groupId>com.google.code.gson</groupId>
   <artifactId>gson</artifactId>
   <version>2.8.4</version>
</dependency>

Log4J Logging

Log4J-Core
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.11.0</version>
</dependency>
Log4J-API
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.11.0</version>
</dependency>

Maven Plugins

Please again note that the latest versions may change since the date I wrote this guide.  I once again recommend searching for each plugin listed below on https://mvnrepository.com and simply copying the plugins from there and then pasting them into the <plugins> tag section in your project’s POM.xml file.

Do again make sure however, that you include all the specific information in my examples.

  1. In the same POM.xml file, add <plugins/> tags within added <build/> tags, and then add the following plugins within the <plugins/> tags. Again add all this outside of the <dependencies/> tags but within the <project/> tags

Maven-Resources-Plugin

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-resources-plugin</artifactId>
   <version>2.4</version>
</plugin>

Maven-Surefire-Plugin

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-surefire-plugin</artifactId>
   <version>2.14.1</version>
   <configuration>
       <suiteXmlFiles>
           <suiteXmlFile>testng.xml</suiteXmlFile>
       </suiteXmlFiles>
   </configuration>
</plugin>

Maven-Cucumber-Reporting

<plugin>
   <groupId>net.masterthought</groupId>
   <artifactId>maven-cucumber-reporting</artifactId>
   <version>3.8.0</version>
   <executions>
       <execution>
           <id>execution</id>
           <phase>verify</phase>
           <goals>
               <goal>generate</goal>
           </goals>
           <configuration>
               <projectName>iOSAppAutomationFramework</projectName>  <!-- Replace with project name -->
               <outputDirectory>target/cucumber-reports/advanced-reports</outputDirectory>
               <cucumberOutput>target/cucumber-reports/CucumberTestReport.json</cucumberOutput>
               <buildNumber>1</buildNumber>
               <parallelTesting>false</parallelTesting>
           </configuration>
       </execution>
   </executions>
</plugin>

IntelliJ Plugins

Cucumber for Java Plugin

  1. Ensure ‘Cucumber for Java’ plugin is installed and enabled in IntelliJ by going to Settings –> Plugins and ensuring ‘Cucumber for Java’ is checked
    1. MacOS: IntelliJ IDEA –> Preferences –> Plugins
    2. Windows: File –> Settings –> Plugins

Create a .gitignore File

  1. In IntelliJ, right-click on your project root and select New –> File
    1. Name the file .gitignore and click OK
  2. Paste the following into your .gitignore file (this is a default template used for Maven projects)
    log/
    target/*
    .idea/
    *.iml
    *.iws
    .DS_Store
    pom.xml.tag
    pom.xml.releaseBackup
    pom.xml.versionsBackup
    pom.xml.next
    release.properties
    dependency-reduced-pom.xml
    buildNumber.properties
    .mvn/timing.properties
    .envrc
    node_modules/
    
    # Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
    !/.mvn/wrapper/maven-wrapper.jar

    Now would be a good time to save the Maven project if you haven’t yet done so! 🙂

Packages & Directory Structure

  1. Right-click on the {project-root}/src/test/java directory, select New –> Package, and add the following packages (as well as sub packages within other packages.  You may need to put a temporary dummy file in ‘utils’ package first before adding the sub-packages)
    • pages
    • steps
    • utils
      • drivers
      • extensions
      • helpers
      • hooks
      • appium
  2. Right-click on the {project-root}/src/test directory, select New –> Directory
    • Name the directory ‘resources’ and click OK
  3. Right-click on the {project-root}/src/test/resources directory and select ‘Mark Directory As’ –> ‘Test Resources Root’ (if not marked already)
  4. Right-click the /src/test/resources directory again and select New –> Directory
    • Name the directory ‘features’ and click OK

Initial Files in each Package / Directory

Features folder

  1. Right-click the ‘features’ directory, select ‘New’ –> ‘File’ and add the following feature files (Feature files is what Cucumber uses to write BDD scenarios using Gherkin language. Please see https://cucumber.io/ for more information)
    • BaseScenarios.feature

Pages package

  1. Right-click the ‘pages’ package, select ‘New’ –> ‘Java Class’ and add the following classes to the package (the ‘pages’ package will contain all our class files for our web pages / page objects, following Page Object Model (POM) principles. Please see https://goo.gl/4iq2Et for more information)
    • Page
    • BasePage

Steps package

The steps package will contain all our step definition classes, which will contain our step definitions / glue which links our steps in our test scenarios to the java methods which perform different actions.

When it comes to grouping our step definitions, it is good practice to have a Step Definition class file for each major domain object we are trying to test.

For example, in this blog series, we will mainly be testing that a user can navigate and view information on pieces by a specific, chosen artist in the Artistry app.

So in this case, we could have the following Step Definition files…

  1. Right-click the ‘steps’ package, select ‘New’ –> ‘Java Class’ and add the following classes to the package (the ‘steps’ package will contain all our step definitions, which acts as the glue that connects our BDD/Gherkin language scenarios in our Feature files, to our test methods in our Java classes.  Please see https://cucumber.io/docs/gherkin/step-organization/ for more information)
    • BaseSteps
      • this class contains all the step definitions for your base scenarios and steps that apply across multiple domain objects
        • This can also include steps that involve the initial on-boarding screens of the app (if any)
    • NavigationSteps
      • this class contains all the step definitions for steps that perform navigation actions in the Artistry app
    • PaintingSteps
      • this class contains all the step definitions that involve individual/selected paintings

Utils package

Drivers package

  1. Right-click the ‘drivers’ package, select ‘New’ –> ‘Java Class’ and add the following classes to the package (the ‘drivers’ package will contain class files for all the different AppiumDrivers our test framework will use)
    • IOSAppDriver

Extensions package

  1. Right-click the ‘extensions’ package, select ‘New’ –> ‘Java Class’ and add the following classes to the package (the ‘extensions’ package will contain class files for all our static methods that we can use as extensions to our existing functionality)
    • GeneralExtensions
    • JavascriptExtensions
    • JqueryExtensions
    • JquerySelectorExtensions
    • WebDriverExtensions
    • MobileElementExtensions
    • XCTestExtensions (for iOS / XCTest specific mobile gestures)

Helpers package

  1. Right-click the ‘helpers’ package, select ‘New’ –> ‘Java Class’ and add the following classes to the package (the ‘helpers’ package will contain class files for all our static methods which can act as helpers to our existing functionality)
    • GeneralHelpers
    • JavascriptHelpers

Hooks package

  1. Right-click the ‘hooks’ package, select ‘New’ –> ‘Java Class’ and add the following classes to the package (the ‘hooks’ package will contain classes for all the different hooks we can run before and/or after test runs/suites/scenarios etc.)
    • CucumberHooks
    • StepHooks
    • TestRunHooks

Appium package

  1. Right-click the ‘selenium’ package, select ‘New’ –> ‘Java Class’ and add the following classes to the package (the ‘selenium’ package will contain our core WebDriver setup and DriverController instance, as well as a Settings class where we can list public static variables to be used in our project)
    • Driver
    • DriverController
    • Settings

Installing Appium Server

We can now use NPM (Node Package Manager) to install Appium server globally on our system.

Normally, I like to follow best practices and install all my NPM packages locally to the project that depends on them, however with Appium Server, it is required to install it globally (or add ‘./node_modules/.bin/appium’ to PATH) if you want to be able to start it up programatically in Java using ‘AppiumDriverLocalService’.

This is OK as in a later part of this series when we add our Appium test framework to a CI/CD build server like Jenkins, we can define any NPM packages that we want to install globally in it (and of course Appium Server will be one of those). Obviously any developer working on the project will also need to install Appium Server globally on their machine.

  1. Open up Terminal (or Command Prompt) and change directory (cd) into the local project root for this project…
    cd path/to/Project

    (change ‘path/to/Project’ to the path of your local project)

  2. Once at the project root in Terminal (or Command Prompt), let’s initialise NPM so we can create our package.json file which will list all the NPM packages we contain in / that are local to our project (we won’t actually have any because we are installing appium globally, but it’s good practice any how)…
    npm init -y
  3. Now let’s install Appium Server globally to our system…
    npm install -g appium
    • You can check Appium Server was successfully installed globally after, by entering into Terminal (or Command Prompt):
      appium -v

Updating .gitignore file

Let’s now exclude the ./node_modules directory from being included in our remote repository. Because we initialised NPM and our project contains a package.json file, any one who clones our repo can simply run

npm install

and NPM would read through the package.json file and automatically install all the listed packages.

  1. Open up the .gitignore file and add
    node_modules/

    to it

Installing Appium Desktop

Unlike Android, iOS does not have a tool like UIAutomatorViewer that we can use to inspect elements in an iOS app.

Instead, we can use Appium Desktop to create a new session with specified Desired Capabilities and inspect elements of an iOS app within the Appium Desktop session.

  1. Go to https://github.com/appium/appium-desktop/releases and download the DMG of the latest version of Appium Desktop
  2. Open the DMG and drag and drop the Appium Desktop application into your /Applications folder on your MacAppium Desktop is now installed, we will use it later in this blog series to inspect elements of the iOS app 🙂

Log4J2

Apache Log4j is a Java-based logging utility. It was originally written by Ceki Gülcü and is part of the Apache Logging Services project of the Apache Software Foundation. Log4j is one of several Java logging frameworks.

Configuring Log4J2

In our framework, we will create a Log4J2 config file and use it to configure our logging to the console.  You can also use Appender class in Log4J2 with a config file to configure logging to files, however we will stick to the Console in this blog series.

You can have one of many different types of Log4J2 config files, with certain filetypes being read before falling back to others.

In our framework, we will go with a simple XML config file.

For more info, please visit https://logging.apache.org/log4j/2.x/manual/configuration.html

Log4J2 XML File

  1. Right-click on the ‘/src/test/resources‘ directory and select ‘New’ -> ‘File’, name the file ‘log4j2-test.xml’ and press OK
  2. Paste the following into the xml file, it should look like below…
    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration>
        <Appenders>
            <Console name="Console">
                <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %c{1} -%msg%n"/>
            </Console>
        </Appenders>
        <Loggers>
            <Root level="info">
                <AppenderRef ref="Console"/>
            </Root>
        </Loggers>
    </Configuration>

In the next section, we will begin writing code for our drivers and the rest of the core framework 😀

Liked it? Take a second to support Thomas on Patreon!

Previous Article

Next Article

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.