How can I validate a SOAP response against an XSD file that defines the response schema. the web service I'm calling has an XMLDocument as input and output, so can't use WSDL for response schema validation.
I case you still need this (valid for SOAP UI version 2.5.1):
File, Preferences, Editor Setting, Validate Response.
Use script assertion:
def project = messageExchange.modelItem.testStep.testCase.testSuite.project
def wsdlcontext = project.getInterfaceAt(0).getDefinitionContext()
def validator = new com.eviware.soapui.impl.wsdl.support.wsdl.WsdlValidator(wsdlcontext);
def errors = validator.assertRequest(messageExchange, false)
assert errors.length < 1
You can use the groovy script for validation the response against the xsd file.
Here is the way to validate
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;
import javax.xml.XMLConstants;
//Read your xsd file and get the conten into a variable like below.
def xsdContent = "Some Schema Standard";
//Take the response into another variable that you have to validate.
def actualXMLResponse = "Actual XML Response ";
//create a SchemaFactory object
def factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
//Create a given schema object with help of factory
def schema = factory.newSchema(new StreamSource(new StringReader(xsdContent ));
//Create a validator
def validator = schema.newValidator();
//now validate the actual response against the given schema
try {
validator.validate(new StreamSource(new StringReader(actualXMLResponse )));
} catch(Exception e) {
log.info (e);
assert false;
}
I hope this will help you :-)
This not worked me caused try not working
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;
import javax.xml.XMLConstants;
//Read your xsd file and get the conten into a variable like below.
// trim - XSD SCHEME no spaces
def xsdscheme = context.expand('${Properties-XSD_Scheme_Black_and_White#XSDSchemeWhite}')
def xsdscheme2 = xsdscheme.replace(' ', '')
xsdscheme2 = xsdscheme2.replaceAll("[\n\r]", "");
log.info "RES2 TRIMED " + xsdscheme2
def xsdContent = xsdscheme2;
//Take the response into another variable that you have to validate.
Res = context.expand('${#TestCase#WhiteListDecoded}');
def Res2 = Res.replace(' ', '')
Res2 = Res2.replaceAll("[\n\r]", "");
log.info "RES2 TRIMED " + Res2
def actualXMLResponse = Res2
//create a SchemaFactory object
def factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
//Create a given schema object with help of factory
def schema = factory.newSchema(new StreamSource(new StringReader(xsdContent ));
//Create a validator
def validator = schema.newValidator();
//now validate the actual response against the given schema
try {
validator.validate(new StreamSource(new StringReader(actualXMLResponse )));
} catch(Exception e) {
log.info (e);
assert false;
}
Related
I have a piece a code as below. This is loading data from JMX to monitoring tool. Unfortunately, there are some 'NaN' values, which are not read properly by monitoring tool, and this interrupts transfer. My intention is to replace 'on fly' values 'NaN' to 'null'.
Has anybody any idea how to do it?
BR
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import java.security.PrivilegedAction;
def hostName = hostProps.get("system.hostname")
def jmxPort = "10002"
def query = "Hadoop:service=hiveserver2,name=hiveserver2"
def metricsURL = "http://${hostName}:${jmxPort}/jmx?qry=${query}"
def ad = true
public class FetchMetrics implements PrivilegedAction {
def url;
public FetchMetrics(String url) {
this.url = url;
}
public Object run() {
URL urlObject = new URL(url);
def con = (HttpURLConnection) urlObject.openConnection();
return con.getInputStream();
}
}
lc = new LoginContext("Client");
lc.login();
Subject subject = lc.getSubject();
PrivilegedAction action = new FetchMetrics(metricsURL);
def metrics = Subject.doAsPrivileged(subject, action, null);
def jsonSlurper = new JsonSlurper()
def deviceMetrics = jsonSlurper.parse(metrics)
// Hit out endpoint and get our metrics
//deviceMetrics = jsonSlurper.parse(new URL(metricsURL))
deviceMetrics.'beans'[0].each {
println it
}
return 0
simplest way to use LAX json slurper, however it will parse NaN as a string "NaN"...
import groovy.json.JsonSlurper
import groovy.json.JsonParserType
import groovy.json.JsonBuilder
def jsonSlurper = new JsonSlurper().setType( JsonParserType.LAX )
def json = jsonSlurper.parseText('{ "a":111, "b": NaN}')
println new JsonBuilder(json).toPrettyString()
prints
{
"a": 111,
"b": "NaN"
}
I am trying to retrieve a number of flightids from an xml and place them in an array but I keep getting no data displayed. It doesn't seem to find 'flights' but I am not sure why, is there anything wrong with the code below?
import groovy.xml.XmlUtil
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def response = context.expand( '${SOAP Request#Response}' )
def parsedxml = new XmlSlurper().parseText(response)
def tests= parsedxml.'**'.findAll { it.name() == 'b:TestId'}
log.info tests
//Get the rate plan codes
def testId = { option ->
def res = option.'**'.findAll {it.name() == 'b:TestId'}
if (res) return option.TestId.text()
null
}
def testIdArray = []
tests.each { if (testId(it)) testIdArray << testId(it) }
for (int i = 0; i < testIdArray.size(); i++) {
log.error "TestIds: " + testIdArray[i]
}
log.warn testIdArray.size()
Below is the xml:
<s:Envelope xxx="xxx" xxx="xxx">
<s:Header>
<a:Action s:mustUnderstand="1">xxx</a:Action>
</s:Header>
<s:Body>
<XML1 xmlns="xxx">
<XML2 xmlns:b="xxx" xmlns:i="xxx">
<XML3>
<b:TestId>000000</b:TestId>
</XML3>
<XML3>
<b:TestId>000000</b:TestId>
</XML3>
</XML2>
</XML1>
</s:Body>
</s:Envelope>
Pass the xml string response to below response variable
def xml = new XmlSlurper().parseText(response)
def getFlightIds = { type = '' ->
type ? xml.'**'.findAll { it.name() == type }.collect { it.FlightId.text() } : xml.'**'.findAll {it.FlightId.text()}
}
//Get the respective flight ids
//Use the desired one as you have mentioned none
def inFlightIds = getFlightIds('InboundFlightInformation')
def outFlightIds = getFlightIds('OutboundFlightInformation')
def allFlightIds = getFlightIds()
log.info "Inbound flight ids: ${inFlightIds}"
log.info "Outbound flight ids: ${outFlightIds}"
log.info "All flight ids: ${allFlightIds}"
You can quickly try online Demo
it.name() in your case it is a NodeChild
so, it.name() returns just a name without prefix. it means you should compare it to FlightId (without b: )
if you want to check a namespace (linked to a prefix) then your lookup must be like this:
def flights = parsedxml.'**'.findAll { it.name() == 'FlightId' && it.namespaceURI()=='xxx' }
How to save the test case properties if any of the assertions fail within this groovy script step?
Below is example code:
// define properties required for the script to run.
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def dataFolder = groovyUtils.projectPath
def vTIDAPI = testRunner.testCase.getPropertyValue("vTIDAPI")
def vTIDDB = testRunner.testCase.getPropertyValue("vTIDDB")
def RefAPI = testRunner.testCase.getPropertyValue("RefAPI")
def RefDB = testRunner.testCase.getPropertyValue("RefDB")
def AmountAPI = testRunner.testCase.getPropertyValue("AmountAPI")
def AmountDB = testRunner.testCase.getPropertyValue("AmountDB")
def CurrencyAPI = testRunner.testCase.getPropertyValue("CurrencyAPI")
def CurrencyDB = testRunner.testCase.getPropertyValue("CurrencyDB")
assert vTIDAPI == vTIDDB
assert RefAPI == RefDB
assert AmountAPI == AmountDB
assert CurrencyAPI == CurrencyDB
Here is the Groovy Script which does compare the given set of properties and on any of the assertion failure, writes the properties to a given file.
You need to change the value of property file name to be stored for variable propFileName variable.
Add more properties to be asserted in the form of key:value pairs format if needed
//Provide / edit the file name to store properties
def propFileName = '/tmp/testCase.properties'
//Define the properties to be matched or asserted ; add more properties if needed
def props = [ 'vTIDAPI':'vTIDDB', 'RefAPI':'RefDB', 'AmountAPI': 'AmountDB', 'CurrencyAPI': 'CurrencyDB']
/**
* Do not edit beyond this point
*/
def writeTestCasePropertiesToFile = {
//Get the test case properties as Properties object
def properties = context.testCase.properties.keySet().inject([:]){map, key -> map[key] = context.testCase.getPropertyValue(key); map as Properties}
log.info properties
assert properties instanceof Properties
properties?.store(new File(propFileName).newWriter(), null)
}
def myAssert = { arg1, arg2 ->
context.testCase.getPropertyValue(arg1) == context.testCase.getPropertyValue(arg2) ? null : "${arg1} value does not match with ${arg2}"
}
def failureMessage = new StringBuffer()
props.collect{ null == myAssert(it.key, it.value) ?: failureMessage.append(myAssert(it.key, it.value)).append('\n')}
if(failureMessage.toString()) {
log.error "Assertion failures:\n ${failureMessage.toString()}"
writeTestCasePropertiesToFile()
throw new Error(failureMessage.toString())
} else {
log.info 'Assertions passed'
}
EDIT: Based on the OP comments
Replace def myAssert = ... with below code fragment.
def myAssert = { arg1, arg2 ->
def actual = context.testCase.getPropertyValue(arg1)
def expected = context.testCase.getPropertyValue(arg2)
actual == expected ? null : "${arg1} value does not match with ${arg2} - api ${actual} vs db ${expected}"
}
I'm working on a project with Soapui when I send the request I have this error unexpected end of file here is my code:
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.IOException
import java.util.Date
import java.io.*
import org.apache.poi.hssf.usermodel.HSSFCell
import org.apache.poi.hssf.usermodel.HSSFCellStyle
import org.apache.poi.hssf.usermodel.HSSFDataFormat
import org.apache.poi.hssf.usermodel.HSSFRow
import org.apache.poi.hssf.usermodel.HSSFSheet
import org.apache.poi.hssf.usermodel.HSSFWorkbook
import org.apache.poi.hssf.util.HSSFColor
import org.apache.poi.xssf.usermodel.*
import com.opencsv.CSVReader
import com.opencsv.CSVWriter
CSVReader reader = new CSVReader(new FileReader("C:\\Users\\******\\Desktop\\Groovy Script test\\data.csv"))
CSVWriter writer = new CSVWriter(new FileWriter("C:\\Users\\******\\Desktop\\Groovy Script test\\Output.csv"))
//get property
propTestStep = context.testCase.getTestStepByName("PRO-Number-property") // get the Property step (ours is named "property-loop")
//loop
String [] nextLine
while ((nextLine = reader.readNext()) != null ) {
writer.writeNext(nextLine)
log.info ("The value on the excel sheet is data " + nextLine[5])
//assign value of pro
propTestStep.setPropertyValue("PRO Number", (nextLine[2])) //set the value of Pro" property equal to Excel's column B ( getCell(1) )
//Get node of the response
testRunner.runTestStepByName("GetByProNumber") //we're going to run the Soap Request after each iteration of the Excel's rows.
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
if( "GetByProNumber#Response" == null){
log.info("Null try again")
} else {
def holder = groovyUtils.getXmlHolder("GetByProNumber#Response")
log.info (holder)
holder.namespaces["ns"] = "http://www.SaiaSecure.com/WebService/Shipment"
if (holder != null){
writer.writeNext("${holder.getNodeValue('//ns:Activity')}", nextLine[0])
log.info("Node Response:${holder.getNodeValue('//ns:Activity')}")
} else {
log.info("Null try again")
}
}
}// end of while loop
//writer.close()
writer.close()
log.info ("Done" )
Please I want to know what I'm doing wrong Thanks for any help I'm working on a project with Soapui when I send the request I have this error unexpected end of file here is my code:
Oh ok, your comment is very useful to identify the issue.
That appears to be a trivial error.
Change your code snippet from:
def holder = groovyUtils.getXmlHolder("GetByProNumber#Response")
To:
//Get the specified test step response and assign to variable
def stepResponse = context.expand('${GetByProNumber#Response}')
//Now pass the above variable to xmlholder to create the object
def holder = groovyUtils.getXmlHolder(stepResponse)
I am getting the above error in the groovy script in boomi Please help me!! Below is the code.I am trying to format to xml. Data process is throwing this error.
import java.util.Properties;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import com.boomi.execution.ExecutionUtil;
import java.io.BufferedReader;
import java.io.InputStreamReader;
// Retrieve a handle to the Logger
logger = ExecutionUtil.getBaseLogger();
InputStream io = dataContext.getStream(0);
Properties props = dataContext.getProperties(0);
BufferedReader br = new BufferedReader(new InputStreamReader(io));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
def text = sb.toString();
text = text.replaceAll('<', '')
text = text.replaceAll('>', '')
def xmlStream = new XmlParser().parseText(text);
def data = xmlStream.data;
def result = "<records>"
for (child in data) {
def stringWriter = new StringWriter()
new XmlNodePrinter(new PrintWriter(stringWriter)).print(child)
result = result + stringWriter.toString();
}
result = result + "</records>"
def childIO = new ByteArrayInputStream(result.getBytes());
dataContext.storeStream(childIO, props);
Unless the input data with profile is given in this question, it will be difficult to answer it. However from the code, it seems that an extra parent node is being created to the input XML. This can easily be achieved by a Message component in Boomi. Use a message shape and input the following: <records>{1}</records> and form the parameters option in Message shape, use Current Data. This will give the same output for all your documents which you are trying to achieve from code. In case if it does not fulfill your requirements please provide more details like input profile with fields and expected output.