Testing Sequences in WSO2 ESB

This post is intended to present a project that could help with testing the mediation sequences created in WSO2 ESB Projects.

Using tools like SOAP UI and Postman, we can test our APIs and Proxies by issuing requests to them and validate the response of the services. As this gives us a good start point for testing the integrations, it doesn’t allow us to test the individual pieces that compose the integration, the mediation sequences.

Thinking on that the project WSO2UnitTesting was created. The project was based on the following blog post.

The project consists in a car file that needs to be deployed to WSO2 ESB/EI server where the artifacts that needs to be tested will be also deployed to. It provides an API that we will call in order to test the sequences.

The API receives a post request with a JSON payload that will contain the information required to test a sequence:

An example of a request can be seen below:

{
"payload" : "<abc xmlns=\"http://www.abc.com\"><text>123</text></abc>",
"requestType": "xml",
"responseType": "xml"
"properties": [
    {
        "name":"PROP1",
        "value": "ABC",
        "scope": "default",
        "type":"STRING"
    }
],
"sequences": [
    "SequenceForTest"
]
}

The response has a similar structure, the only difference is that it will contain the payload and properties generated after the execution of the sequence.

Unit Test Example

As an example, we have built a sample app, that is a simple REST api around a Calculator SOAP Service. For the sake of the simplicity, we have create just one resource, /add that receives two numbers and returns a JSON with the result of the sum.

The resource is composed by the following sequences:

The API Code can be seen below:

An example of the API call can be seen below:

http://localhost:8280/calculator/add/1/2

As we could see, it is a very simple example of a WSO2 ESB API.

Let us now work on the Unit Tests for the sequences created for this examples.

Pre-requisites for running the examples

In order to run the examples we need to:

  1. Clone the WSO2UnitTesting project: git clone https://github.com/fjunior87/WSO2UnitTesting.git
  2. Build it: cd WSO2UnitTesting; mvn clean install
  3. Deploy the car file into the WSO2 EI/ESB. It will be under WSO2UnitTesting/WSO2UnitTestCompositeApplication/target;
  4. Clone the Application Example: git clone https://github.com/fjunior87/WSO2UnitTestExample.git
  5. Build it: cd WSO2UnitTestExample; mvn clean install
  6. Deploy the car file into the WSO2 EI/ESB. It will be under WSO2UnitTestExample/WSO2UnitTestExampleAppCompositeApplication/target;

We also need the postman project that can be found in the example app: UnitTestExample.postman_collection.json.

You can import it to postman and then send the requests.

Unit Test Using Postman

For this post, I will use postman to issue the requests to our UnitTest API and also to validate the response, as it supports tests.

For the first example we will test the validation sequence for a Success scenario. We can see the sequence code below:

As we could see, the sequence expects two properties and validate if they are both numbers. Below we can see, what would be the payload to test the success scenario:

{
    "payload" : "<empty/>",
    "requestType": "xml",
    "responseType": "xml",
    "properties": [
        {
            "name":"uri.var.number1",
            "value":"1",
            "type": "STRING"
        },
        {
            "name":"uri.var.number2",
            "value":"2",
            "type": "STRING"
        }
    ],
    "sequences": [
        "UnitTestExample_Validation_Sequence"
    ]
}

Let us now describe the payload being passed for this test case:

Using the payload above we will make a request to the following endpoint:

http://localhost:8280/unittest/test

The response payload will look like below:

{
    "payload": "<empty/>",
    "requestType": "xml",
    "responseType": "xml",
    "properties": [
        {
            "name": "number1_value",
            "value": "1",
            "type": "STRING",
            "scope": "default"
        },
        {
            "name": "uri.var.number2",
            "value": "2",
            "type": "STRING",
            "scope": "default"
        },
        {
            "name": "VALIDATION_RESULT",
            "value": "SUCCESS",
            "type": "STRING",
            "scope": "default"
        },
        {
            "name": "uri.var.number1",
            "value": "1",
            "type": "STRING",
            "scope": "default"
        },
        {
            "name": "number2_value",
            "value": "2",
            "type": "STRING",
            "scope": "default"
        }
    ],
    "sequences": [
        "UnitTestExample_Validation_Sequence"
    ]
}

It will basically contain the payload generated and the properties set after the execution of the sequence. In this case, it contains the properties that were used by the sequence as well the properties set after it, the most important property for our testing would be: VALIDATION_RESULT. Looking into the response payload we can see it was set as SUCCESS.

Once we have the request and response, we can use postman test scripts to assert the properties set and also the payload generated.

pm.test("response is ok", function () {
    pm.response.to.have.status(200);
});

pm.test("VALIDATION_RESULT is SUCCESS", function () {
    json = pm.response.json();
    var prop = json.properties.find(prop => prop.name == 'VALIDATION_RESULT' && prop.scope == 'default');
    pm.expect(prop.value).to.equal("SUCCESS"); 
});

Basically, this test is validation the status code, if it is 200, and if the property VALIDATION_RESULT is equal to ‘SUCCESS’

We can see an example of this test case execution below:

Validation Sequence Test Success

As we could see with this test, we were able to execute a sequence from our application passing all the expected properties.

In the next test case we will see an example of test passing an expected payload to a sequence.

In the test below we will be testing the sequence that generates the response payload based on the response got from the backend call. The test request can be seen below:

{
    "payload" : "<AddResponse xmlns=\"http://tempuri.org/\"><AddResult>30</AddResult></AddResponse>",
    "requestType": "xml",
    "responseType": "json",
    "properties": [],
    "sequences": [
        "UnitTestExample_BuildResponsePayload_Sequence"
    ]
}

In this test, we are not setting any property as it is not expected by the sequence being tested. We set only:

By executing this request we will receive a response like below:

{
    "payload": "{\n\t\t\t\t\"result\": 30\n\t\t\t}",
    "requestType": "xml",
    "responseType": "json",
    "properties": [],
    "sequences": [
        "UnitTestExample_BuildResponsePayload_Sequence"
    ]
}

And our Postman test will look like this:

pm.test("response is ok", function () {
    pm.response.to.have.status(200);
});

pm.test("Response payload should have the result equals to 30", function () {
    json = pm.response.json();
    payload = JSON.parse(json.payload);
    pm.expect(payload.result).to.equal(30);

});

That’s it for today.

In the postman project there are a couple of other test cases. If you want, you can also run the postman tests in the command line using Newman. Also, you could create your test cases using any other testing tool/framework like SOAPUI, RestAssured, Karate.

The source code of the unit test app and the example app can be found in the links below:

I hope you enjoyed and this can help you to increase the quality of your WSO2 EI projects!

See you in the next post.

comments powered by Disqus