Posted on by & filed under Content - Highlights and Reviews, Programming & Development.

A guest post by Andrew Oberstar, a community contributor to Gradle and plugin author. You can find him at http://www.andrewoberstar.com or http://github.com/ajoberstar.

Introduction

Gradle is a build automation tool, making use of Groovy to provide a powerful Domain Specific Language (DSL) to describe and instruct the behavior of your build. Gradle is most frequently associated with builds for JVM languages (with built in support for Java, Groovy, and Scala), although a lot of work has been going into their C++ support.

If you’re not familiar with Gradle, I suggest you hop over to their home page and check it out. Their model-oriented approach makes it trivial to configure a typical build, while still providing flexibility to provide logic for unique cases.

I’m going to assume basic knowledge of Gradle in this post and show a slightly more advanced feature: initialization scripts (a.k.a. init scripts).

What Is an Init Script?

When you execute a Gradle build, it goes through a lifecycle that consists of three phases:

  1. Initialization – executes the settings scripts that determine the projects in the build, as well as the init scripts we’ll be discussing
  2. Configuration – evaluates the build scripts to configure the tasks and domain objects in the build
  3. Execution – determines the tasks to be run and executes them

In this post we’ll be focusing on the initialization phase. While this phase happens before the projects are available to configure, init scripts can be used to inject:

  • listeners that fire various events in the build lifecycle (e.g. task execution, project evaluation, test execution)
  • delayed project configuration that will be executed as soon as the project is made available in the configuration phase

While init scripts can be included in a build via a command line flag (-I or --init-script), for more practical uses they will be automatically loaded from the three following locations:

  • init.gradle in USER_HOME/.gradle
  • Any *.gradle file in USER_HOME/.gradle/init.d
  • Any *.gradle file in the Gradle installation’s init.d directory

For enterprise-wide configuration, dropping init scripts into a repackaged Gradle distribution is a great way to do things like setting up the repositories and plugins that are used in the organization. This can kill a lot of boilerplate config that would otherwise be in every build script.

The topic for this post, though, is a developer-specific configuration. While, typically, your configuration should all be in source control, there are some options that might be specific to your machine, or that might help you with your day-to-day productivity, but aren’t tied to a specific build. Since init scripts in the first two locations above will apply to all Gradle builds on your machine, they serve to centralize configuration not appropriate, or too unique, for general plugins.

An Example

Now, I will walk through an example with two pieces of functionality:

  • Anytime a Test task fails, the HTML report will be open in the default browser.
  • Configure test logging that goes to the console during a Gradle build.

Both of these may be helpful to you, but shouldn’t be forced on every developer working on your project.

To start off, create a file (I’ll call it my-test-config.gradle) in your USER_HOME/.gradle/init.d directory. Since this is probably your first init script, the init.d directory will need to be created manually.

Opening the Test Report

The basic logic is that we want to know if a Test task has failed. If so, we get the path to the HTML report and execute a command to open it in our browser.

Step 1: Listen for Failed Test Task

Init scripts delegate to a Gradle instance. Its method called addListener takes many different flavors of listener, including a TaskExecutionListener that would be called before and after every task, giving us access to the Task object and its resulting state.

Step 2: Open the Test Report

Now that we have access to the failed Test task, we can find the location of the report and open it in our browser. I’m not aware of a cross-platform way to do this, so you need to substitute the right option for your OS.

Configuring Test Console Output

Gradle provides a TestLoggingContainer on each Test task that allows you to decide how much information should end up in the console as your JUnit/TestNG tests are executed. While this is a great feature, it will mostly be developer preference, so it would be rare to check this type of config into source control.

Within an init script you have access to configure all of the projects run by Gradle. This will look deceivingly like the configuration runs while the init script executes, but it will actually be delayed until the projects are created as part of their normal lifecycle.

The TestLoggingContainer doesn’t limit you to one configuration approach all the time, since you can configure it differently based upon the different log levels Gradle can be run under.

In this example, we want to:

  • Have more exception information and information on passed and skipped tests during normal Gradle execution (i.e. lifecycle level logging)
  • Show all levels of granularity for test logging, allowing you to see which process was running each test, during info logging

Here is our code:

Complete Example

Here is my-test-config.gradle:

Conclusion

Gradle’s init scripts can be a powerful feature, allowing a developer control of their own build environment, while still preserving the project-specific build script versioned in source control. This post has shown an example of how to use init scripts to provide flexibility in how tests results are presented to the developer. See below for some Gradle resources from Safari Books Online.

Safari Books Online has the content you need

Gradle Beyond the Basics is an advanced guide that provides the recipes, techniques, and syntax to help you master this build automation tool. With clear, concise explanations and lots of ready-to-use code examples, you’ll explore four discrete areas of Gradle functionality: file operations, custom Gradle plugins, build lifecycle hooks, and dependency management.
Building and Testing with Gradle shows you to us Gradle for building and testing software written in Java and other JVM languages. It covers transitioning to Gradle from Maven, integration with IDEs such as Eclipse, and more.
Gradle Effective Implementation Guide is a great introduction and reference for using Gradle. The Gradle build language is explained with hands on code and practical applications. You learn how to apply Gradle in your Java, Scala or Groovy projects, integrate with your favorite IDE and how to integrate with well-known continuous integration servers.

About the author

andrew Andrew Oberstar, a community contributor to Gradle and plugin author. You can find him at http://www.andrewoberstar.com or http://github.com/ajoberstar.

Tags: gradle, init scripts, software testing,

Comments are closed.