Running Spock tests as part of a build process

Một phần của tài liệu Manning java testing with spock (Trang 243 - 247)

So far, I’ve silently assumed that whenever I show you a Spock test, you run it manually and visually check the results in the IDE or the command-line shell. Although this is true for your day-to-day development schedule, a well-designed enterprise application employs a build server that automatically checks out code at various time intervals, compiles it, runs unit tests, and creates reports in a completely automated manner.

If you’re not familiar with build servers, explaining them is outside of the scope of this book. As a suggestion, start by downloading Jenkins (https://jenkins-ci.org/) and then read both the theory24 and practice25 behind a sound build process.

For the rest of the chapter, I assume that you already have a build server in place for running JUnit tests and mention only what you need to do for Spock (spoiler:

almost nothing, as Spock is JUnit-compatible).

7.5.1 Splitting unit, integration, and functional tests

If you look back at table 7.1, which lists the characteristics of unit, integration, and functional tests, it should be clear that they have different requirements.

For starters, functional (and sometimes integration) tests require a running rep- lica of the system that’s tested. Therefore, you know that functional tests must be treated differently than the rest of the tests.

Another big difference is the speed of tests. Unit tests (which depend only on Java code) are fast and give quick feedback. Integration and functional tests are much slower (especially when external systems and real databases are involved).

The speed of unit tests means that they can be executed automatically after every developer commit for quick feedback. Functional tests, on the other hand, may run less frequently (for example, once a day) and also require the setup of a test environ- ment exclusive to them (which typically replicates the production environment).

These best practices aren’t specific to Spock. They also apply to JUnit or TestNG. I mention them here so that before complaining that “Geb tests are really slow,”

you should understand that Geb tests must run in a different manner than simpler Spock tests.

24See “Continuous Delivery” by Jez Humble and David Farley on the Martin Fowler website (http://martin fowler.com/books/continuousDelivery.html).

25See Jenkins: The Definitive Guide by John Ferguson Smart (O’Reilly, 2011), www.wakaleo.com/books/jenkins- the-definitive-guide.

219 Running Spock tests as part of a build process

In the sample code of the book, I use Maven and have chosen to launch the Tomcat application server before the functional tests run. Figure 7.14 shows the Maven life- cycle26 for the examples of this chapter.

With this approach, you have a split between slow and fast tests. Running mvn test runs only the fast unit tests, and running mvn verify also runs the slow functional tests (after launching a Tomcat instance). This lifecycle is accomplished by using the Maven Failsafe plugin (https://maven.apache.org/surefire/maven-failsafe-plugin/) and the Tomcat plugin (http://tomcat.apache.org/maven-plugin.html), as shown in the following listing.

[...rest of pom.xml....]

<build>

<plugins>

[...rest of build plugins....]

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-failsafe-plugin</artifactId>

<version>2.18</version>

<executions>

<execution>

<goals>

<goal>integration-test</goal>

<goal>verify</goal>

</goals>

</execution>

</executions>

26You can learn more about the Maven lifecycle at the Apache Maven Project website (https://

maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html).

Listing 7.13 Running Spock functional tests on a Tomcat instance

compile test-compile

test package

pre-integration-test integration-test post-integration-test

verify

Java code is compiled Spock tests are compiled Unit tests run (fast)

Tomcat starts—application deployed REST/web functional tests run (slow) Tomcat stops—application shuts down Functional tests are examined Maven

phases

Figure 7.14 Tomcat is launched before functional tests and shuts down afterward.

Instructs Failsafe plugin to run Spock tests in integration-test phase

<configuration>

<useFile>false</useFile>

<includes>

<include>**/*Spec.java</include>

</includes>

</configuration>

</plugin>

<plugin>

<groupId>org.apache.tomcat.maven</groupId>

<artifactId>tomcat7-maven-plugin</artifactId>

<version>2.2</version>

<executions>

<execution>

<id>tomcat-run</id>

<goals>

<goal>run-war-only</goal>

</goals>

<phase>pre-integration-test</phase>

<configuration>

<fork>true</fork>

</configuration>

</execution>

<execution>

<id>tomcat-shutdown</id>

<goals>

<goal>shutdown</goal>

</goals>

<phase>post-integration-test</phase>

</execution>

</executions>

</plugin>

</plugins>

</build>

This technique works for small- to medium-size applications. For large-scale enterprise applications that need specialized test environments, you need to adapt your build sys- tem according to your business requirements in cooperation with the team responsi- ble for provisioning.27

Running both Spock and JUnit tests in the same Java project

If it isn't clear by now, the Maven plugins (Surefire and Failsafe) will run both JUnit and Spock tests in a similar manner. No special configuration is needed if you have both kinds of tests. You can mix and match, and many configurations are possible.

For example, you could have JUnit tests run as pure unit tests and use Spock only for web tests (with Geb). Consult the Maven documentation for the respective plugins and appendix A of this book for more information on the subject.

27I hear they’re called “devops” these days.

Naming convention for Spock tests that will run as integration-test phase

Starts Tomcat before Spock tests run

Stops Tomcat after Spock tests run

221 Running Spock tests as part of a build process

7.5.2 Getting code coverage from Spock tests

For some strange reason, when I introduce Spock to Java developers, even after I explain that it uses the JUnit runner, the first question they ask is how to obtain code coverage statistics with Spock.

The answer to this question is, “In the same way that you get coverage reports28 for JUnit.” There’s nothing special about it. Figure 7.15 shows a sample JaCoCo report (www.eclemma.org/jacoco/) that was generated by Spock tests.

There’s nothing Spock-specific about this report. I obtained it by adding JaCoCo in my pom.xml file and executing the jacoco:report goal with Maven as I would for Junit, as shown in the following listing.

[...rest of build plugins here...]

<plugin>

<groupId>org.jacoco</groupId>

<artifactId>jacoco-maven-plugin</artifactId>

<version>0.7.4.201502262128</version>

<executions>

<execution>

<id>prepare-agent</id>

<goals>

<goal>prepare-agent</goal>

</goals>

</execution>

</executions>

</plugin>

[...rest of pom.xml here...]

The same principle applies to any other tools that you have around JUnit. If they work fine with JUnit, they’ll probably work with Spock as well. For a full-blown, code-quality reporting tool, you should also look at SonarQube (www.sonarqube.org) if you aren’t already using it.

28Common coverage tools are Cobertura (http://cobertura.github.io/cobertura/) and Clover (www.atlassian .com/software/clover/).

Listing 7.14 Using JaCoCo with Spock Figure 7.15 Code coverage by Spock tests

Using Spock with SonarQube requires exactly zero extra configuration (apart from the standard instructions29). An example of SonarQube results from a Spock test is shown in listing 7.16.

I hope that the level of compatibility between JUnit-enabled tools and Spock tests is clear to you now.

Một phần của tài liệu Manning java testing with spock (Trang 243 - 247)

Tải bản đầy đủ (PDF)

(306 trang)