June 10, 2016

A Quick Gradle Overview: Setting Dependencies and Running Tests

Since January of this year, our little automation department at work has been trying to re-align itself, getting more in line with what the other software developers are doing -- a fantastic (but scary) learning opportunity for me.

Back in March 2015, I was trying to relearn for loops and foreach loops in Java. By September, though, I was helping build out the automation framework for our Selenium WebDriver browser tests -- See Automate Amazon for a sample. And by January 2016, I thought I was really becoming an experienced developer, independently writing a framework to handle Rest APIs. All the extra work I was putting into learning to code was really paying off.

Now, I feel like I don't know anything!

We are switching from being an "Automation Department" to being a "Software Test Engineering" department, from just running browser tests to testing APIs and performance testing. I find myself experimenting with many languages and tools that are brand new to me... and one of them is the build management tool, Gradle.

Maven and Gradle: Setting Dependencies


As far as I knew, a build management tool was something you set up once at the start of the project to handle the dependencies, installing the tools you needed to create the framework, and then forgot about them.



I was first introduced to Apache Maven during Alan Richardson's online course, Selenium 2 WebDriver with Java. Take a look at the first practice testing framework I designed back in July 2015. The pom.xml file has nothing but dependencies for the tools I am using.

Pom.xml
 <?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/xsd/maven-4.0.0.xsd">  
   <modelVersion>4.0.0</modelVersion>  
   <groupId>WebDriver_TheInternet_Advanced</groupId>  
   <artifactId>WebDriver_TheInternet_Advanced</artifactId>  
   <version>1.0-SNAPSHOT</version>  
   <dependencies>  
     <dependency>  
       <groupId>org.testng</groupId>  
       <artifactId>testng</artifactId>  
       <version>6.1.1</version>  
       <scope>test</scope>  
     </dependency>  
     <dependency>  
       <groupId>org.seleniumhq.selenium</groupId>  
       <artifactId>selenium-java</artifactId>  
       <version>2.46.0</version>  
     </dependency>  
   </dependencies>  
 </project>  

If you take a look at the poorly named project I created, InitialWebDriverSetup_GradleJunitChromeDriver, you can see that I am only using Gradle in this same way. It is just a quick way for the project to download other libraries I am using in the project. Take a look at the build.gradle file:

Build.gradle
 group 'com.tmaher'   
  version '1.0-SNAPSHOT'   
  apply plugin: 'java'   
  repositories {   
   mavenCentral()   
  }   
  dependencies {   
   testCompile group: 'junit', name: 'junit', version: '4.11'   
   compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '2.53.0'   
   compile group: 'org.hamcrest', name: 'java-hamcrest', version: '2.0.0.0'   
  }   


Gradle Tasks


There is a lot more to Gradle than handling dependencies. When creating a Gradle project with IntelliJ, as I did in the blog post WebDriver development environment setup with IntelliJ, Gradle, Hamcrest, and ChromeDriver, you can see that there are many Gradle tasks that have been set up for us:

These tasks were automatically created as soon as the Java plugin for Gradle was added to the build.java file. See Chapter 45: The Java Plugin of the free Gradle Users Guide.

Gradle: Build Tasks: 
  • assemble: Assembles all the archives in the project 
  • build: Performs a full build of the project. 
  • buildDependents: Performs a full build of the project and all projects which depend on it. 
  • clean: Deletes the project build directory. 
Gradle: Verification tasks:
  • check: Performs all verification tasks in the project. 
  • test: Runs the unit tests using JUnit or TestNG.
We have in the project the following tests saved in a TestClass under src/test/java (not src.main/java).

public class TestClass {

    private WebDriver driver;

    @Test
    public void testFirefoxDriver() {

        driver = new FirefoxDriver();
        . . . 
    }

    @Test
    public void testChromeDriver() {
        . . . 
    }

    @Test
    public void testIE11Driver() {
        . . . 
    }

    @After
    public void closeBrowsers() throws Exception {
        driver.quit();
    }
}

Running Tests through IntelliJ


When I double-click on test:
  • Build.Gradle is reviewed: Since there isn't anything explicitly saying test { useTestNG() } it will use JUnit (3.8.x or 4.x). See Gradle Test configurations.
  • It searched for all the unit tests in src/test/java. Since it didn't see anything in the build.gradle file excluding any tests, it ran all the tests we marked @Test. 
  • After the project is compiled, one by one, the browser tests are run. 
  • A report is printed out.
 Testing started at 1:05 AM ...  
 1:05:14 AM: Executing external task 'test'...  
 :compileJava UP-TO-DATE  
 :processResources UP-TO-DATE  
 :classes UP-TO-DATE  
 :compileTestJava UP-TO-DATE  
 :processTestResources UP-TO-DATE  
 :testClasses UP-TO-DATE  
 :test  
 BUILD SUCCESSFUL  
 Total time: 29.391 secs  
 1:05:43 AM: External task execution finished 'test'.  

Running Tests through the Command Line


These tests can also be run in the Command Line Interface (CLI), within the Mac Terminal or the Windows Command Prompt. Go into the project folder and run the following from the command line:

Mac Terminal:
 ./gradlew test  

Windows Command Prompt:
 gradlew.bat test  

This does the same exact thing as above, except it uses the Gradle Wrapper to execute the task called test. On the Windows environment, the wrapper is a batch file (*.bat) that runs Gradle.

What is the Gradle Wrapper?


From Chapter 5: The Gradle Wrapper of the Gradle Users Guide, Version 2.13

"Most tools require installation on your computer before you can use them. If the installation is easy, you may think that’s fine. But it can be an unnecessary burden on the users of the build. Equally importantly, will the user install the right version of the tool for the build? What if they’re building an old version of the software?

"The Gradle Wrapper (henceforth referred to as the 'Wrapper') solves both these problems and is the preferred way of starting a Gradle build [...]

"If a Gradle project has set up the Wrapper (and we recommend all projects do so), you can execute the build using one of the following commands from the root of the project:

  • ./gradlew <task> (on Unix-like platforms such as Linux and Mac OS X)
  • gradlew <task> (on Windows using the gradlew.bat batch file)

"Each Wrapper is tied to a specific version of Gradle, so when you first run one of the commands above for a given Gradle version, it will download the corresponding Gradle distribution and use it to execute the build".

What Was Gradle, Again? 

It was created mainly by Hans Doctker ( LinkedIn, Twitter: @hans_d ) the CEO of the Gradle (formerly Gradleware) company.

From Wikipedia's article on Gradle:

"Gradle is an open source build automation system that builds upon the concepts of Apache Ant and Apache Maven and introduces a Groovy-based domain-specific language (DSL) instead of the XML form used by Apache Maven of declaring the project configuration. Gradle uses a directed acyclic graph ('DAG') to determine the order in which tasks can be run.

"Gradle was designed for multi-project builds which can grow to be quite large, and supports incremental builds by intelligently determining which parts of the build tree are up-to-date, so that any task dependent upon those parts will not need to be re-executed.

"The initial plugins are primarily focused around Java, Groovy and Scala development and deployment, but more languages and project workflows are on the roadmap".

Gradle Links:

Breaking Open: Gradle: Interview with the author of Gradle

Video Description: "Published on Oct 4, 2012: In our second episode of Breaking Open, Hans Dockter peels back the curtains on Gradle, the open source, general purpose, and platform agnostic build system he created to address the changing landscape and new demands of modern enterprise automation".

Gradle Summit 2015 Keynote: Hans Dockter
"It Used To Be Fun To Make Software" 



... With the next blog post, we'll explore the free class offered on Udacity: Gradle for Android and Java.

Until then, Happy Testing!

-T.J. Maher
Sr. QA Engineer,
Fitbit-Boston

// QA Engineer since Aug. 1996
// Automation developer for [ 1 ] year and still counting!
// Check out Adventures in Automation on Facebook!

No comments: