Writing Unit Tests With Spock Framework: Creating a Gradle Project

The Spock Framework is a testing and specification framework for Java and Groovy applications. Its website make a somewhat bold claim:

What makes it stand out from the crowd is its beautiful and highly expressive specification language.

Before we can verify if this claim is true, we have to create an example project that we can use for this purpose.

The previous part of this tutorial described how we can do this by using Maven. Now we will learn how we can do this by using Gradle.

This blog post describes how we can create a Gradle project that fulfils the following requirements:

  • It must support "normal" unit tests that use JUnit and unit tests that use the Spock Framework.
  • It must compile and run the "normal" unit tests that are found from the src/test/java directory.
  • It must compile and run the Groovy unit tests that are found from the src/test/groovy directory.
  • It must create an HTML test report that describes the test results of our unit tests that use the Spock Framework.

Let's start by getting the required dependencies.

Additional reading:

If you are not familiar with Gradle, you should read the following blog posts before you continue reading this blog post:

Getting the Required Dependencies

We can get the required dependencies by adding the following dependencies into the testCompile configuration:

  • JUnit (version 4.12) is a framework that allows us to write both unit and integration tests.
  • Spock Core (version 1.0-groovy-2.4). Spock is a testing and specification framework for Java and Groovy applications.
  • Groovy All (version 2.4.4). Groovy is a dynamic programming language for the JVM.

After we have added these dependencies into our build.gradle file, its source code looks as follows:

dependencies {
    testCompile(
            'junit:junit:4.12',
            'org.codehaus.groovy:groovy-all:2.4.4',
            'org.spockframework:spock-core:1.0-groovy-2.4'
    )
}
We don’t have to add the JUnit and Groovy dependencies into our build.gradle file. However, if we leave them out, we have to use the JUnit and Groovy versions specified by Spock Core.

Additional Reading:

After we have added the required dependencies into our build.gradle file, we have to configure Gradle to compile and run our unit tests.

Compiling and Running Our Unit Tests

Because our unit tests use both Java and Groovy programming languages, we need to compile our test sources by using the Groovy plugin that extends the Java plugin and adds support for Groovy projects.

We can configure our Gradle build by following these steps:

  1. Apply the Groovy plugin.
  2. Ensure that the Java compiler accepts code that uses Java 1.8.
  3. Ensure that the compiled classes are compatible with Java 1.8.

After we have configured Gradle to compile and run our unit tests, the source of code of our build.gradle file looks as follows:

apply plugin: 'groovy'

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    testCompile(
            'junit:junit:4.12',
            'org.codehaus.groovy:groovy-all:2.4.4',
            'org.spockframework:spock-core:1.0-groovy-2.4'
    )
}
The Groovy plugin extends the project layout of the Java plugin by adding the Groovy related directories into our Gradle build. The relevant directories are described in the following:

  • The src/main/java directory contains the source code of our example application.
  • The src/test/java directory contains the "normal" unit tests that use JUnit.
  • The src/test/groovy directory contains the unit tests that use the Spock Framework.

Additional Reading:

We can now compile and run our unit tests by running the following command at the command prompt:

gradle clean test

When we do this, we see that:

  • The compileTestJava task is invoked. This task compiles the unit tests that are found from the src/test/java directory.
  • The compileTestGroovy task is invoked. This task compiles the unit tests that are found from the src/test/groovy directory.
  • The test task invokes all unit tests.

The output of this command looks as follows:

> gradle clean test
:clean
:compileJava
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes
:compileTestJava
:compileTestGroovy
:processTestResources UP-TO-DATE
:testClasses
:test

BUILD SUCCESSFUL

The last thing that we have to do is to configure Gradle to create an HTML test report that describes the test results of unit tests that use the Spock Framework.

Creating an HTML Test Report

When we run our unit tests, Gradle creates an HTML test report to the build/reports/tests directory. The HTML report that describes the test results of our test class, which uses the Spock Framework, looks as follows:

Gradle Standard Test Report

If we are happy with this report, we don't have to do anything. We can just enjoy the ride.

However, if we want to create a test report that describes the preconditions and the expected results of our test cases, we have to use the Spock Reports Extension. By default, it creates an HTML report for each invoked specification and and a summary that lists all invoked specifications.

We can use this Spock extension by following these steps:

  1. Ensure that Gradle resolves the dependencies of our build by using the Bintray’s JCenter Maven repository.
  2. Add the Spock Reports Extension jar file into the classpath. We can do this by adding the spock-reports dependency (version 1.2.7) into the testRuntime configuration.

After we have enabled the Spock Reports Extension, the source code of our build.gradle file looks as follows:

apply plugin: 'groovy'

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    jcenter()
}

dependencies {
    testCompile(
            'junit:junit:4.12',
            'org.codehaus.groovy:groovy-all:2.4.4',
            'org.spockframework:spock-core:1.0-groovy-2.4',
    )
    testRuntime(
            'com.athaydes:spock-reports:1.2.7'
    )
}
Additional Reading:

We can now run our unit tests by using the command:

gradle clean test

When we run our unit tests, the Spock Reports Extension creates an HTML test report to the build/spock-reports directory. The HTML report that describes the test results of our test class, which uses the Spock Framework, looks as follows:

Test Report Created by Spock Reports
If you need to provide custom configuration to the Spock Reports Extension, you need to create a properties file to the following location (relative to the classpath):

META-INF/services/com.athaydes.spockframework.report.IReportCreator.properties

Additional Reading:

Let's summarize what we learned from this blog post.

Summary

This blog post has taught us three things:

  • We know how we can get the required dependencies with Gradle.
  • We can compile and run our unit tests by using the Groovy plugin.
  • If we want to create a test report that describes the preconditions and the expected results of our test cases, we have to use the Spock Reports Extension.

The next part of this tutorial gives an introduction to Spock specifications.

P.S. You can get the example of this blog post from Github.

16 comments… add one
  • Imteyaz Ahmad Jan 24, 2016 @ 3:29

    Nice post....I wasn't aware of the customization of test report..thanks for sharing that.. :)

    • Petri Jan 24, 2016 @ 9:52

      You are welcome!

  • Skorfulose Apr 7, 2016 @ 16:18

    Thanks Petri, you saved my day! I spent hours to resolve a groovy-all dependency conflict between compile localGroovy()
    and
    compileTest 'org.spockframework:spock-core:1.0-groovy-2.4'
    and now it works smoothly.

    Kudos for the great tutorial!

    • Petri Apr 7, 2016 @ 17:39

      You are welcome! It was nice to hear that this tutorial was useful to you.

  • Mor May 22, 2016 @ 12:41

    Hi!

    Great post, all worked well except one thing.

    I want to write groovy BDD tests using spock.
    For some reason I have the src/test/java package mentioned, but not the src/test/groovy package.
    I tried creating it but it seems not to work for some reason.

    Care to shed any light on this?

    Sorry if this is a silly question :)

    Thanks!

    • Petri May 23, 2016 @ 18:30

      Hi,

      Did you remember to apply the groovy plugin? The reason why I ask this is that the groovy plugin adds the src/test/groovy directory into your build.

  • Sapan Sep 21, 2016 @ 14:17

    Hi When I run my test cases they do not seem to find the packages from under src/main/java. Is this expected behavior?

  • Gopi Jan 20, 2017 @ 9:16

    Hi

    I have the src/test/java/ package mentioned, but not the src/test/groovy package.
    I have 2 groovy files under src/test/java/
    1. basetest.groovy :
    2. Project.gorrvy :

    : Having all basic methods which test cases will make use, Launch browser, Launch URL, etc..

    : Having all my test cases...(currently 4 test cases and all passing)

    Currently I am running individual test case placing the cursor on def of first test case and choose Run in right click option. This is running and giving console output. But no reports generated.

    I have created gradle task and linked Project.gorrvy file to run all 4 test cases. This has generated reports file index.html under build/reports directory ONLY once. if I run again it is NOT creating new index.html file..

    Need help..
    build.gradle contents :

    
    group 'poa-AFAT'
    version '1.0'
    
    apply plugin: 'java'
    //apply plugin: 'checkstyle'
    apply plugin: 'maven'
    apply plugin: 'groovy'
    
    sourceCompatibility = 1.5
    targetCompatibility = 1.5
    
    test{
        maxParallelForks = 6
    }
    
    repositories {
        maven { url "http://repo.maven.apache.org/maven2" }
    }
    
    configurations {
        cucumberRuntime {
            extendsFrom testRuntime
        }
    }
    
    dependencies {
        compile "com.jayway.restassured:rest-assured:2.4.1"
        compile "com.jayway.jsonpath:json-path:2.0.0"
        compile "com.jayway.restassured:json-schema-validator:2.5.0"
        compile group: 'org.spockframework', name: 'spock-core', version:'1.1-groovy-2.4-rc-2'
        compile group: 'org.gebish', name: 'geb-spock', version:'0.13.1'
        compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version:'2.48.2'
        compile "org.seleniumhq.selenium:selenium-firefox-driver:2.52.0"
        compile "org.dbunit:dbunit:2.5.3"
    //    compile "mysql:mysql-connector-java:5.1.36"
        compile group: 'mysql', name: 'mysql-connector-java', version: '6.0.2'
        compile "org.codehaus.groovy.modules.http-builder:http-builder:0.7.1"
        compile 'info.cukes:cucumber-groovy:1.2.2'
        //testCompile 'info.cukes:cucumber-java:1.0.2'
        compile 'org.gebish:geb-core:0.13.1'
        compile group: 'info.cukes', name: 'cucumber-core', version: '1.2.5'
        compile group: 'info.cukes', name: 'cucumber-junit', version: '1.2.5'
    }
    
    task verizon2yearsunset(type: Test){
        include '**/VZN2YearSunsetTestScenarios.class'
        maxParallelForks = 1
    
    
    • Gopi Jan 20, 2017 @ 9:19

      Also i want index.html file to be created whenever i run individual test case from project.groovy file
      Need help

      • Petri Jan 20, 2017 @ 10:20

        So, to summarize, your problem is that you can run your test cases from your IDE, but:

        • If you run all tests, the test report is created only once AND
        • If you run one test, the test report is not created at all

        Did I understand your problem? If so, what IDE are you using?

        • Gopi Jan 23, 2017 @ 8:03

          Hi Petri..

          Thanks for your quick response...

          The IDE i am using :
          IntelliJ community Edition - 2016.3
          Build : #IC-163.7743.44

          Could you also help to create HTML/XML file used as suite which links all my test cases ?
          So that when i ever i need to run selective test cases.. i can comment those which i do not required to run and enable those which i need to execute and generate report..

          This will help to have single file for controlled execution... In selenium/Java framework I have XML filea.. anything similar here? if yes. need format...

          Thanks
          Gopi

          • Gopi Jan 26, 2017 @ 11:49

            Hi

            Any help for me on suite file (xml) creation in Cucumber-Geb-Spock-Groovy framework, which links all my test cases(currently 4 test cases).. and i will have two options to run
            1. Gradle task which run all my 4 test cases and gives html output.
            2. Suite(XML) file which links 4 test cases.. where i can run selective test cases and run.

            Need help on 2 and format of xml file..

            Thanks
            Gopi

          • Petri Jan 26, 2017 @ 23:19

            Hi, I am sorry that it took me some time to answer to your comment. In any case, here we go:

            As far as I know, there is no way to create the test report if you run individual tests from your IDE. Also, the behavior that you described (test report created only when you run all tests for the first time) sounds like a bug, but it can also be a problem of your build script. Unfortunately I cannot find any problems from your build script.

            2. Suite(XML) file which links 4 test cases.. where i can run selective test cases and run. Need help on 2 and format of xml file..

            Unfortunately I have no experience from the combination you seem to be using (Cucumber-Geb-Spock-Groovy), and I don't know how you can create the suite.xml file. Is it a Cucumber / Geb specific thing?

Leave a Reply