Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
stephen_xue
Active Participant

Introduction


Groovy script is one of the main programming languages used in SAP CPI development. The SAP CPI console however doesn't provide an IDE to easily test and debug the groovy script program.

By using the "debug" / "trace" option in the message monitor, we can get some clues of the program in the runtime. Whereas it is not convenient to supervise all of the wanted variables during the runtime after all. That's why the gurus have come up with the great ideas as below:

https://blogs.sap.com/2017/10/06/how-do-you-test-your-groovy-scripts/

https://blogs.sap.com/2019/05/28/pimp-my-groovy-boosting-cpi-groovy-developments-with-intellij-idea/

https://blogs.sap.com/2018/05/22/get-groovin-with-your-iflows-groovy-scripting-with-eclipse-for-cpi/

 

It makes the Groovy script program becomes testable in the local IDE.

Take into account that more and more projects are running on the Agile mode and test driven development has been widely used. I'd like to show a case that developing a Groovy script for SAP CPI by using Test Driven Mode.

Sample Case


Overview requirement


The CPI is supposed to expose an API to the client to consume. The endpoint URL is in format as below
https://test.bsn.neo.ondemand.com/http/hello?client=NPL&system_id=e6975e7a-4c7f-11ea-b77f-2e728ce881...

The Groovy script inside the CPI is to parse all of the Header parameters and all 5 parameters of the client URL and populate them into message body in form of json as below
{
"client": "NPL",
"system_id": "e6975e7a-4c7f-11ea-b77f-2e728ce88125",
"scope": "COMPANY",
"start_date": "2020-01-02",
"redirect_uri": "http://remote.com.au/Callback",
"category": null
}


Possible Story Card for The Groovy Script to be Developed



  • Given


The Client makes a GET operation to the endpoint by using URL



https://test.bsn.neo.ondemand.com/http/hello?client=<client>&system_id=<system_id>&scope=<COMPANY|DI...;


  • When


The Sroovey script has been executed




  • Then


The payload as below should be set to message body



{
"client": <client>,
"system_id": <system_id>,
"scope": <COMPANY|DISTRIBUTION|PLANT>,
"start_date": <DATE>,
"redirect_uri": <http://remote.com.au/Callback>,
"category": <category>
}

Unit Test Template


here is a Unit Test template for your reference to be used. I will elaborate the detail implementation of each methods included later.
    static void main(String[] args) {
Initialization()
//GIVEN
SetHeaders()
SetBody()
//WHEN
ExecuteTest()
//THEN
UnitTestCases()
DisplayResultToConsole()
}

method Initialization will create a test class instance;

for GIVEN part, the template will set message header, body by using the testing data;

for WHEN part, the production code will be called;

for THEN part, the unit test cases will be asserted one by one and the result will be displayed;

Design the test cases


As for the test driven development, the test cases is supposed to be designed before the production code development.

In this example case, i will use URL given at the very beginning
https://test.bsn.neo.ondemand.com/http/hello?
client=NPL&system_id=e6975e7a-4c7f-11ea-b77f-2e728ce88125&
scope=COMPANY&start_date=2020-01-02&
redirect_uri=http://remote.com.au/Callback&category='

it has five parameters and the last one, category, is empty

For the test cases, i have come up with two:

  1. Check the hostname plus the endpoint is correct

  2. Check all of the parameter names are correct


These are two test cases developed.
    private static void UT_HTTPURLIsCorrect(payload){
String uttpurl = 'https://test.bsn.neo.ondemand.com/http/hello'
assert payload.find{it.key == 'CamelHttpUrl'}.value== uttpurl
}
private static void UT_ParemterNameIsCorrect(payload){
Set parameterList = ["client", "system_id", "start_date", "redirect_uri","category"]
int i
payload.each {
it ->
if(parameterList.contains(it.key)) {
i++
}
}
assert i == 5
}

After all of the test cases have been asserted, the result(header/body) still needs to be displayed so that it will be more clear for the developer to check.
    private static void DisplayResultToConsole(){
// Print Headers
msg.getHeaders().each {
println it
}
// Print body
println msg.getBody()
}

 

Positive Test Result


This is the result when a successful test has been conducted.



 

Negative Test Result


In order to make a negative result, let change a Unit Test Case a little bit as below:



and execute the test program again. we will get a result as below:


Production Code


The production code developed is quite straightforward. Here is the source code
package test.com
import com.sap.gateway.ip.core.customdev.util.Message;
import groovy.json.*;

Message processData(Message message) {
def params = [:]
def urlParameters = message.getHeaders().get("CamelHttpQuery")
// Parse all URL parameters into message payload
urlParameters.split("&").each {
it ->
String[] pair = it.split("=")
params[pair[0]] = (pair as List)[1]
}

// Parse all header parameters into message payload
message.getHeaders().each {
it ->
params << it
}
message.setBody(JsonOutput.toJson(params))
message.setHeader('Content-Type', 'application/json');
return message
}

 

Full version of the Unit Test Template Program
package test.com
import com.sap.gateway.ip.core.customdev.util.Message
import com.sap.gateway.ip.core.customdev.processor.MessageImpl
import groovy.json.JsonOutput
import groovy.json.JsonSlurper

class UnitTest {
// Global Variables
private final static String TEST_PROGRAM = './src/test/com/ParseURLParameter02.groovy'
private static String testURL = 'https://test.bsn.neo.ondemand.com/http/hello?client=NPL&system_id=e6975e7a-4c7f-11ea-b77f-2e728ce88125&scope=COMPANY&start_date=2020-01-02&redirect_uri=http://remote.com.au/Callback&category='
private static Message msg

static void main(String[] args) {
Initialization()
//GIVEN
SetHeaders()
SetBody()
//WHEN
ExecuteTest()
//THEN
UnitTestCases()
DisplayResultToConsole()
}

/*----------------------------------Unit Test----------------------------------------*/
private static void UnitTestCases(){
def jsonSlurper = new JsonSlurper()
def payload = jsonSlurper.parseText(msg.getBody());

UT_ParemterNameIsCorrect(payload)
UT_HTTPURLIsCorrect(payload)
}
private static void UT_HTTPURLIsCorrect(payload){
String uttpurl = 'https://test.bsn.neo.ondemand.com/http/hello'
assert payload.find{it.key == 'CamelHttpUrl'}.value== uttpurl
}
private static void UT_ParemterNameIsCorrect(payload){
Set parameterList = ["client", "system_id", "start_date", "redirect_uri","category"]
int i
payload.each {
it ->
if(parameterList.contains(it.key)) {
i++
}
}
assert i == 5
}

/*---------------------------------Utility Methods-----------------------------------------*/
private static void DisplayResultToConsole(){
// Print Headers
msg.getHeaders().each {
println it
}
// Print body
println msg.getBody()
}
private static void ExecuteTest(){
GroovyShell shell = new GroovyShell()
def script = shell.parse(new File(TEST_PROGRAM))
script.processData(msg)
}
private static void SetBody(){
def payload = [:]
msg.setBody(JsonOutput.toJson(payload))
}
private static void SetHeaders(){
// Parse URL
def urlComponents = [:]
(this.testURL =~ /([^?]*)+/)[0..-1].eachWithIndex{
it,i->
switch(i) {
case 0:
urlComponents [ 'CamelHttpUrl' ] = it [ 0 ];
break;
case 2:
urlComponents [ 'CamelHttpQuery' ] = it [ 0 ];
break;
}
}
// Set URL parameters
msg.setHeader('CamelHttpUrl',urlComponents.CamelHttpUrl)
msg.setHeader('CamelHttpQuery', urlComponents.CamelHttpQuery)
}
private static void Initialization(){
msg = new MessageImpl()
}
}

 

Conclusion

Given the fact that SAP CPI console doesn't support runtime testing of Groovy script, the Test Driven Development in the local IDE will be quite effective for CPI development.

 

The source code can be downloaded from here.

 
2 Comments
Labels in this area