Setup Citrus for testing Mule ESB

15 Apr

Recently, I ran into an open-source test framework called Citrus. Citrus supports you in testing message interfaces in enterprise applications. Manual testing effort as well as coding mocks and simulators are not necessary. Instead Citrus enables integration testing in an automated way with out-of-the-box simulation of various message transports. We’ll use it to test our Mule based ESB.

Mule, of course, offers great possibility to unit test your application. And we also have a test setup which ‘talks’ to other applications. What we didn’t have was a testing environment which we could use to test the ESB as a blackbox without being dependent on other (external) applications. And this is exactly where Citrus comes in. Citrus makes it possible to test the complete lifecycle of a message flow without being dependent of other systems, actually with Citrus you proxy these dependencies.
In this post I will provide details and tips on how to setup and use Citrus. Although the documentation that is available is easy to read, it is not complete. It took me quite some effort to get it all running but like I said before the benefits of this framework are huge.

In the reference guide of Citrus there is a chapter about how to use Citrus with Maven. I use that guide as base and add some info that was missing in my case but is essential to get things working. I use the 1.2-SNAPSHOT edition of Citrus.

I took the following steps to get it running:

  1. Add repositories to your settings.xml
  2. To have access to the Citrus jars you need to tell Maven where to get them. You can do this by adding the following repositories to your settings.xml (or even better to Artifactory or similar repository manager):

    <repositories>
        [...]
        <repository>
          <id>consol-labs-release</id>
          <url>http://labs.consol.de/maven/repository/</url>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
          <releases>
            <enabled>true</enabled>
          </releases>
        </repository>
        <repository>
          <id>consol-labs-snapshots</id>
          <url>http://labs.consol.de/maven/snapshots-repository/</url>
          <snapshots>
            <enabled>true</enabled>
            <!-- Policy: always, daily, interval:xxx (xxx=#minutes, 60*24*7=10080), never -->
            <updatePolicy>10080</updatePolicy>
          </snapshots>
          <releases>
            <enabled>false</enabled>
          </releases>
        </repository>
        [...]
      </repositories>
    
  3. Add necessary dependencies to your project’s pom
  4. Add the following dependencies to the pom of your project (at least the citrus-core, the others are depending on the tests you want to perform).

    <dependency>
        <groupId>com.consol.citrus</groupId>
        <artifactId>citrus-core</artifactId>
        <version>1.2-SNAPSHOT</version>
        <scope>test</scope>
      </dependency>
     <dependency>
       <groupId>com.consol.citrus</groupId>
       <artifactId>citrus-http</artifactId>
       <version>1.2-SNAPSHOT</version>
    <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>com.consol.citrus</groupId>
       <artifactId>citrus-adapter</artifactId>
       <version>1.2-SNAPSHOT</version>
       <scope>test</scope>
     </dependency>
    
  5. Add necessary plugins to your project’s pom
  6. To generate and execute the Citrus test cases you need to add the Citrus plugins (and extra source path) to your project. This is done by adding the following to your project’s pom:

     <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>2.0.2</version>
                    <configuration>
                        <source>1.5</source>
                        <target>1.5</target>
                        <encoding>${project.build.sourceEncoding}</encoding>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>2.2</version>
                    <configuration>
                        <encoding>${project.build.sourceEncoding}</encoding>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>com.consol.citrus.mvn</groupId>
                    <artifactId>citrus-maven-plugin</artifactId>
                    <version>1.1</version>
                    <configuration>
                        <author>Pascal Alma/author>
                        <targetPackage>net.pascalalma.test</targetPackage>
                    </configuration>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <skip>true</skip>
                    </configuration>
                    <executions>
                        <execution>
                            <id>citrus-tests</id>
                            <phase>integration-test</phase>
                            <goals>
                                <goal>test</goal>
                            </goals>
                            <configuration>
                                <skip>false</skip>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
    
            <testSourceDirectory>src/citrus/java</testSourceDirectory>
            <testResources>
                <testResource>
                    <directory>src/citrus/java</directory>
                    <includes>
                        <include>**</include>
                    </includes>
                    <excludes>
                        <exclude>*.java</exclude>
                    </excludes>
                </testResource>
                <testResource>
                    <directory>src/citrus/tests</directory>
                    <includes>
                        <include>**/*</include>
                    </includes>
                    <excludes>
                    </excludes>
                </testResource>
                <testResource>
                    <directory>src/citrus/resources</directory>
                    <includes>
                        <include>**/*</include>
                    </includes>
                    <excludes>
                    </excludes>
                </testResource>
            </testResources>
        </build>
    
  7. Create a Citrus Test Case
  8. Next step is to use the Maven plugin to create a new Test Case. Run the command

    mvn citrus:create-test

    and answer the questions.
    Note 1: the name of the testcase is going to be the Java class name so only use the valid characters for a Java class name
    Note 2: Make sure the name of the testcase ends with ‘Test’ otherwise the test isn’t found when trying to run it (at least in case you generate a JUnit4 type of test).

  9. Add a ‘citrus-context.xml’ to the classpath
  10. This isn’t mentioned in the guide but is a mandatory step: you need to have a ‘citrus-context.xml’ file on the classpath for Citrus to run your tests. Here is a snippet from the config file that can be found in the examples that are delivered with Citrus:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:citrus="http://www.citrusframework.org/schema/config"
           xmlns:citrus-ws="http://www.citrusframework.org/schema/ws/config"
           xmlns:citrus-http="http://www.citrusframework.org/schema/http/config"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.citrusframework.org/schema/config http://www.citrusframework.org/schema/config/citrus-config.xsd">
    
    ...
        <!-- Message Validators -->
        <bean id="xmlMessageValidator" class="com.consol.citrus.validation.xml.DomXmlMessageValidator"/>
        
        <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
            <property name="brokerURL" value="${jms.server.url}" />
        </bean>
        
        <bean class="com.consol.citrus.variable.GlobalVariables">
            <property name="variables">
                <map>
                    <entry key="project.name" value="Citrus Greeting sample"/>
                </map>
            </property>
        </bean>
        
    ...
        
        <!-- TestSuite definition -->
        <bean name="citrus-samples-greeting" class="com.consol.citrus.TestSuite"/>
    </beans>
    

When all this is done you can run your test with the command:

mvn clean integration-test -Dtest=YourTestNameTest

In the next posts I will go into more detail about certain Test Scenarios and how to test these with Citrus.

Follow

Get every new post delivered to your Inbox.

Join 111 other followers

%d bloggers like this: