Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Extending Iridium With Custom Step Definitions

DZone's Guide to

Extending Iridium With Custom Step Definitions

Iridium makes it easy for developers to build in their own custom step definitions, removing the need to write custom code gluing Cucumber and WebDriver together.

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

Cucumber, which is the library that Iridium is built on, has been designed to allow developers to easily have their own code run in response to a step inside a feature script. Once you have all the boilerplate code written to initialize Cucumber, having it run your own code is as simple as creating a POJO with methods that have the annotations @Then, @When, @But, @Given or @And.

But getting all the boilerplate code written is not quite as easy as it sounds, especially when you are integrating Cucumber with WebDriver in order to drive a web browser. In fact, the bulk of code in Iridium has been written to provide an environment where WebDriver and Cucumber can work together. Writing the code that is executed by a feature scripts is actually one of the easiest aspects of the Iridium code base.

Fortunately, developers can take advantage of the work done in Iridium to create their own step definitions which can then be run by Iridium alongside (or completely replacing) the standard set of steps provided by Iridium.

To demonstrate this, we’ll create a simple extension with a simple step definition that logs a message.

To start with, you’ll also need to create a GPG key, which is used to sign the extension JAR files. The Building chapter of the Getting Started Guide has details on how to create a GPG key.

You’ll also need to sign up to the Sonatype Open Source Maven publishing programme. This is a service provided by Sonatype that allows open source developers to publish artifacts to the central Maven repositories, which is incredibly useful given that Maven is the defacto method for sharing Java artifacts.

Once you have created your GPG key and have a Sonatype account, those details go in the file ~/.gradle/gradle.properties.

signing.keyId=12345678
signing.password=password
signing.secretKeyRingFile=/home/username/.gnupg/secring.gpg
ossrhUsername=sonatype_user
ossrhPassword=sonatype_password

With that done, we can create the Java project. We’ll start with the Gradle build script in the build.gradle file.

buildscript {
    repositories {
        mavenLocal()
        mavenCentral()
        maven {
            url 'https://oss.sonatype.org/content/repositories/snapshots'
        }
        maven {
            url 'https://oss.sonatype.org/content/repositories/releases'
        }
    }
    dependencies {
        classpath 'com.matthewcasperson:build:0.+'
    }
}

apply plugin: 'com.matthewcasperson.build.iridiumextension'

This build file takes advantage of a custom Gradle plugin that handles everything you need to create an Iridium extension. You can find the source code to this plugin here. By using the Gradle plugin, things like maven repos, maven publishing, dependencies and code style checking is implemented for you.

One of the requirements enforced by the plugin is the need to specify a number of properties of the extension. This is done in the gradle.properties file.

# Update these properties to reflect the details of the extension
Group=com.matthewcasperson
ArchivesBaseName=example-extension
Version=0.0.1-SNAPSHOT
MavenName=Iridium Example Exntension
MavenDescription=A demo of an extension that can be used with the Iridium testing application
MavenURL=https://github.com/mcasperson/iridium-example-extension
MavenSCMConnection=scm:git:https://github.com/mcasperson/iridium-example-extension
MavenSCMURL=https://github.com/mcasperson/iridium-example-extension
MavenLicenseName=MIT
MavenLicenseURL=https://opensource.org/licenses/MIT
MavenDeveloperID=mcasperson
MavenDeveloperName=Matthew Casperson
MavenDeveloperEMail=matthewcasperson@gmail.com

To make it easy for others to build your project, create a Gradle wrapper with the command

gradle wrapper --gradle-version 2.12

This saves some scripts in your project that are intended to be checked into source control. Running these scripts will download the appropriate version of Gradle onto the user’s local PC if it doesn’t already exist, and means that other developers don’t need Gradle installed to build your project.

Now we create the class that will hold our step definition. The class needs to in a package under au.com.agic.apptestingext.steps. This is because Iridium has been configured to scan all classes under au.com.agic.apptestingext.steps for step definitions.

package au.com.agic.apptestingext.steps;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cucumber.api.java.en.When;

/**
 * Cucumber steps exist in a POJO
 */
public class Example {

private static final Logger LOGGER = LoggerFactory.getLogger(Example.class);

/**
 * Annotate a public method with @And, @But, @When, @Given or @Then, and cucumber
 * will recognise the method as a Gherkin step
 *
 * @param message The message to be written to the log
 */
@When("I write \"(.*?)\" as a log message")
public void writeExampleLogMessage(final String message) {
LOGGER.info(message);
}
}

The @When annotation takes a regular expression that is matched to any steps in a feature script. The groups in the regular expression are passed into the method as parameters. In this case we have one regaular expression group, which takes the message to be logged, and this is passed to the message parameter.

Inside the method, we use these parameters however we like. Our example takes the message and logs it to the console.

Once you are happy with the code, publish it to Sonatype with the command:

./gradlew build uploadArchive

This uploads the artifact to the Sonatype staging repo. Note that while it is in the staging repo, the artifact is not available to other developers unless they specifically add the staging repo to their build scripts. Our Gradle plugin does add the staging repo though, so anyone using this plugin will have access to your artifact. Publishing to the central Maven repo (which makes the artifact globally available) is covered by the Sonatype docs.

With your Iridium extension in the staging Maven repo, we now need to incorporate it into a build of Iridium. To do this, clone the Iridium repo, and the following line to the build.gradle file:

dependencies {
  // Existing dependencies go here...

  compile group: 'com.matthewcasperson', name: 'example-extension', version: '0.0.1-SNAPSHOT' 
}

Doing so adds your new extension JAR as a dependency of the Iridium project. You can now build a self contained uberjar with the command:

./gradlew clean shadowJar --refresh-dependencies

The resulting JAR file in the build/libs directory now contains your JAR file with the step definitions. You can reference these step definitions from a feature script like any of the step definitions included with Iridium.

Feature: Local Test
  Scenario: Local Scenario
    And I write "Hello World" as a log message

The source code to this example extension can be found here.

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

Topics:
maven ,extension ,code ,feature ,repo ,guide ,key ,script ,base ,gpg

Published at DZone with permission of Matthew Casperson, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}