When developing software that exchanges data with other components or services you may be confronted with the proper simulation of those foreign services during integration testing. This is because you need to connect with a foreign service
that is simply not available on your local machine or in a test environment.

For unit testing purpose you can use mocks that help out to simulate proper responses. There will be times where your software is deployed to a test environment
in order to perform some acceptance tests with your stack holders before going to a final release. Usually this is also done with the customer exploring the software through manual testing. In these situations traditional service mocking is not
a good option and you need a real simulator instance that receives requests and responds with proper test data.

This is exactly what the Citrus simulator project provides for you. Standalone simulation and complex request/response processing with solid validation capabilities. The Citrus simulator provides a very easy and reliable definition of inbound and outbound messages for different scenarios.
Good news is that this is not only for Http REST interfaces but also for SOAP WebService, JMS, RMI, mail messaging and many more. So you can use the simulator whenever you need to integrate with another service that is simply not available on your local machine or in your test environment.

The citrus-simulator project is a side project of the test framework Citrus. The simulator uses Citrus to define server APIs and the logic to respond with predefined messages according to
defined scenarios.

In general the simulator is nothing but a normal Spring Boot web application that you can start on your local machine. The simulator waits for incoming requests and each request executes a predefined scenario that will create a response message for the client.
Which scenario to execute is identified based on a mapping key that is extracted from the incoming request.

Let’s have a simple example project to demonstrate the simulator concepts.

User login sample

Let’s say you are in charge of developing an application that connects with a user login service for proper authentication. Your service comes as a Microservice web application and is ready for deployment in the acceptance test environment.

Unfortunately the user authentication service is not ready yet and is not deployed in that test environment. Without the user
login service your application is not able to work properly as each user interaction needs to be authenticated with foreign service calls first.
This means the foreign user login service needs to be simulated so users can explore your application in that test environment.

Spring Boot simulator

We start to simulate that user login service by creating a new Spring Boot project. Of course you can use any build system you like when building the simulator application. Most popular tools would be Gradle or Maven.
Here we show how to setup everything using Gradle.

The build script defines a typical Spring Boot project with its dependencies and plugin configuration. In addition to that we add the citrus-simulator-starter dependency. The citrus-simulator-ui dependency is optional
and provides a detailed Angular2 user interface that you can open with your browser once the simulator is up and running.

Let’s add the Spring Boot main class for the application com.consol.citrus.simulator.Simulator.java:

The main class is a typical Spring Boot application that uses @SpringBootApplication annotation with auto configuration of needed components. As we have added the citrus-simulator-starter dependency to the project we also get auto
configuration of all simulator related beans and components. The application can use a SimulatorRestAdapter extension in order to overwrite some simulator components such as the default fallbackEndpointAdapter. This adapter defines a
default Http 500 internal server error response when something went wrong on the simulator request processing. Also we give the url mapping that defines how clients connect with the user login REST API later on using the base
URL http://localhost:8080/services/rest/v1/**.

Now we can add a first a default scenario that responds to incoming requests.

packagecom.consol.citrus.simulator;importcom.consol.citrus.http.message.HttpMessage;importcom.consol.citrus.simulator.scenario.*;importorg.springframework.http.HttpStatus;@Scenario("DEFAULT_SCENARIO")publicclassDefaultScenarioextendsAbstractSimulatorScenario{@Overridepublicvoidrun(ScenarioDesignerdesigner){designer.send().message(newHttpMessage("No scenario found for this request").status(HttpStatus.NOT_FOUND));}}

The scenario uses the annotation @Scenario("DEFAULT_SCENARIO") and extends AbstractSimulatorScenario. In the run method we can use the Citrus Java DSL designer to create some response generating logic.
This default scenario is activated when no other scenario is matching the incoming request. So we send back a Http 404 NOT FOUND as we obviously did not match a scenario. Now let’s build and start the simulator application.

Build and run

You can build and run the simulator application from command line using the Gradle binaries.

./gradlew build bootRun

You will see the application starting up. Usually you will see some console log output. The web server should start within seconds. Once the application is up and running
you can open your browser and point to http://localhost:8080. You will see the simulator user interface.

You can access the simulated REST services on http://localhost:8080/services/rest/. Up to now we only have the default scenario so we constantly get Http 404 NOT FOUND responses.
Let’s add some scenarios representing the user login service.

User login REST API

The user login service defines following REST API:

{"swagger":"2.0","info":{"description":"This is a user login service","version":"1.0.0","title":"User Login Service"},"host":"user-login-service","basePath":"/v1","schemes":["http"],"paths":{"/user":{"post":{"operationId":"createUser","produces":["application/xml","application/json"],"parameters":[{"in":"body","name":"body","description":"Created user object","required":true,"schema":{"$ref":"#/definitions/User"}}],"responses":{"default":{"description":"successful operation"}}}},"/user/login":{"get":{"operationId":"loginUser","produces":["application/xml","application/json"],"parameters":[{"name":"username","in":"query","description":"The user name for login","required":true,"type":"string"},{"name":"password","in":"query","description":"The password for login in clear text","required":true,"type":"string"}],"responses":{"200":{"description":"successful operation","schema":{"type":"string"},"headers":{"X-Rate-Limit":{"type":"integer","format":"int32","description":"calls per hour allowed by the user"},"X-Expires-After":{"type":"string","format":"date-time","description":"date in UTC when token expires"}}},"400":{"description":"Invalid username/password supplied"}}}},"/user/logout":{"get":{"operationId":"logoutUser","produces":["application/xml","application/json"],"parameters":[],"responses":{"default":{"description":"successful operation"}}}},"/user/{username}":{"get":{"operationId":"getUserByName","produces":["application/xml","application/json"],"parameters":[{"name":"username","in":"path","description":"The name that needs to be fetched. Use user1 for testing. ","required":true,"type":"string"}],"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/User"}},"400":{"description":"Invalid username supplied"},"404":{"description":"User not found"}}}}},"definitions":{"User":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"username":{"type":"string"},"password":{"type":"string"}},"xml":{"name":"User"}}}}

The scenario for Http POST requests on request path /v1/user uses the Spring @RequestMapping annotation. The simulator scenario mapper will automatically
route incoming requests to this scenario based on that information.

The scenario itself receives the incoming request using the Citrus Java DSL. The receive operation validates the Http POST request method and gives an expected control Json message body as external file resource. The
user-control.json defines the expected user object on this operation:

The control user object verifies that the elements id, username and password are present. In addition to that we can use Citrus validation matchers in order to validate the element values. The scenario produces a proper response
only in case the incoming request matches the expected control Json object. The simulator scenario is able to use the full Citrus validation power for comparing message data in Json, XML and plaintext message format. JsonPath and XPath expression evaluation and validation
is also possible here.

Now let’s define a proper response message for the scenario. We send back a Http 200 OK response. This is how the scenario is able to control the response generation with Citrus.

We continue with the remaining scenarios for all other operations defined in the REST API:

The login operation verifies the presence of Http query parameter username and password. As response the scenario defines some header information X-Rate-Limit and X-Expires-After where latter is the
expire date time one hour from now calculated with the Citrus function citrus:currentDate(YYYY-MM-DD'T'hh:mm:ss, +1h). As payload we send back a 40 character random token as plaintext string.

Last not least the logout operation that completes the REST API for the user login service. Now the simulator is able to respond to all operations that are defined in the REST API. Clients are now able to call the
operations via Http REST. The simulator will verify the incoming request data and create proper response messages.

You can test the simulator by pointing your browser to the following URLs:

You should always get proper Http 200 OK response messages. The login request should get a new login token in the response every time. In case we send some invalid request we should get Http 500 responses and for
unsupported request paths we should get a Http 404 response. Try that with following test URLs.

With the above test requests we triggered some activities on the simulator. Let’s review those activities in the web based user interface.

Simulator user interface

The simulator provides a web based Angular2 user interface so users can review the status and all activities on the simulator. We have already seen the dashboard that gives an overview of the simulator status:

In addition to that you can view detailed information available scenarios and their execution activity.

Auto generate scenarios

Up to now we have added simulator scenarios manually. We could have also used auto generated scenarios based on the given Swagger Open API specification of the REST API. Just add a HttpScenarioGenerator bean
to the application:

The HttpScenarioGenerator reads the Open API specification file at runtime and generates scenarios for each operation. The generated scenarios do also
verify the request data according to the rules defined in the specification. The response messages hold dynamic data objects generated from the API schema definitions.

What’s next?!

The Citrus simulator project brings everything to manage standalone simulation of interfaces that you need to connect to during software development. The sample above showed REST API simulation. Same logic is possible with SOAP web services,
JMS and many other messaging transports. The integration with Citrus framework capabilities enables us to create even very complex scenarios with intermediate message handling and consecutive message calls as well as
content based routing.

It has been a while since the last release in the Citrus universe. It took us some time to get the new Citrus release 2.7.2 ready for you.
Of course we were not being lazy in that time. Besides the new Citrus 2.7.2 release we are proud to announce a new player in the Citrus team. The Citrus administration UI is a
web-based user interface that helps you to manage your Citrus projects and test cases.

Often users complained about the complexity of having to learn all about Citrus and the Spring framework in particular as Citrus uses Spring for configuration and dependency injection.
Especially non-developers had problems to master the learning curve for Citrus and Spring when starting to use the framework. Also people asked for a way to have a user interface for managing
components and tests.

We heard you and introduced a new administration user interface for Citrus! There is a detailed Citrus Admin documentation (which is still ongoing).
However I would like to outline the main features of that web UI here in a short post for you.

Download

You can start the web UI on your local machine with an executable web archive available at

Once loaded you can start the admin UI as Spring boot web application from command line like this:

java -jar citrus-admin.war

You will see the application starting up. The web server should start within seconds. Once the application is up and running you can open your browser and point to http://localhost:8080.

The administration web UI is able to open any Citrus project on your local machine. When opened you can display the project information such as the latest test results. In addition to that you are able
to view the Citrus components configured in the in the Spring application context. The web UI is also able to navigate to all test cases in your project. You can open the tests and execute them.

Edit configuration components

One of the major goals in the web UI is to give new users an easier way to get started with the Citrus Spring configuration. All configuration components get loaded from the Spring application context.
You can view and edit those components such as Citrus endpoints via HTML forms:

In case you add new components or save changes to configuration items the administration web UI directly changes the Spring configuration files on your local machine in that particular project. Of course you can
open the Spring configuration files in another editor (e.g. your favorite Java IDE) and review the changes made. In addition to that all configuration changes made from external editors are directly visible to the admin UI.

Test management

You can see all available Citrus test cases in the opened project. The list of tests contains XML and Java DSL tests.

When opening a particular test case the UI will display the test details to you. This includes all test actions, source code, log output and the latest test results.

If you execute the test you will see the log output of that process and you will get a detailed access to all messages exchanged in that test run.

As you can see the test log output is forwarded to your browser. Also the test progress and result (success or failure) is tracked by the administration UI.
In the messages table you are able to review all messages (inbound/outbound) that were part of the test run.

Reporting

The administration UI is able to read the test results in your project. Typically these are JUnit or TestNG reports that are generated from each test run. If present the UI will read and display detailed
test results of the latest test run.

When a test case is failing for some reason exception and failure information will be provided.

The administration UI aims to give you an additional tooling for Citrus integration testing. The administration web UI is not there to eliminate your favorite IDE (IntelliJ, Eclipse or whatever)! The UI is a helping
instrument for getting in touch with Citrus and its concepts and works side by side with your local Java IDE as well as other text editors of your choice.

Also the UI is helpful when executing the Citrus integration tests in different stages (test, acceptance, explorative) of your release process. There is not always a full capable development environment available for
executing integration tests. You can run the Citrus administrative UI as Docker container or Kubernetes pod in order to make the tests portable to your containerized test environment.

Docker image

The administration UI is available as Docker image (consol/citrus-admin:latest). You can pull the image and link it to your local Citrus project:

The command above loads the Docker image and runs a new Citrus web UI container. The container is provided with a volume mount that makes the current directory accessible from within the container.
This current directory is then used as project home so the admin UI will automatically open the Citrus project from that directory. Once the container is running
you can point your local browser to http://localhost:8080 in order to access the web UI.

The CITRUS_ADMIN_PROJECT_HOME environment setting is optional and is used to automatically open a project on container startup. You can leave out this setting in order to select a project folder
in your mounted working directory when starting the web UI.

In case you do not have a Citrus project ready yet, the admin UI can also create a new project for you. It is possible to run a Maven archetype on container startup that creates a complete new project for you.
You can set the Maven archetype coordinates (groupId, artifactId, version) as environment variables when running the container.

The command above will load the project sources from git with URL https://github.com/account/citrus-project.git and open that project afterwards. The git repository of course should hold the Citrus project sources. In case
the Citrus project is located in a sub module in that git repository you can load that sub module by specifying additional environment properties:

This loads and builds the Docker image and starts a new Docker container with running Citrus Admin UI pointing to that very same Maven project.

Stopping the container is as easy as calling:

mvn docker:stop

This is a very comfortable way to build and ship a Citrus admin UI container with your project. You can deploy the tests to any Docker environment or even use
the container in Kubernetes as pod.

What’s next!?

Now it is your turn! Open your Citrus project with that web UI and tell us how you like it! There are many different approaches to using Citrus in a development project.
We tried to cover all aspects and we are sure that the web UI is able to read most of the Citrus project out there. In case there is a time when the web UI is not able to
read your project for some reason please tell us. When there is something wrong or simply not working out for you just open an issue on github.

We are keen to answer your questions and discuss any doubts and we are looking forward to receive your feedback!

In a previous article we went through how to build a chat room web application that used REST and STOMP for communicating between the client and server.
In this article I use the very same application and show how to write automated integration tests using the open source Citrus integration test framework.

If you haven’t read the first article don’t worry. A quick summary of all the important bits will be shown shortly below. But before I get to that lets talk a little bit about automated integration testing and citrus.

One of the biggest challenges when testing any application is being able to simulate all endpoints.

If you take an online web shop for example it typically interacts with numerous backend services (product catalogue, credit check, shipping, billing, etc.) during the course of processing the order.
When writing an automated integration test that tests the placement of an order you’ll have to simulate each of these services. Some services may expose a REST/HTTP interface whereas others may expose a SOAP/JMS interface.
In some scenarios the online web shop will be acting as a client, consuming the backend services. In other cases it will be acting as a server, processing customer requests.

The point is that testing such a scenario can be very complex. A simple application today with one or two interfaces may quickly grow into a complex application with 10s or even 100s of interfaces later on.
When you look at integration test tools then don’t loose sight of this. Sure some tools are great at simulating REST interfaces. Others are great at simulating SOAP.
However for me the most important criteria is to find a test tool that combines these and many other messaging protocols. The tool should be flexible and extensible. And this is where citrus comes into the equation.

Before I dive into integration testing, let’s do a quick recap on the chat room application.

Chat Room

The basic architecture of the chat room application is presented below:

We have a client-server architecture, using web sockets and REST for communicating between the client and the server. The system under test is the blue box above and I’m going to write some tests that simulate the two green arrows.

The application’s entity model is very modest, using just the two entities shown below:

A room contains a list of messages and the name of the user that created the room. A message contains some text and the name of the user that sent the message. That’s basically it.

The following REST operations can be sent from the client to the server:

Join or leave the chat application

Get the list of logged in users

Get the list of rooms

Create or remove a room

Send a message to a room

The server can push the following notifications to connected clients using STOMP over WebSocket:

Testing the application

All the source code I’ll be displaying below is available here: https://github.com/martinmaher/jcache-chat-citrus.
I will show you how to build the project from scratch so you can either clone the above repository or just follow the instructions below, whatever you prefer.

The first thing I need to do is to create an empty maven project for storing and executing our tests. The quickest way of doing this is to execute the maven archtetype goal,
which will create a citrus project with a basic pom file and some sample integration tests. This can be done as follows:

The first thing I need to do is to create a new java class for executing my test. I extend the TestNGCitrusTestDesigner class, which allows me to use Citrus’s Java DSL and add I’ll add a variable for storing a random name, which will be used for the user name when joining the chat room.

The first test action sends the request to the HTTP server. The action basically says:

send(“chatRestClient”) -> send using the chatRestClient

payload(“”) -> an empty payload

http() -> using the HTTP protocol

method(HttpMethod.POST) -> using HTTP’s POST method

path(“/users/${username}”) -> to URI to send the HTTP request to

The syntax ${variable-name} is a variable placeholder used in citrus that gets resolved to the value of the variable at runtime. In the example above I use it for adding the variable username to the URI.

The second action is used for verifying that the server processes the request successfully. It expects a HTTP 200 code to be returned from the server.

You may be wondering how citrus knows which host and port to send the request to. It doesn’t, well not yet. I still have to configure this. This strange string chatRestClient is instructing citrus to find an endpoint using this name in the citrus configuration and use this endpoint for sending and receiving requests.

I have added a new HTTP client endpoint chatRestClient that sends requests to the base url http://localhost:8090/. By default the request method POST will be used with the content-type application/json, but both of these can be overloaded in the test. After sending a request citrus will wait 60 seconds for a reply from the server before timing out. And that’s it.

Now go ahead and run this test. If you have the application opened up in your browser then you will notice a new user joins the chat room when the test executes.

To complete the test I’m going to add the test actions for leaving the chat.

Each frame contains a single COMMAND, zero or more HEADERS, a BODY and the null character (^@) to terminate the frame.

In the chat room application the server sends all notifications to connected clients using this protocol. It does this using the WebSocket API since it enables bidirectional communication between the web server and clients. Each time an event occurs, like a user joining the chat room, this event data is then pushed to the clients from the server.

In STOMP there are different types of COMMANDs that can be sent:

CONNECT: this is sent by a client to the server when it connects

CONNECTED: this is an acknowledgement sent by the server to a client on successful connection

SUBSCRIBE_: this is sent by a client to the server to indicate that it is interested in certain types of messages. The client sends a destination header to indicate which messages it is interested in.

MESSAGE_: this is sent by the server to the client when a destination, that the client has subscribed to, sends a message.

DISCONNECT_: this is sent by the client to the server when its disconnecting.

This is by no means an exhaustive list of commands but covers all commands used in the chat room application.

To put all that into perspective, this is basically what happens when the user Joe Blogs joins the chat room application:

The client opens a WebSocket connection to the server

The client sends a CONNECT frame to the server

CONNECT
accept-version:1.1
heart-beat:0,0

The sever sends a CONNECTED frame acknowledgement back to the client

CONNECTED
version:1.1
heart-beat:0,0

The client sends a SUBSCRIBE frame to the server, indicating that it is interested in messages on the destination /topic/users/joined

The first test action is using the endpoint chatWebSocketClient to send the STOMP CONNECT frame to the server. The payload I just covered above only this time control characters like carriage return and the null character have been added.

The second test action is verifying the client was successfully connected. It compares the received payload from the server against the expected payload, which is specified in the test action. Only when both payloads match exactly will the action be successful.

Before I can execute my test I have to configure the chatWebSocketClient endpoint. Again this is done in the citrus-context.xml file by adding the following lines:

There’s nothing special here. I just added a websocket client endpoint that connects to the server on the url ws://localhost:8090/chatEndpoint/websocket.

Now you are good to go and you can run the test. If all goes well you should see a lot of console output with SUCCESS somewhere near the bottom.

Ok, so the test doesn’t really do a whole lot just yet. So I’m going to add the next test actions to subscribe to the destination /topic/users/joined, join the chat room and then finally verify that a STOMP MESSAGE frame is sent to indicate a user has joined.

If you look carefully at the last test action, the MESSAGE frame, you will notice the message-id header. The server sets the value of this header dynamically so the exact payload comparison done here is bound to fail, unless of course you are incredibly lucky. So how do I get around this problem?

Thanks to citrus there are many ways to solve this problem:

Remove the payload verification from the test action - This just ignores the problem for the time being but doesn’t fix it.

Do a partial payload verification – It’s possible to just search for certain strings in the payload, ignoring the rest.

Unmarshall the payload, converting it into a java object and verify the individual attributes – This is slightly more complicated but offers by far the most flexibility.

For the moment I’m going to go with partial payload verification. When using the Citrus Java DSL you can easily do this with a ValidationCallback as shown below:

Great. Go ahead and run the test. This time it should run successfully.

Cleaning up the test

So far I’ve covered a user joining the chat room. I still have to verify that rooms can be created, removed, messages can be sent, notifications for the above are received, etc. But before I do this lets take a step back and look at our test so far.

It’s not bad, but it could be cleaned it somewhat. There are too many concatenated strings, too many carriage returns and other funny characters. It’s too hard to read. It would be great if I could use a fluid API for generating the STOMP frames. And since I’m planning on verifying and extracting data from the received payloads it would be equally cool if this could be somehow unmarshalled. Well guess what, you can do this with citrus. This is what I was talking about earlier when I mentioned how important it is to pick an integration test tool that is flexible. It’s not that citrus supports STOMP out of the box, because it doesn’t, at least not yet. However through its flexible API it enables a tester to add support for features or behaviour that is currently not supported. And this is what I’m going to show you now when I clean up or refactor this test.

I’ll leave the other test class in place and create a new test class Test_03_StompIT, copying over the contents of the original.

I’ll begin by creating a new StompFrame class, which is just a container for holding a STOMP frame in a structured way.

Wrap-up

I added one final test class Test_04_CompleteIT which simulates all REST and STOMP communication in one single test including

subscribing to all STOMP topics,

joining the chat,

creating a room,

sending a message,

deleting a room

and finally leaving the chat

You can find it in my git repository along with all the other tests.

I hope I have inspired you in this blog to at least consider Citrus when you’re thinking about integration tests in the next or even current project. Although I concentrated mainly on testing a web application here, you can use Citrus for just about all integration test scenarios you can imagine. It’s used a lot in middleware applications, which is one of the reasons the test framework was developed to begin with, but it’s not limited to middleware as is hopefully demonstrated above.

Some time has passed since part one of this blog post series and we have made some improvements on the Citrus Arquillian extension.
So we can look forward to this post as we move on with a more complex test scenario where we include some Citrus mail server within our test. In part one we have already combined both frameworks Arquillian
and Citrus with a basic example.

Let me recap first what we have so far. Citrus is part of the Arquillian test execution and we are able to call our employee REST JEE service which is deployed in an embedded Wildfly application server.
Arquillian takes care on the test deployment and provides resources such as the endpoint URL to call. In our first test we called the employee service adding new employees and getting the complete list of all employees via REST.

Now we want to extend the employee service so that each new employee gets a welcome email message. Therefore we extend the employee JEE EJB with a mail session bean that is able to send email messages.

@SingletonpublicclassEmployeeRepository{privatefinalEmployeesemployees;@EJBprivateMailSessionBeanmailSessionBean;publicEmployeeRepository(){employees=newEmployees();}publicvoidaddEmployee(Employeee){employees.getEmployees().add(e);if(e.getEmail()!=null&&e.getEmail().length()>0){mailSessionBean.sendMail(e.getEmail(),"Welcome new employee",String.format("We welcome you '%s' to our company - now get to work!",e.getName()));}}publicEmployeesgetEmployees(){returnemployees;}}

The employee service calls a mail session bean implementation when the email field is set on the new employee. The mail message is sent to the employee mail address as recipient and is a basic text message with subject and text body part.
Lets have a closer look at the mail session bean implementation that uses Java mail API for creating sending out the mail mime message.

Now in our test scenario we need a valid SMTP mail server on host localhost and port 2222. Fortunately Citrus is able to provide such a mail server so we add the citrus-mail Maven module to our test project.

Now we are ready to add the mail server as a Citrus component. Citrus is working with Spring so we need to add the mail server to the Spring application context. We add a new property to the Arquillian descriptor so the Citrus extension will
load our new configuration:

The configuration class must extend the Citrus base configuration class. This basic class adds all needed Spring beans for Citrus such as message validators, functions, validation matchers and so on. Important is our new mail server that uses the port
2222 and automatically starts with the Citrus application context. This is everything we need to do in order to add the mail server component to the Citrus runtime. We can add other Citrus endpoint components such as JMS endpoints, SOAP WebService servers
and Camel endpoints here the same way. For now we are finished with the configuration and we can reference the mail server in our test case.

@RunWith(Arquillian.class)@RunAsClientpublicclassEmployeeMailTest{@CitrusFrameworkprivateCitruscitrusFramework;@ArquillianResourceprivateURLbaseUri;privateStringserviceUri;@CitrusEndpointprivateMailServermailServer;@Deployment(testable=false)publicstaticWebArchivecreateDeployment(){returnShrinkWrap.create(WebArchive.class).addClasses(RegistryApplication.class,MailSessionBean.class,EmployeeResource.class,Employees.class,Employee.class,EmployeeRepository.class);}@BeforepublicvoidsetUp()throwsException{serviceUri=newURL(baseUri,"registry/employee").toExternalForm();}@Test@CitrusTestpublicvoidtestPostWithWelcomeEmail(@CitrusResourceTestDesignercitrus){citrus.send(serviceUri).fork(true).message(newHttpMessage("name=Rajesh&age=20&email=rajesh@example.com").method(HttpMethod.POST).contentType(MediaType.APPLICATION_FORM_URLENCODED));citrus.receive(mailServer).payload("<mail-message xmlns=\"http://www.citrusframework.org/schema/mail/message\">"+"<from>employee-registry@example.com</from>"+"<to>rajesh@example.com</to>"+"<cc></cc>"+"<bcc></bcc>"+"<subject>Welcome new employee</subject>"+"<body>"+"<contentType>text/plain; charset=us-ascii</contentType>"+"<content>We welcome you 'Rajesh' to our company - now get to work!</content>"+"</body>"+"</mail-message>").header(CitrusMailMessageHeaders.MAIL_SUBJECT,"Welcome new employee").header(CitrusMailMessageHeaders.MAIL_FROM,"employee-registry@example.com").header(CitrusMailMessageHeaders.MAIL_TO,"rajesh@example.com");citrus.receive(serviceUri).message(newHttpMessage().statusCode(HttpStatus.NO_CONTENT));citrus.send(serviceUri).fork(true).message(newHttpMessage().method(HttpMethod.GET).accept(MediaType.APPLICATION_XML));citrus.receive(serviceUri).message(newHttpMessage("<employees>"+"<employee>"+"<age>20</age>"+"<name>Rajesh</name>"+"<email>rajesh@example.com</email>"+"</employee>"+"</employees>").statusCode(HttpStatus.OK));citrusFramework.run(citrus.getTestCase());}}

The Arquillian test case is basically the same as before in our first part example. The test now uses a @CitrusEndpoint annotated mail server component. The Arquillian Citrus extension will automatically inject the
mail server Spring bean that we have added to the Citrus configuration before. In case multiple components of the same type are available in the configuration you can use the @CitrusEndpoint annotation with a Spring bean name
like @CitrusEndpoint(name=”myMailServer”). We receive the mail message right after the test has called the service interface with the new employee Rajesh and a valid email field rajesh@example.com. The mail server Citrus component
is ready to be used in a receive test action. Citrus waits for the mail message to arrive and performs message validation with an expected mail message. Citrus automatically converts the mail mime message to a XML message representation.
We can expect the mail message content much better using the XML syntax as we can use the powerful XML validation with XPath, ignore and validation matcher support.

In addition to that Citrus adds some special header values for explicit validation in the receive action. That completes the mail server test case. Citrus automatically start a SMTP server that receives the mail message. The mail is not sent to
a real recipient we just want to validate the mail message content in our test. The mail server did automatically accept the authentication in default mode. We could also switch to advanced mode where we can also validate the authentication steps. For now we keep
it simple and are happy to receive the mail message. Please note that we can mix the receive actions of different interfaces in Citrus very easy. Citrus acts both as client and server on our REST and mail interfaces in the test.

This should close the book for this post. You can review the example code on christophd@github. In a next post I will show you how we can execute
the test as part of the test deployment on the application server. Then we have direct access to container managed resources such as JMS connection factories and queues. Once again, stay tuned!

Citrus and Arquillian
both refer to themselves as integration test frameworks. Following from that you might think these frameworks somehow ship the same package but this is not the case. In fact the frameworks work
brilliant together when it comes to automate the integration testing of JEE applications.

Arquillian has a focus on simplifying the archive deployment with the ability to run integration test cases inside the boundaries of an application container.
The tests are literally part of a server deployment. This approach brings great advantages such as accessing deployment and container resources within the test case.
The application is deployed to a real application server (e.g. Tomcat, Wildfly) which is a good idea as we then also test our application server configuration and we load
the application with all container managed resources such as database connections, JNDI resources and so on. Secondly the test case itself is able to directly use the
container managed resources with injection in the Arquillian test case which is a great thing to do! It becomes very easy to invoke your services in a close to production
nature then.

Citrus primarily has the objective to simplify the usage of different messaging transports in a test case. Citrus offers ready to use components for sending and receiving
messages as a client or server and helps to design a message flow across multiple service calls.

In combination the two frameworks manage complex integration test scenarios that perform fully automated. And this is what we want to have at the end of a day - fully automated integration tests.
The magic is possible since Arquillian offers a great extension mechanism and Citrus provides an Arquillian extension module. Once the extension is enabled in your Arquillian project
you can use Citrus features and components within a your Arquillian test case.

The extension configuration is placed in the basic Arquillian descriptor called arquillian.xml. We use the citrus qualifier so the settings are automatically loaded with the Citrus extension.

For now the possible extension settings are:

citrusVersion: The explicit version of Citrus that should be used. Be sure to have the same library version available in your project (e.g. as Maven dependency). This property is optional. By default the extension just uses the latest stable version.

autoPackage: When true (default setting) the extension will automatically add Citrus libraries and all transitive dependencies to the test deployment. This automatically enables you to use the Citrus API inside the Arquillian test even when the test is executed inside the application container.

suiteName: This optional setting defines the name of the test suite that is used for the Citrus test run. When using before/after suite functionality in Citrus this setting might be of interest.

configurationClass: Full qualified Java class name of customized Citrus Spring bean configuration to use when loading the Citrus Spring application context. As a user you can define a custom Citrus configuration with this optional setting.

The dependency automatically adds the required Citrus core dependencies so you are ready to work with Citrus framework components. In case you want to use special Citrus components like JMS, FTP, Mail or something like that you need to
add these modules each separately to your Maven POM, too. For now we want to use Http clients and the Citrus Java DSL so lets add the dependencies for that.

@RunWith(Arquillian.class)@RunAsClientpublicclassEmployeeResourceTest{@CitrusFrameworkprivateCitruscitrusFramework;@ArquillianResourceprivateURLbaseUri;privateStringserviceUri;@DeploymentpublicstaticWebArchivecreateDeployment(){returnShrinkWrap.create(WebArchive.class).addClasses(RegistryApplication.class,EmployeeResource.class,Employees.class,Employee.class,EmployeeRepository.class);}@BeforepublicvoidsetUp()throwsMalformedURLException{serviceUri=newURL(baseUri,"registry/employee").toExternalForm();}/**
* Test adding new employees and getting list of all employees.
*/@TestpublicvoidtestCreateEmployeeAndGet(@CitrusTestCitrusTestBuildercitrus){citrus.send(serviceUri).message(newHttpMessage("name=Penny&age=20").method(HttpMethod.POST).contentType(MediaType.APPLICATION_FORM_URLENCODED));citrus.receive(serviceUri).message(newHttpMessage().statusCode(HttpStatus.NO_CONTENT));citrus.send(serviceUri).message(newHttpMessage().method(HttpMethod.GET).accept(MediaType.APPLICATION_XML));citrus.receive(serviceUri).message(newHttpMessage("<employees>"+"<employee>"+"<age>20</age>"+"<name>Penny</name>"+"</employee>"+"</employees>").statusCode(HttpStatus.OK));citrusFramework.run(citrus.build());}}

As you can see this is a normal Arquillian JUnit test case. We are running the test in client mode with the @RunAsClient annotation. As the
Citrus extension is active in background we are able to inject the framework instance with the @CitrusFramework annotation. The Citrus
framework instance is automatically loaded and configured with all necessary settings in background when the Arquillian test starts. As usual
we can build the deployment archive with our server resources that we need to test and we have access to @ArquillianResource annotated
resources such as the REST service endpoint URI of our application.

The test method itself is provided with a @CitrusTest annotated method parameter that represents the Citrus execution test builder. This is a Java DSL representation
of what Citrus has to offer when it comes to sending and receiving messages over various message transports. The Citrus Arquillian extension will automatically inject
this method parameter so we can use it inside the test method block in order to define the Citrus test logic.

Basically we invoke the deployed REST service with Citrus using the Java DSL send and receive methods. Each receive operation in Citrus also triggers the message validation mechanism. This includes
a syntax check in case of SOAP and XML messages with a WSDL or XSD given and a semantic check on received message body and header values. The tester is able to give an expected message template that is used
as comparison template. Citrus is able to deeply walk through XML or JSON message payloads comparing elements, attributes, namespaces and values. In case the received message response does not match the given message template
the Arquillian test case will fail with respective validation errors. For now lets keep it simple so we just expect some Http response status codes in the receive operations. The last receive operation expects a very simple XML
message payload with the newly added employee data.

With the ability to send and receive messages via Http REST we simply invoke the deployed service endpoint and validate its outcome. With a sequence of send and receive operations in Citrus we can build complex message flows with
multiple service endpoints involved.

That’s it we have successfully combined both frameworks. Arquillian helps us to deploy and run our application inside an application container and we have easy access to managed resources. Citrus is able to invoke the services via Http with
powerful validation of the received response messages. This is just a very simple sample for now as I just wanted to show the basic setup. Based on this knowledge we can continue with a more complex test scenario. We will start
to use Arquillian in container testing mode and we will start to use more complex Citrus server components in one of my next posts. Stay tuned!

In this post I will continue with the Apache Camel integration testing scenario that we have worked on in part one and
part two of this series.
This time we focus on exception handling in Camel routes. First of all let’s add exception handling to our Camel route.

Camel supports exception handling on specific exception types. The onException route logic is executed when the defined exception type was raised
during message processing. In the sample route we call a separate Seda endpoint seda:errors for further exception handling. The challenge for our
test scenario is obvious. We need to force this error handling and we need to make sure that the Seda endpoint seda:errors has been called accordingly.

The static endpoint definition is not mandatory as Citrus is also able to work with dynamic endpoints. In our case the dynamic endpoint for consuming messages on
the seda:errors endpoint would simply be camel:sync:seda:errors. The decision which kind of endpoint someone should use depends
on how much the endpoint could be reused throughout multiple test scenarios. Of course static endpoints are highly reusable in different test cases. On the downside
we have to manage the additional configuration burden. In this post I will use the static endpoint that is injected to the test case via Spring’s autowiring mechanism.
Let’s write the integration test.

The magic happens when Citrus sends back a synchronous response on the seda:sayHello endpoint which is done right after the sleep action in our sample test.
Instead of responding with a usual plain text message we add special header values citrus_camel_exchange_exception and citrus_camel_exchange_exception_message.

send(sedaHelloEndpoint).messageType(MessageType.PLAINTEXT).payload("Something went wrong!").header("citrus_camel_exchange_exception","com.consol.citrus.exceptions.CitrusRuntimeException").header("citrus_camel_exchange_exception_message","Something went wrong!");

These special Citrus headers instruct the Citrus Camel endpoint to raise an exception. We are able to specify the exception type as well as the exception message. As a result
the Citrus endpoint raises the exception on the Camel exchange which should force the exception handling in our Camel route.

The route onException block in our example should send the error to the seda:errors endpoint. So let’s consume this message in a next test step.

receive(sedaErrorHandlingEndpoint).messageType(MessageType.PLAINTEXT).payload("Something went wrong!").header("CamelExceptionCaught","com.consol.citrus.exceptions.CitrusRuntimeException: Something went wrong!");

With this receive action on the error endpoint we intend to validate that the exception handling was done as expected. We are able to check the error message payload and in addition
to that we have access to the Camel internal message headers that indicate the exception handling. Both message payload and message headers are compared to expected values in Citrus.

As a next test step we should provide a proper response message that is used as fallback response. The response is sent back as synchronous response on the seda:errors endpoint saying Hello after error!.
The Camel onException block and in detail the default Camel error handler will use this message as final result of the route logic. So finally in our test we can receive the fallback response message as result
of our initial direct direct:hello request.

This completes this simple test scenario. We raised an exception and forced the Camel route to perform proper exception handling. With the Citrus endpoints in duty we received the error message and provided a fallback
response message which is used as final result of the Camel route.

Error handling in message based enterprise integration scenarios is complex. We need to deal with delivery timeouts, retry strategies and proper transaction handling. This post only showed the top of the iceberg but I hope
you got the idea of how to set up automated integration tests with Apache Camel routes. The Citrus framework is focused on providing real message endpoints no matter of what kind or nature (Http, JMS, REST, SOAP, Ftp, XML, JSON,
Seda and so on). What we get is automated integration testing with real messages being exchanged on different transports and endpoints.

In part one of this blog series we have used Citrus in combination with Apache Camel for setting up
a complete integration test scenario. Remember we have interacted with our Camel route via JMS as client and via SOAP Http WebService as a server.

Now in the second part we want to interact with a Camel route using direct and Seda in memory message transports. First of all we need a Camel route to test.

The Camel route is obviously very simple. The route reads messages from a direct inbound endpoint and forwards all messages to a Seda in memory channel. The Seda communication is synchronous
so the route waits for a synchronous response to arrive. Now when we would like to test this simple route we would have to provide the inbound messages to trigger the route and we would have to
provide proper synchronous response messages on the Seda endpoint.

Lets set up a Citrus test case for this test scenario. We need a direct Camel route message endpoint that is able to call the Camel route. The Camel endpoints are available with a separate Citrus module.
We need to add this library to our project as test scoped dependency if not already done so.

As you can see we have added two Citrus endpoint components both coming from the Citrus Camel module. The first component is interacting with the direct endpoint direct:hello and the second component is interacting with the
Seda seda:sayHello endpoint. Both Citrus components use synchronous message communication so we are able to send and receive messages synchronously. Let’s move on with writing a test case.

The test is using Spring’s autowiring mechanism in order to inject the Citrus message endpoint components. We have four message interactions in our test. First of all we send a plain text message to the direct Camel route endpoint.
The Camel route is triggered and according to the route logic the message is forwarded to the Seda endpoint. The second test action is a message receive action on this same Seda endpoint. So if the Camel route logic is working as
expected we should be able to receive a message here. The receive test action also performs a validation on the message content received. As a tester we specify the expected message payload. Citrus as test framework compares this
expectation to the message content actually arriving. When everything is matching as expected we continue with the test.

As the Seda endpoint is synchronous we can send back a response to the calling client. In our test this is done with a respective send message action that references the same Seda endpoint. Before we send back a plain text response message
we add a sleep test action in order to simulate some hard work on the backend. As a next step the Camel route receives our simulated response message and immediately responds to the calling direct endpoint client to complete the route.
This is our last step in the test case where we receive the very same response message on the direct endpoint as final message response.

Please do not get confused with this test setup. This scenario is purely constructed for demonstrating how Citrus interacts with Camel routes in terms of synchronous communication on both ends (consuming and producing). As the test performs
all actions four messages are exchanged in between Citrus and our Camel route to test. If everything is working as expected all messages are completed and the test case is successful.

Someone might feel uncomfortable in defining the Citrus endpoint components for each Camel route endpoint in the Spring application context just to reference them inside the test case. This is where dynamic endpoints come in handy. Citrus
is also able to create the endpoint at runtime. See how this looks like.

With the dynamic endpoints we do not have to use any of the predefined endpoint components in the Citrus Spring application context. The test just creates the endpoints automatically at runtime. The result is exactly the same as before.

We have seen that Citrus is able to both send and receive message from an to route message endpoints in Apache Camel. This is a good way of testing Camel routes with simulation of route interface partners. In the next part I will
add some error scenarios where the Seda endpoint component is forcing an exception that should be handled within our Camel route.

Apache Camel is a great mediation and routing framework that integrates with almost every enterprise messaging transport. In the past I have experienced Camel projects struggling with integration testing where the actual message interfaces to boundary applications are not tested properly in an automated way.

So in a series of posts I would like to talk about integration testing strategies for Apache Camel projects using the Citrus integration test framework.

Part 1: Setup the Citrus test project and interact with a sample Apache Camel project with JMS and SOAP WebService components

The route consumes messages from a JMS destination called JMS.Queue.News, logs the message content and forwards the message content to a Http SOAP WebService using the Spring WS library. So we have two different messaging interfaces (JMS and SOAP WebService) to boundary systems in our sample.

Camel does provide very good test strategies for mocking these message transports. In a unit test you can mock the boundary JMS and SOAP interfaces with special mock components. This is great, but sometimes error prone for the following reasons. The JMS protocol provides several settings that are essential for the whole application behavior. For instance the JMS consumer may operate with concurrent consumers, connection pooling and transactional behavior. These settings are done on the Camel JMS component and on the JMS connection factory. In a mocked unit test these settings are not included as the test mock just does not process the real JMS message transports. No doubt these settings make a significant difference in production and have to be tested. In addition to that the SOAP WebService interface uses a WSDL and other SOAP specific settings like the soap action header. We could also add WS-Security and WS-Addressing headers here. In a mocked unit test these quite important interface characteristics are not tested over the wire. The actual SOAP message is not created and you are not able to verify the complete message contents as they are sent over the wire.

So the crucial weapon to avoid bugs related to untested transport settings is integration testing where the actual JMS message broker and a real SOAP WebService endpoint are involved in the test. And this is where Citrus comes in. In a Citrus test case the actual JMS consumer and producer settings do apply as well as a fully qualified WebService endpoint that receives the messages via Http message protocol. We use a real JMS message broker and Http server as it is done in production.

Lets setup a Citrus project that is able to interact with the sample Camel application route.

Citrus as integration test framework works best with Maven. You can setup a Citrus Maven project in minutes with this quick start tutorial. Once you have done this we have a Maven project with some sample Citrus test cases already in it. No we need to add the JMS and SOAP WebService configuration to the Citrus project. First of all let us add ActiveMQ as JMS message broker.

We need to add the ActiveMQ Maven dependencies to our Citrus project. This is done in the Maven POM pom.xml file. Once we have this we can add the message broker to the Citrus configuration. We add a new Spring application context file citrus-activemq-context.xml in src/citrus/resources folder.

As next step we include this new Spring context file in the citrus-context.xml so both the ActiveMQ message broker and the JMS connection factory get loaded during startup. Just add a import statement to the citrus-context.xml file like this:

<importresource="classpath:citrus-activemq-context.xml"/>

Good! Now we are ready to connect with the JMS message transport. Let us add the Citrus JMS endpoints. You can do this also in the citrus-context.xml file:

This represents a Citrus Java test case. Notice that this is nothing but a normal Java unit test. I use TestNG as unit test framework. Others might prefer JUnit which is also possible. I think TestNG is much more powerful but this is another story. Also notice that we referenced the newsJmsEndpoint Citrus component in the first send operation. We could have used Spring autowire injection of the JmsEndpoint here, but we want to keep it simple for now. What we have right now is an integration test which actually sends the JMS message with some news content to the JMS queue destination and on the other side we receive the real SOAP message as a web server. But wait! We have not yet added the SOAP server configuration yet! Let’s do this in the citrus-context.xml configuration file.

The server starts a fully qualified Http web server with the SOAP endpoint for receiving the news request. In the test case we can reference the server in a receive operation. That’s it! We are able to run the test. Of course we also need to start our Camel application. You can do this in another process with Maven or you deploy your Camel application to some application server. Citrus is interacting with the Camel route as a normal interface client just using the JMS endpoint. Once you run the integration test you will see how the messages are actualy sent over the wire and you will see Citrus receiving the actual SOAP request message:

Also Citrus will put this received message content to validation with comparing the message body and header to the expected content given in the test case. Let’s recap. What we have done is a complete integration test where the Camel route interfaces are called with real message transport interaction. The ActiveMQ JMS message broker is real the SOAP WebService server is real. The message transport configuration is tested properly with message conversion and expected message content validation. The Camel application is loaded and deployed with the complete configuration and settings.

Citrus invokes the Camel route by sending a proper JMS message to the route endpoint. The Camel route processes the message and sends out the SOAP request message. In case the message content is not as expected in the Citrus receive operation or in case the SOAP message is not arriving at all the integration test fails. In this integration test we can simulate both client and server side interaction with our Camel application.

As the Citrus test case is nothing but a normal TestNG/JUnit test we can integrate the test in our Maven build lifecycle and continuous integration process. This completes our first part of how to do extended integration testing with Apache Camel projects. In my next part I will concentrate on how to interact with Apache Camel routes using direct and Seda in memory message transports.

In part I of this tutorial I introduced the basic concepts and benefits of Citrus as a test driver for ESB projects in general and webMethods in particular.
In this second part I want to discuss some Citrus project setup options and provide a quickstart template project for Ant users.

Maven or Ant?

Basically, Citrus support both options – you are free in your choice of the build system to use to drive your Citrus tests. Typically a Maven setup is preferred since Maven reduces the necessary project setup
clutter one has to face when using Ant. Check this quickstart if you want to let Maven create your project structure for you.

However, everything in the webMethods world is ant-based (like tooling, deployment etc.), at least this was the case during my experience with the 8.2 version of webMethods, let me know if things have changed meanwhile.
So it might make pretty good sense to setup the Citrus project with Ant as well to reuse existing project knowledge. That’s what the rest of this blog entry is basically about.

Ant Setup

The Citrus homepage provides an awesome Ant quickstart. Everything you need is described there in detail, however, it is quite a tough job to collect all the necessary dependency jar’s manually.
Since version 1.4, Citrus provides a maven assembly goal which creates a directory with all dependency jar’s which can be thrown into the lib folder of your newly created Citrus project. You can trigger this assembly
by grabbing the Citrus sources and execute

mvn assembly:assembly -Passembly-antlibs

from the project root. Unfortunately I faced some issues on my Macbook with Maven version 3.0.5 so this way was blocked for me. Additionally, not everyone might have interest or possibilities to check out the sources
or have maven installed and setup on his machine. That’s basically why I want to provide a template project to speed up Ant project setup.

Citrus Ant Template Project

For those who prefer the easiest way (like me), I have set up up a little Eclipse template project, where everything needed to run Citrus with Ant is already in place. It contains

The correct folder structure

All necessary Citrus (1.4) core libs and dependencies

A prepared citrus citrus-context.xml and log4j.xml

A template build.xml file

You can grab the template project on Github here , import it (Select Import –> General/Archive File in Eclipse/SAG Designer)
and kick start developing integration tests for your webMethods project. Typically, you will work in Software AG Designer to develop your webMethods solution, luckily it is based on Eclipse and you can perfectly
work with your Citrus test projects in the Java perspective of SAG Designer. In fact, the template project is created and exported from SAG Designer 9.5.

In the next part, I will enhance our empty project with a first test: a SOAP request/reply scenario with Citrus against a webMethods package.

Continuous integration is almost mainstream nowadays. Probably no one wants to argue against the value of having an all-embracing integration test suite in place,
which is lightweight enough to be executed on each code change. In this blog series I want to show the interplay between Citrus,
the integration test framework written and maintained by ConSol and a commonly used Enterprise Service Bus, the webMethods Integration Server.

Meet the participants

Citrus is a lightweight integration test framework specially suited for enterprise integration challenges. It supports a broad set of communication protocols and is able to
simulate partner applications of any type to provide proper end-to-end testing in a sandbox environment.

Our system-under-test is Software AG’s webMethods Integration Server, which is an industry-proof ESB solving complex integration and B2B challenges in large-scale deployments around the globe.

Why Citrus?

On a closer look at the built-in support for automated testing, webMethods provides integrated tooling (namely the wMTestSuite), directly incorporated into the Software AG Designer to support
developers with tests operating on the basic building blocks inside webMethods – the Flow service.

Comparing this tooling to traditional software development, this means there is a good framework for Unit/white box testing in place, but: wmTestSuite is not suited for automated tests from an
integration/black box perspective. For such tasks, several commercial tools are available, but this is where Citrus with its support for automated tests on interface level comes into play as a
smart and fully open source alternative.

What’s coming up?

Over the next parts of this series I want to share the basic steps in order to setup a Citrus project and develop automated tests for several webMethods integration scenarios, including SOAP
request/reply, SOAP and JMS mocking as well as flat file integration. In the end I might also cover the topic BPMN processes on top of webMethods which can be tested with Citrus as well.

Lately I had to deal with Excel files as REST Http service response. I came up with a pretty clever validation mechanism in Citrus that I would like to share with you. You can apply the Excel validator to your Citrus project, too. It is not very complicated as you will see in this post.

First of all lets have a closer look at the response message we get from REST Http service.

The response message states a Content-Type header set to application/vnd.ms-excel which indicates the Excel content to the browser. Furthermore the Content-Disposition header informs the browser that he should open the save as dialog to the user rather than displaying the content. Finally the Excel file is added as binary content with charset windows-1252.

So now we would like to receive this message in our Citrus test also being able to validate the Excel file content as well as the important header entries. This is how we can do it:

First of all we introduce a custom message validator which handles the binary Excel message content. We intend to create an Excel workbook object that we can pass into the Citrus test. The tester is then able to write Groovy validation code accessing the Excel workbook object. Heres the code for the custom Excel message validator:

The message validator is quite simple isn’t it. We extend GroovyScriptMessageValidator as we would like to write groovy validation code inside the test. The validator uses a custom script template (excel-script-validation.groovy) and supports message type ms-excel. Keep that in mind as we will use this later in our test case. For now we add this message validator to the Citrus Spring application context (citrus-context.xml).

Not much has happened though in this validator’s Java code. The magic is done inside the Groovy script template excel-script-validation.groovy that we have added to the classpath in our project. Lets have a look at this file:

Ah, now we are getting more precisely! We introduce a new HSSFWorkbook (see also http://poi.apache.org/) with the message payload that we have just received. Please do not mind the Java-like Groovy programming style - I want to keep things easy for Java programmers in this post. However we now have the workbook object ready for validation code in our test which automatically comes in where @SCRIPTBODY@ placeholder is located. So before we continue to look at the test example we shortly add apache poi jar dependency to our project Maven pom.

We can access the Excel workbook object like a charm. Also the important message headers are checked for expected values. Do not forget to define the message type ms-excel in the receive action. This ensures that the validation mechanism in Citrus uses our custom Excel message validator for preparing the apache poi workbook object in advance.

That’s it! We are now able to validate Excel files in Citrus! The same thing can easily be done with other MS office formats (doc), too. If I have time the next days I will zip that project code and add it as download for you. Have fun with it!

TestNG provides brilliant support for test parameters and data providers. With some annotation magic you are able to pass parameter values to your test method and finally to your Citrus test logic. Actually the TestNG parameters are injected to the Citrus test as normal test variables. Lets put this to the test with a simple example:

We have to use the Citrus data provider (citrusDataProvider) along with a named parameter annotation (message) on the test method. Just add the annotations to the Citrus test method as shown in the example above. Next thing we override the method getParameterValues() in order to provide the actual parameter values. As you can see we provide three static values for the “message” parameter.

Inside the Citrus test you can use the test variable $ as usual. TestNG and Citrus automatically take care on creating the variable with respective value from data provider. The test case is very simple and looks like follows:

As we have three static parameter values in our data provider the whole Citrus test is executed three times. Each time the data provider injects the respective test parameter and ${message} variable. The Citrus test report gives us the test results with all parameters.

We can also use multiple test parameters at a time with all values coming from data provider. How about reading the parameter values from external property files or database?! I use this feature a lot for preparing my Citrus tests with dynamic parameter values from external resources and I bet you will enjoy this feature as much as I do. For more information on TestNG data providers please also have a look at the official documentation (http://testng.org/doc).

Citrus includes a lot of convenient features which are only waiting for you to discover and use them. The other day I needed to validate a SoapAttachment.
As you probably already know, a SoapAttachment is referenced by a href property in an Include tag like this:

Things become a little more complicated as soon as you start to connect to real backend systems for integration testing. Especially when timestamps are involved. In my case the SoapAttachment contains a calendar
invitation in vCal format which is basically a simple text based key/value format. I have to ignore the value for the key LAST-MODIFIED because it would be impossible to predict this timestamp and
it’s not really relevant either. So what I really need is a way to compare the expected structure with the actual result line by line, a possibility to completely ignore a line and a way to only ignore the value
but still compare the keys of some lines.

To solve this, the Citrus framework offers the possibility to define your own validators and include them into your test cases. Simply add a Java class which extends AbstractSoapAttachmentValidator to your test project and
implement the validateAttachmentContent method. This will be your new validator and could look somewhat like the simple example I’ll add to the end of this blog entry.

Go back to your citrus-context.xml and add your newly created validator bean:

So here’s the promised simple example for your lineByLineSoapAttachmentValidator:

publicclassLineByLineWithIgnoreSoapAttachmentValidatorextendsAbstractSoapAttachmentValidator{privatestaticfinalStringIGNORE="@ignore@";privatestaticfinalStringLINE_DELIMITERS_R_N="[\\r\\n]+";@OverrideprotectedvoidvalidateAttachmentContent(SoapAttachmentreceivedAttachment,SoapAttachmentcontrolAttachment){try{Stringcontrol=controlAttachment.getContent().trim();Stringreceived=receivedAttachment.getContent().trim();String[]controlLines=control.split(LINE_DELIMITERS_R_N);String[]receivedLines=received.split(LINE_DELIMITERS_R_N);// Check number of propertiesif(controlLines.length!=receivedLines.length){thrownewCitrusRuntimeException("Number of lines are not equal. Expected: "+controlLines.length+" Received: "+receivedLines.length);}// Now compare the propertiesfor(inti=0;i&lt;controlLines.length;i++){StringcontrolLine=controlLines[i].trim();StringreceivedLine=receivedLines[i].trim();if(StringUtils.endsWithIgnoreCase(controlLine,IGNORE)){compareBeginningOfLines(controlLine,receivedLine);// value shall be ignored, so just continue;continue;}if(StringUtils.startsWithIgnoreCase(controlLine,IGNORE)){compareEndingOfLines(controlLine,receivedLine);// value shall be ignored, so just continue;continue;}if(!controlLine.equalsIgnoreCase(receivedLine)){thrownewCitrusRuntimeException("Lines are not equal.\n\nExpected: "+controlLine+"\n\nReceived: "+receivedLine);}}}catch(Exceptione){thrownewCitrusRuntimeException("Validation failed!",e);}}privatevoidcompareBeginningOfLines(StringcontrolLine,StringreceivedLine){// check the beginning of the lineStringbegin=controlLine.substring(0,controlLine.length()-8);if(StringUtils.hasText(begin)&amp;&amp;!StringUtils.startsWithIgnoreCase(receivedLine,begin)){thrownewCitrusRuntimeException("Beginning of lines not equal.\n\nExpected: "+controlLine+"\n\nReceived: "+receivedLine);}}privatevoidcompareEndingOfLines(StringcontrolLine,StringreceivedLine){// check the beginning of the lineStringend=controlLine.substring(8);if(StringUtils.hasText(end)&amp;&amp;!StringUtils.endsWithIgnoreCase(receivedLine,end)){thrownewCitrusRuntimeException("Ending of lines not equal.\n\nExpected: "+controlLine+"\n\nReceived: "+receivedLine);}}}

TestNG groups add great flexibility to the Citrus test execution. We are able to divide all tests into several groups reaching a sophisticated seperation of concerns in our test setup. As an example I want to classify some of my functional Citrus tests as “long-running”. These tests may not apply to continuous execution every time I package my project. Instead of this I want to set up a scheduled integration build to execute those long-running tests in a time schedule.

We simply declare the TestNG groups in the Java part of the Citrus tests, like this:

In Maven I can configure the TestNG groups to be included and excluded during build lifecycle. For better usability I add properties and profiles to my Maven POM, so the configuration looks like follows:

With this setup I am not forced to wait for the long-running tests every time I build the project locally as these test group is excluded by default. However with Maven profiles I am able to run all TestNG groups together or explicitly execute a single group:

TestNG groups in combination with Maven are extremely useful to break down Citrus tests into logical units. For additional reading and other ways to execute TestNG groups without using Maven please see the official TestNG documentation.

By setting the SOAP mustUnderstand header attribute to “1”, you indicate that the service provider must process the SOAP header entry. In case the service provider is not able to handle this special header a SOAP fault server error is sent back to the calling client. In this post I would like to point out an easy way to support these mustUnderstand headers when simulating SOAP WebServices with Citrus.

The service provider respectively the Citrus SOAP server simulation has to handle this UserID. Otherwise the client request can not succeed and is responded with SOAPFault.

Citrus uses the SpringWS project to provide SOAP WebServices endpoints for clients. In SpringWS you are able to add interceptors to the request processing chain in order to support SOAP-ENV:mustUnderstand headers. In this example we add the interceptors directly to the endpoint mapping in the Spring application context.

SpringWS automatically raises SOAP server faults in case we do not handle a SOAP-ENV:mustUnderstand header in the interceptor chain. Fortunately we explicitly accept the UserID SOAP header in the interceptor implementation with the understands() method returning “true” in that case. With this SOAP endpoint interceptor we are able to support mustUnderstand headers in Citrus WebService endpoints.

Citrus also offers a default interceptor implementation which handles mustUnderstand headers with a simple configuration. Just add the interceptor to the request processing and you will not have to implement the interceptor on your own.

Test cases in Citrus are usually provided with some meta information like the author’s name or the date of creation. This post shows how to extend on this to include your very specific meta data on your own.

However there may be some additional data needed to meet your individual testing strategy. Therefore you can extend the meta-info section at the very beginning of a test case very easily. Let me use a simple example to show how it is done.

First of all we define our custom meta information elements in a XML schema:

The schema declares four simple elements (requirement, pre-condition, result and classification) all typed as string. Later we want to add those elements as children to the meta-info element in the test case. But before we can do that let us add the new xsd schema to our project. As I use a Maven project layout the schema file goes to “src/main/resources/com/consol/citrus/schemas/my-testcase-info.xsd”.

Next thing we need to do is to announce the new schema to Spring. A Citrus test case is nothing else but a simple Spring configuration file with customized XML schema support. Therefore Spring needs to know our XML schema while parsing the test case configuration file. So we add the spring.schemas file to following location in our project: src/main/resources/META-INF/spring.schemas

The file maps virtual schema locations to the actual xsd locations in our project. The file content for our example will look like follows:

As you see it is quite easy to add custom meta information to your Citrus test case. The customized elements may be precious for automatic reporting. XSL transformations for instance are able to read those meta information elements in order to generate automatic test reports and documentation.

You can also declare our new XML schema in the Eclipse preferences section as user specific XML catalog entry. Then even the schema code completion in your Eclipse XML editor will be available for our customized meta-info elements.