I've recently moved on from a .Net software developer role have started working with Java. A recent project requirement for the creation of a testing framework from scratch led to my discovery of the groovy based Geb wrapper (pronounced jeb) and the Spock framework.
Geb is described as "bringing together the power of WebDriver, the elegance of jQuery content selection, the robustness of Page Object modelling and the expressiveness of the Groovy language".
Geb is a wrapper for the Selenium WebDriver API and works incredibly well with the testing and specification framework Spock. Being from a .Net background I had never used things like Java (although it feels very familiar), Maven, POM files, etc. so in this series of blog posts I will guide you through the set up process and build a specification based automated testing framework from scratch using Geb, Spock, Maven and the IntelliJ IDE.
UI Automation with Geb & Spock (Part 1): Create New Project
1. Add the Maven Integration plugin you haven't got it: File -> Settings... -> Plugins
2. Create a new Maven project using the gmaven-archetype-basic archetype
Note: You will need to download the Java SDK if you haven't already, and set this in the Project SDK section at the top of the New Project window
Your project structure should look like this (with the sections highlighted in red being different depending on the name you gave your project) :
2. Clean up the project - delete the following:
- Example.groovy
- Helper.groovy
- ExampleTest.groovy
- HelperTest.groovy
3. Set the src/test/groovy directory as the Test Sources Root:
- Right click the groovy folder
- Select Mark Directory As > Test Sources Root
4. Delete the contents of the pom.xml file after the version tag and before the closing project tag so it looks similar to this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>example-project</groupId>
<artifactId>geb-automation</artifactId>
<name>ndds-automation project</name>
<version>1.0-SNAPSHOT</version>
<!-- PASTE FURTHER XML HERE -->
</project>
Now we want to add in some property variables that will allow us to easily change the version of the geb, selenium and groovy packages. These should be added just below the version tag:
<properties>
<gebVersion>2.2</gebVersion>
<seleniumVersion>3.14.0</seleniumVersion>
<groovyVersion>2.5.3</groovyVersion>
<spockVersion>1.2-groovy-2.5</spockVersion>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
Below the closing properties tag we now want to add in the package dependencies we will need. These are:
groovy-all - contains the groovy libraries required to write groovy code
spock-core - the testing and specification framework
geb-spock - geb library with spock integration
selenium... - the selenium browser drivers and support code
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>${groovyVersion}</version>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>${spockVersion}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.gebish</groupId>
<artifactId>geb-spock</artifactId>
<version>${gebVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-firefox-driver</artifactId>
<version>${seleniumVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>${seleniumVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${seleniumVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-support</artifactId>
<version>${seleniumVersion}</version>
<scope>test</scope>
</dependency>
</dependencies>
Note: Notice how the variables we added earlier are referenced using ${ } e.g. ${seleniumVersion}
Next underneath the dependencies closing tag add the build section below which includes all the plugins required to get started:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<includes>
<include>**/*Test.groovy</include>
<include>**/*Spec.groovy</include>
</includes>
<systemPropertyVariables>
<geb.build.reportsDir>target/test-reports/geb</geb.build.reportsDir>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>build-assembly</id>
<phase>compile</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.6.2</version>
<type>maven-plugin</type>
</plugin>
</plugins>
</build>
Finally below the closing build tag add in the repositories (these are the locations used to download the dependencies):
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
<releases>
<enabled>false</enabled>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
You may now have to import all the dependencies we've just added. You can do this in IntelliJ by pressing Ctrl-Shift-A to bring up the Action window, then typing reimport and selecting Reimport All Maven Projects:
That's it for Part 1 - We're now ready to start modelling some pages and creating some tests!
Download the project for part 1 on GitHub if you prefer: https://github.com/rushby/geb-example-project-part1
Software Development & Testing Blog