< Java
Blog >
Using Concordion to automate integration testing
Harry Klerks

In my life as a Java software engineer, I have always been puzzled by the common practice of unit testing. Not so much the existence per se, but more the sometimes religious way many of my fellow software engineers go about this activity and perhaps more importantly, why they think it is a good idea to do so. Somehow, I have always felt intuitively that something was not quite right with this practice, but was never able to prove the communis opinio wrong. 

But then I stumbled upon this essay by James Coplien. In this essay, Coplien clearly demonstrates why the modern day practice of unit testing software is seriously flawed. A bit later I found this sequel to the first essay. You can find the slide-deck of Coplien's talk at Rakuten Technology Conference in 2014 on Slideshare.

And then it all made sense to me.

Perhaps by now, you wonder what all this has to do with the subject of this blog? Well, there are many things to take away from the great sources of insight mentioned above. One of the most important ones is that unit testing is one of the least effective methods to discover defects in software and that testing at the system and integration levels is much more rewarding. Which brings us to this blog's topic. Enter Concordion. Concordion is a tool that enables you to automate the use of so called executable specifications. You may know similar tools like Cucumber or JBehave. For us at Bongaro, Concordion was the first in this software tool category, and we like it a lot.

Ok, let’s get to work.

Configuring a Maven build - Adding the dependency for Concordion

Add the following dependency to the build configuration:

<dependency></dependency>

<groupid>org.concordion</groupid>

<artifactid>concordion</artifactid>

<version>1.5.1</version>

<scope>test</scope>

Configuring the maven-failsafe-plugin

Integration tests in Maven are best executed by the maven-failsafe-plugin.

<project></project>

...

    <plugin></plugin>

        <artifactid>maven-failsafe-plugin</artifactid>

        <version>2.19.1</version>

        <configuration></configuration>

            <systempropertyvariables></systempropertyvariables>

 <concordion.output.dir>target/concordion</concordion.output.dir>

            

        

        <executions></executions>

            <execution></execution>

                <goals></goals>

                    <goal>integration-test</goal>

                    <goal>verify</goal>

                

            

        

    

...

The property configured in line 8 controls where Concordion will write its output. This might be convenient to know if you intend to publish the output as an artefact in your build process.

The Concordion side of things

Concordion works with the concept of so called 'executable specifications'. A specification in Concordion is written in HTML and instrumented with Concordion specific tags. These tags connect the specification with a so called 'Fixture', a JUnit-enabled Java class that is run with a special Concordion runner. And finally, the fixture accesses the system under test. This way, the specification is cleanly disconnected from its implementation.

A simple specification example

<!DOCTYPE html>

<html xmlns:concordion="http://www.concordion.org/2007/concordion"></html>

   <p>Given some pre-condition</p>

   <p>When something occurs</p>

   <p>Then <span concordion:assertequals="getSomeText()">some post-condition applies</span></p>

Note that Concordion allows you to write specifications in the given-when-then template style, but does not enforce this. The specification might as well be a Use Case, for example. Also note the suffix IT in the name of the HTML file and name of the fixture class (below). The maven-failsafe-plugin by default runs every test that ends in IT or ITCase. Finally note that the HTML file and the Java fixture class have the same name (this includes the package/folder name). Concordion needs this to match the specification with the fixture.

A simple Java fixture

RunWith(ConcordionRunner.class)

public class IntegrationTestIT {

   public String getSomeText() {

       return "some post-condition applies";

   }

}

mvn verify

This test would obviously alway pass and would therefore be a clear example of waste (wink). See the Concordion web site for more examples, documentation and tutorials.

Executing the integration tests

The maven-failsafe-plugin is by default attached to the verify phase of the Maven build so...

mvn verify

...would execute all integration tests.