Test With Spring Course
Save Time by Writing Less Test Code
  • Home
  • Pre-Sales FAQ
  • Support
  • Log In

/ June 26, 2017 / petrikainulainen

Running Unit Tests With Maven – Spock Edition

Lesson Progress:
← Back to Topic

After we have finished this lesson, we:

  • Understand how we can compile unit tests which use the Groovy programming language.
  • Know how we can run unit tests which use Spock Framework.
  • Can run only unit tests which belong to a specific JUnit 4 category.

This lesson assumes that:

  • You are familiar with JUnit 4 categories
  • You can run unit tests with Maven

Watch the Lesson

 

The text version of this lesson is given in the following:

The Requirements of Our Maven Build

The requirements of our Maven build are:

  • Our application is written by using the Java programming language.
  • It must support unit tests which use Spock framework.
  • The source directory of our unit tests must be: src/test/groovy.
  • The resources directory of our unit tests must be: src/test/resources.
  • It must run only unit tests which belong to the UnitTest category.

Let’s move on and find out how we can get the required dependencies with Maven.

Getting the Required Dependencies

We can get the required dependencies by declaring the following dependencies in our pom.xml file:

  • JUnit (version 4.12) is a framework that allows us to write automated tests with Java programming language.
  • Groovy All (version 2.4.11). Groovy is a dynamic programming language for the JVM.
  • Spock Core (version 1.1-groovy-2.4). Spock is a testing and specification framework for Java and Groovy applications.

After we have added these dependencies to our pom.xml file, its dependencies section looks as follows:

<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.12</version>
	<scope>test</scope>
</dependency>
<dependency>
	<groupId>org.codehaus.groovy</groupId>
	<artifactId>groovy-all</artifactId>
	<version>2.4.11</version>
	<scope>test</scope>
</dependency>
<dependency>
	<groupId>org.spockframework</groupId>
	<artifactId>spock-core</artifactId>
	<version>1.1-groovy-2.4</version>
	<scope>test</scope>
</dependency>

We don’t have to add the JUnit and Groovy dependencies to our pom.xml file. However, if we leave them out, we have to use the JUnit and Groovy versions specified by Spock Core dependency.

Next, we will take a quick look at our Spock specifications.

Introduction to Our Spock Specifications

Our example project has two simple specification classes that are described in the following:

First, the MessageServiceSpec class specifies one unit test that belongs to the UnitTest category. Its source code looks as follows:

import org.junit.experimental.categories.Category
import spock.lang.Specification

@Category(UnitTest.class)
class MessageServiceSpec extends Specification {

    def messageService = new MessageService()

    def 'Get message'() {
        expect: 'Should return the correct message'
        messageService.getMessage() == 'Hello World!'
    }
}

The UnitTest interface is a simple marker interface that identifies tests which should be run when we run our unit tests. Its source code looks as follows:

interface UnitTest {
}

Second, the UnCategorizedSpec class specifies one unit test that doesn’t belong to any category. In other words, this unit test shouldn’t be run when we run our unit tests. The source code of the UnCategorizedSpec class looks as follows:

import spock.lang.Specification

class UnCategorizedSpec extends Specification {

    def messageService = new MessageService()

    def 'Should not be run'() {
        expect: 'Should return the correct message'
        messageService.getMessage() == 'Hello World!'
    }
}

By the way, we will take a closer look at Spock specifications in the next lessons of this topic. In other words, you shouldn’t worry if you don’t understand what these specification classes are doing.

Let’s move on and find out how we can compile our unit tests with Maven.

Compiling Our Unit Tests

Because our unit tests use the Groovy programming language, we have to compile our test sources by using the GMavenPlus plugin. Before we can use this plugin, we have to declare this plugin in the plugins section of our POM file.

After we have done this, the relevant part of our pom.xml file looks as follows:

 <plugins>
 	<plugin>
 		<groupId>org.codehaus.gmavenplus</groupId>
 		<artifactId>gmavenplus-plugin</artifactId>
 		<version>1.5</version>
 	</plugin>
 	<plugin>
 		<groupId>org.apache.maven.plugins</groupId>
 		<artifactId>maven-compiler-plugin</artifactId>
 		<version>3.6.1</version>
 		<configuration>
 			<source>1.8</source>
 			<target>1.8</target>
 			<encoding>UTF-8</encoding>
 		</configuration>
 	</plugin>
 </plugins>

We will use the Maven Compiler plugin for compiling the source code of our application that is written by using the Java programming language.

After we have added the GMavenPlus plugin to our Maven build, we have to configure it by following these steps:

  1. Ensure that the GMavenPlus plugin adds our Groovy test sources, which are found from the src/test/groovy directory, to the project’s test sources.
  2. Ensure that the GMavenPlus plugin compiles our unit tests.

After we have configured the GMavenPlus plugin, the relevant part of our pom.xml file looks as follows:

 <plugins>
 	<plugin>
 		<groupId>org.codehaus.gmavenplus</groupId>
 		<artifactId>gmavenplus-plugin</artifactId>
 		<version>1.5</version>
 		<executions>
 			<execution>
 				<goals>
 					<goal>addTestSources</goal>
 					<goal>testCompile</goal>
 				</goals>
 			</execution>
 		</executions>
 	</plugin>
 	<plugin>
 		<groupId>org.apache.maven.plugins</groupId>
 		<artifactId>maven-compiler-plugin</artifactId>
 		<version>3.6.1</version>
 		<configuration>
 			<source>1.8</source>
 			<target>1.8</target>
 			<encoding>UTF-8</encoding>
 		</configuration>
 	</plugin>
 </plugins>

Additional Reading:

  • GMavenPlus Plugin – gplus:addTestSources
  • GMavenPlus Plugin – gplus:testCompile
  • GMavenPlus Plugin Wiki

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

mvn clean test-compile

When do this, we should see the following output:

$ mvn clean test-compile
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Running Unit Tests With Maven 0.1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ running-unit-tests-with-maven ---
[INFO] Deleting /Users/loke/Projects/Java/Courses/test-with-spring/master-package/introduction-to-spock/running-unit-tests-with-maven/target
[INFO]
[INFO] --- gmavenplus-plugin:1.5:addTestSources (default) @ running-unit-tests-with-maven ---
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ running-unit-tests-with-maven ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.6.1:compile (default-compile) @ running-unit-tests-with-maven ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/loke/Projects/Java/Courses/test-with-spring/master-package/introduction-to-spock/running-unit-tests-with-maven/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ running-unit-tests-with-maven ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.6.1:testCompile (default-testCompile) @ running-unit-tests-with-maven ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- gmavenplus-plugin:1.5:testCompile (default) @ running-unit-tests-with-maven ---
[INFO] Using Groovy 2.4.11 to perform testCompile.
[INFO] Compiled 3 files.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.375 s
[INFO] Finished at: 2017-06-26T12:53:46+03:00
[INFO] Final Memory: 23M/307M
[INFO] ------------------------------------------------------------------------

This output reveals that:

  • The GMavenPlus plugin adds a new test source directory to our Maven build.
  • The GMavenPlus plugin invokes its testCompile goal that compiles our unit tests.

Next, we will learn to run unit tests which use the Spock Framework.

Running Our Unit Tests

We can run our unit tests by using the Maven Surefire Plugin. Before we can use this plugin, we have to declare it in the plugins section of our POM file. After we have done this, the relevant part of pom.xml file looks as follows:

 <plugins>
 	<plugin>
 		<groupId>org.codehaus.gmavenplus</groupId>
 		<artifactId>gmavenplus-plugin</artifactId>
 		<version>1.5</version>
 		<executions>
 			<execution>
 				<goals>
 					<goal>addTestSources</goal>
 					<goal>testCompile</goal>
 				</goals>
 			</execution>
 		</executions>
 	</plugin>
 	<plugin>
 		<groupId>org.apache.maven.plugins</groupId>
 		<artifactId>maven-compiler-plugin</artifactId>
 		<version>3.6.1</version>
 		<configuration>
 			<source>1.8</source>
 			<target>1.8</target>
 			<encoding>UTF-8</encoding>
 		</configuration>
 	</plugin>
 	<plugin>
		<groupId>org.apache.maven.plugins</groupId>
		<artifactId>maven-surefire-plugin</artifactId>
		<version>2.20</version>
	</plugin>
 </plugins>

After we have added this plugin to our Maven build, we have to configure the Maven Surefire Plugin by following these steps:

First, Ensure that it runs only the unit tests which belong to the UnitTest category. After we have made this change to the configuration of the Maven Surefire Plugin, the relevant part of our POM file looks as follows:

 <plugins>
 	<plugin>
 		<groupId>org.codehaus.gmavenplus</groupId>
 		<artifactId>gmavenplus-plugin</artifactId>
 		<version>1.5</version>
 		<executions>
 			<execution>
 				<goals>
 					<goal>addTestSources</goal>
 					<goal>testCompile</goal>
 				</goals>
 			</execution>
 		</executions>
 	</plugin>
 	<plugin>
 		<groupId>org.apache.maven.plugins</groupId>
 		<artifactId>maven-compiler-plugin</artifactId>
 		<version>3.6.1</version>
 		<configuration>
 			<source>1.8</source>
 			<target>1.8</target>
 			<encoding>UTF-8</encoding>
 		</configuration>
 	</plugin>
 	<plugin>
		<groupId>org.apache.maven.plugins</groupId>
		<artifactId>maven-surefire-plugin</artifactId>
		<version>2.20</version>
		<configuration>
			<groups>com.testwithspring.master.UnitTest</groups>
		</configuration>
	</plugin>
 </plugins>

Second, the default configuration of the Maven Surefire Plugin includes all test classes whose name ends with the Strings: ‘Test’, ‘Tests’, or ‘TestCase’.

When I write automated tests with Spock Framework, I name my specification classes by appending the String: ‘Spec’ to the name of the specification class. That’s why we have to configure the Maven Surefire Plugin to include only test classes whose name ends with the String: ‘Spec’.

After we have configured the included test cases, the relevant part of our POM file looks as follows:

 <plugins>
 	<plugin>
 		<groupId>org.codehaus.gmavenplus</groupId>
 		<artifactId>gmavenplus-plugin</artifactId>
 		<version>1.5</version>
 		<executions>
 			<execution>
 				<goals>
 					<goal>addTestSources</goal>
 					<goal>testCompile</goal>
 				</goals>
 			</execution>
 		</executions>
 	</plugin>
 	<plugin>
 		<groupId>org.apache.maven.plugins</groupId>
 		<artifactId>maven-compiler-plugin</artifactId>
 		<version>3.6.1</version>
 		<configuration>
 			<source>1.8</source>
 			<target>1.8</target>
 			<encoding>UTF-8</encoding>
 		</configuration>
 	</plugin>
 	<plugin>
		<groupId>org.apache.maven.plugins</groupId>
		<artifactId>maven-surefire-plugin</artifactId>
		<version>2.20</version>
		<configuration>
			<groups>com.testwithspring.master.UnitTest</groups>
			<includes>
				<include>**/*Spec.java</include>
			</includes>
		</configuration>
	</plugin>
 </plugins>

Additional Reading:

  • Maven Surefire Plugin – Inclusions and Exclusions of Tests

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

mvn clean test

When we run this command, we see that the Maven Surefire Plugin runs only the unit test that is found from the MessageServiceSpec class and ignores the test that is found from the UnCategorizedSpec class:

[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.testwithspring.master.MessageServiceSpec
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.091 s 
- in com.testwithspring.master.MessageServiceSpec
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

Let’s summarize what we learned from this lesson.

Summary

This lesson has taught us three things:

  • We can compile our unit tests by using the GMavenPlus plugin.
  • We can run our unit tests with the Maven Surefire Plugin.
  • If we don’t want to use the default naming convention of the Maven Surefire Plugin, we have to change the configuration that selects the included test classes.

Get the source code from Github

Next Lesson →

Can I help you?

This is a free sample lesson of my Test With Spring course. If this lesson helped you to solve your problem, you should find out how my testing course can help you.

Support and Privacy

  • Pre-Sales FAQ
  • Support
  • Cookie Policy
  • No Bullshit Privacy Policy
  • No Bullshit Terms and Conditions

Test With Spring Course

  • Starter Package
  • Intermediate Package
  • Master Package

Free Sample Lessons

  • Introduction to JUnit 4
  • Introduction to Unit Testing
  • Introduction to Integration Testing
  • Introduction to End-to-End Testing
  • Introduction to Spock Framework
  • Introduction to Integration Testing – Spock Edition
  • Writing End-to-End Tests With Spock Framework

Copyright Koodikupla Oy 2016 — Built on Thesis by Themedy