How to create calibration script ?

This document explains to developer how to create SoapUI projects to be used as calibration scripts.

In the Project

We decided to store the soapUI file within the Maven project on the Forge. Base location is PROJECT_EAR/src/main/resources/soapui.

  1. To begin we need to create the directory “calibration_message”; it’s in this place where we will store our messages.
  2. After, we create two new directories in “calibration_message”, one directory for check valid messages : “[service_name]_valid_message”; and another to check invalid messages : “[service_name]_invalid_message”.
  3. We can add other directories in “calibration_message”, if we want create other tests in SoapUI calibration.
  4. In each directory, we store XML messages and the file properties. In the file properties we can find the validator name which allow to validate message. We give the name “validator.properties”; and in the file properties we write the validator name like this : “validator=[validator_name]”.
calibration_message
|    |
|    |__[service_name]_invalid_message
|    |        |
|    |        |__[service_name]_invalid_message.xml
|    |        |__validator.properties
|    |
|    |__[service_name]_valid_message
|    |        |
|    |        |__[service_name]_valid_message.xml
|    |        |__validator.properties
|    |
|    |__[something else ...]
|

In SoapUI

  1. First, for each calibration project in SoapUI we give a name, like this “[service_name]_calibration”.
  2. Next, we add in the SoapUI project the WSDL of our service.
  3. In project properties we add four properties :
    • endPoint : this is the service, usually we put in properties the instance name, for example ${#Project#domain}/Schemat….
    • domain : this is the instance name
    • calibration_file : this property is a boolean value, it allows to compare calibration result with a message file; so true if we have a file and false if we no have file to compare.
    • response_path_save : this property is used to get the path where the files are saved. If this property is empty, the calibration files are saved next to the Soapui project.
  _________________________________________________________________
  |           NAME               |             VALUE              |
  |______________________________|________________________________|
  | endPoint[ServiceName]        | ${#Project#domain}/CDAGene...  |
  |______________________________|________________________________|
  | domain                       | http://[service_instance]      |
  |______________________________|________________________________|
  | response_path_save           | /home/workspace/....           |
  |______________________________|________________________________|
  | calibration_file             | false                          |
  |______________________________|________________________________|

  1. Now we can create a new test suite, usually we use a name like this “[service_name]_calibration TestSuite”.
  2. In this test suite we add all tests cases, for example “[method_name]_valid_values TestCase” or “[method_name]_invalid_values TestCase”.
  3. It’s in these test cases where we test the validation; with messages and properties stored in project directory.
⊟-[service_name]_calibration TestSuite
    |
    ⊞-✓ about TestCase
    |
    ⊞-✓ getListOfValidators_valid_values TestCase
    |
    ⊟-✓ validateDocument_valid_values TestCase
      |
      ⊟-≣ Test Steps (3)
        |_ ★ retrieve_message
        |_ ★ message_response_test
        |_ □ VALID_VALUES (disable)

In SoapUI Script

  1. To begin, we add groovy script step with “retrieve_message” as name. This script allows to retrieve messages and validator property which are stored in the project directory.
  2. For a good execution, we must inform in testCase properties : - messageName : this is the message name, that we stored in project directory. - directoryName : this is the directory name, where we stored messages and validators.
  3. If we need to validate a base64 message, we can uncomment the last part
import org.apache.commons.codec.binary.Base64;
def project = testRunner.testCase.testSuite.project
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
// New variable, which take the response of the request

String rootProjectPath = testRunner.testCase.testSuite.project.path;
String projectName = rootProjectPath.substring(rootProjectPath.lastIndexOf('/')+1, rootProjectPath.length())
rootProjectPath = rootProjectPath.replace(projectName, '')


String directoryName = testRunner.testCase.getPropertyValue("directoryName")
String xmlName = testRunner.testCase.getPropertyValue("messageName")
String samplePath = rootProjectPath + "calibration_message/"+directoryName+"/" + xmlName;
String document = new File(samplePath).getText('UTF-8');

//get the Validator in propeties file
String propertiesValidatorPath = rootProjectPath + "calibration_message/"+directoryName+"/validator.properties";
Properties propValidator = new Properties()
File validatorFile = new File(propertiesValidatorPath)
validatorFile.withInputStream { propValidator.load(it) }
def runtimeString = 'validator'

def messageToVal = document
/*
//this part allows to convert message to Base64
byte[] messageBase64 = Base64.encodeBase64(document.getBytes());
messageToVal = new String(messageBase64)
*/
def ValidatorIheName = propValidator."$runtimeString"

testRunner.testCase.setPropertyValue("validator", ValidatorIheName)
testRunner.testCase.setPropertyValue("message", messageToVal)

  1. After, we add another groovy script step with “message_response_test” as name. In this script we will execute the test 3 times and we will compare the result with the results files which are stored in project directory. If the results are different, the test fail.
      def project = testRunner.testCase.testSuite.project
      def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
   
      String rootProjectPath = testRunner.testCase.testSuite.project.path;
      projectName = rootProjectPath.substring(rootProjectPath.lastIndexOf('/')+1, rootProjectPath.length());
      rootProjectPath = rootProjectPath.replace(projectName, "")
   
      def arg = testRunner.testCase.testSteps
      arg = arg.toString()
      def arg1 = arg.substring(0, arg.indexOf('TestRequestStep'))
      def requestName = arg1.substring(arg1.lastIndexOf(',')+1, arg1.lastIndexOf(':'))
      requestName = requestName.trim()
        if (requestName.contains("[")){
            	requestName = requestName.replace('[','');
            }
            
	  def testName = testRunner.testCase.testSuite.name
	  testName = testName.replace('TestSuite', '');
	  testName = testName.trim()

      def MessageResponse = ""
      def pathRoot = context.expand('${#Project#response_path_save}')
      def calibration = context.expand('${#Project#calibration_file}')
      def fileName = testRunner.testCase.name;
      fileName = fileName.replace(' TestCase', "_"+testName);
      pathRoot = pathRoot.trim()
      calibration = calibration.trim()
   
      if (calibration == null || calibration.isEmpty()){
      	calibration = 'false';
      	testRunner.testCase.testSuite.project.setPropertyValue("calibration_file", calibration)
      }
   
      log.info "Calibration file exist in this directory : " + calibration
   
      if (calibration == 'true'){
      	if (pathRoot != "" || pathRoot.contains('/') ){
      		pathRoot = pathRoot + "/"+fileName+".xml";
      		pathRoot = pathRoot.replace('//', '/');
      		try{
      			String document = new File(pathRoot).getText('UTF-8');
      			document = document.replace("<![CDATA[", "");
      			document = document.replace("]]>", "");
      			document = document.replace("&lt;", "<");
      			document = document.replace("&gt;", ">");
      			validationDate_part1 = document.indexOf('ValidationDate');
      			validationDate_part2 = document.indexOf('/ValidationDate');
      			valiDate = document.substring(validationDate_part1 +15, validationDate_part2 -1)
      			ValidationServiceVersion_part1 = document.indexOf('ValidationServiceVersion');
      			ValidationServiceVersion_part2 = document.indexOf('/ValidationServiceVersion');
      			valiVersion = document.substring(ValidationServiceVersion_part1 +25, ValidationServiceVersion_part2 -1)
      			validationTime_part1 = document.indexOf('ValidationTime');
      			validationTime_part2 = document.indexOf('/ValidationTime');
      			valiTime = document.substring(validationTime_part1 +15, validationTime_part2 -1)
      			document = document.replace(valiDate, 'Date');
      			document = document.replace(valiTime, 'Time');
      			document = document.replace(valiVersion, 'Version');
      			MessageResponse = document
   
      		}catch(Exception e){
      			assert false : "Don't find file in this path "
      		}
      	}else{
      		assert false : "You need to add the file path in project properties";
      	}
      }
   
      if (calibration == 'false'){
      	testRunner.runTestStepByName(requestName)
      	def Response = groovyUtils.getXmlHolder( requestName+"#Response" )
      	def resp = Response.getDomNode('//*:Envelope');
      	def messageResp = resp.toString();
      	messageResp = messageResp.replace("&lt;", "<");
      	messageResp = messageResp.replace("&gt;", ">");
      	validationDate_part1 = messageResp.indexOf('ValidationDate');
      	validationDate_part2 = messageResp.indexOf('/ValidationDate');			
      	valiDate = messageResp.substring(validationDate_part1 +15, validationDate_part2 -1)
      	ValidationServiceVersion_part1 = messageResp.indexOf('ValidationServiceVersion');
      	ValidationServiceVersion_part2 = messageResp.indexOf('/ValidationServiceVersion');			
      	valiVersion = messageResp.substring(ValidationServiceVersion_part1 +25, ValidationServiceVersion_part2 -1)
      	validationTime_part1 = messageResp.indexOf('ValidationTime');
      	validationTime_part2 = messageResp.indexOf('/ValidationTime');			
      	valiTime = messageResp.substring(validationTime_part1 +15, validationTime_part2 -1)
      	messageResp = messageResp.replace(valiDate, 'Date');
      	messageResp = messageResp.replace(valiTime, 'Time');
      	messageResp = messageResp.replace(valiVersion, 'Version');
   
      	MessageResponse = messageResp
   
      	if (pathRoot != "" || pathRoot.contains('/')){
      		try{
      			rootProjectPath = pathRoot + "/"+fileName+".xml";
      			rootProjectPath = rootProjectPath.replace('//', '/');
      			def res = new File(rootProjectPath)
      			res.write(MessageResponse, "UTF-8")
      		}catch(Exception e){
      			assert false : 'Bad save path !'
      		}
      	}else{
      		pathProject = rootProjectPath
      		rootProjectPath = rootProjectPath + "/"+fileName+".xml";
      		def res = new File(rootProjectPath)
      		res.write(MessageResponse, "UTF-8")
      		testRunner.testCase.testSuite.project.setPropertyValue("response_path_save", pathProject)
      	}
      }
   
      for (int i = 1; i <= 3; i++){
   
      	log.info "Test number : "+ i
   
           testRunner.runTestStepByName(requestName)
      	Response = groovyUtils.getXmlHolder( requestName+"#Response" )
      	resp = Response.getDomNode('//*:Envelope');
      	messageResp = resp.toString();
   
      	messageResp = messageResp.replace("&lt;", "<");
      	messageResp = messageResp.replace("&gt;", ">");
   
      	validationDate_part1 = messageResp.indexOf('ValidationDate');
      	validationDate_part2 = messageResp.indexOf('/ValidationDate');			
      	valiDate = messageResp.substring(validationDate_part1 +15, validationDate_part2 -1)
   
      	ValidationServiceVersion_part1 = messageResp.indexOf('ValidationServiceVersion');
      	ValidationServiceVersion_part2 = messageResp.indexOf('/ValidationServiceVersion');			
      	valiVersion = messageResp.substring(ValidationServiceVersion_part1 +25, ValidationServiceVersion_part2 -1)
   
      	validationTime_part1 = messageResp.indexOf('ValidationTime');
      	validationTime_part2 = messageResp.indexOf('/ValidationTime');			
      	valiTime = messageResp.substring(validationTime_part1 +15, validationTime_part2 -1)
   
      	messageResp = messageResp.replace(valiDate, 'Date');
      	messageResp = messageResp.replace(valiTime, 'Time');
      	messageResp = messageResp.replace(valiVersion, 'Version');
   
      	log.info messageResp
      	log.info MessageResponse
   
      	if (MessageResponse.contains(messageResp)){
      			assert true: "It's alway the same response"
      		}else{
      			assert false: "The response has changed"
      			}
      }
  1. So, in the next step, we add a SOAP request; it is in this step that we test our SOAP message:
  2. For the request endPoint we use this property : ${#Project#endPoint[service_name]}
 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.mb.validator.gazelle.ihe.net">
    <soapenv:Header/>
    <soapenv:Body>
       <ws:validateDocument><!--Optional:-->
 	         <document><![CDATA[${#TestCase#message}]]></document>
          <!--Optional:-->
          <validator>${#TestCase#validator}</validator>
       </ws:validateDocument>
    </soapenv:Body>
 </soapenv:Envelope>

  1. Finally, we add an assertion to check the result. To check the validation response, we use an assertion Script Assertion, This is a script which checks the results with xPaths. If the result must be PASSED; we expect a PASSED result in response and if the result should be FAILED, we do the same thing but with FAILED.
import com.eviware.soapui.support.XmlHolder
responsexmlholder = new XmlHolder(messageExchange.getResponseContentAsXml())
Cdataxml = responsexmlholder.getNodeValue("//*:DetailedResult")
Cdataxmlholder = new XmlHolder(Cdataxml)

resultXSD = Cdataxmlholder.getNodeValue("//DocumentValidXSD/Result")
if(resultXSD == "PASSED"){
	assert true;
}else{
	assert false : "Error(s) in the XSD Validation detailed Result";
}

resultDoc = Cdataxmlholder.getNodeValue("//DocumentWellFormed/Result")
if(resultDoc == "PASSED"){
	assert true;
}else{
	assert false : "Error(s) in the XML Validation Report";
}

resultValidation = Cdataxmlholder.getNodeValue("//ValidationResultsOverview/ValidationTestResult")
if(resultValidation == "PASSED"){
	assert true;
}else{
	assert false : "Error(s) in the Gazelle Objects Checker validator results";
}

Now we can run the calibration script.