Tuesday, 11 March 2008

XML automation - Part IV - Sending XML request

This week it is time to send the Web Service request and recieve a response...I have also added some Global parameters in a new sheet in my Excel file so that we can handle test environment properties and so on:



A also added a function for merging Dictionary objects which I use sometimes in my framework. It might not be the best code design approach but I think the concept works well, create a number of dictionaries, merge them together and pass one dictionary to the test case including all test parameters.
Function mergeDictionaries (objDIC1, objDIC2)
If IsObject(objDIC2) Then
allKeys = objDIC2.Keys
allItems = objDIC2.Items
For i = 0 To objDIC2.Count - 1 'Iterate through the array
If objDIC1.Exists(allKeys(i)) Then
'Value in objDIC2 is master
objDIC1.Item(allKeys(i)) = allItems(i)
Else
objDIC1.Add allKeys(i),allItems(i)
End If
Next
End If
Set mergeDictionaries = objDIC1
End Function
And finally the funcion for sending the request



Function sendXMLRequest (objDictionary)
Dim WinHttpReq
Const HTTPREQUEST_SETCREDENTIALS_FOR_SERVER = 0
Set WinHttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")
WinHttpReq.Open "POST", objDictionary.Item("PostURL"), False
WinHttpReq.setRequestHeader "Content-Type", "text/xml;charset=utf-8"
WinHttpReq.setRequestHeader "Accept", _
"text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
WinHttpReq.setRequestHeader "Content-Transfer-Encoding", "binary"
WinHttpReq.setRequestHeader "Connection", "keep-alive"
WinHttpReq.setRequestHeader "SOAPAction", objDictionary.Item("SOAPAction")
If objDictionary.Item("UserName") <> "" Then
WinHttpReq.SetCredentials objDictionary.Item("UserName"), objDictionary.Item("Password"), _
HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
End If
'Add WS header and foot if SOAP
If objDictionary.Item("RequestType") = "SOAP" Then
strHeader = "<?xml version=""1.0"" encoding=""utf-8""?>" &_
"<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""" &_
" xmlns:xsd=""http://www.w3.org/2001/XMLSchema""" &_
" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">" &_
"<soap:Body>"
strFoot = "</soap:Body></soap:Envelope>"
End If
WinHttpReq.Send(strHeader & objDictionary.Item("XMLRequest") & strFoot)
sendXMLRequest = WinHttpReq.ResponseText
End Function


So all together it should look like this:



intTestCaseID = 1
Set objMyTestParameters = getTestParametersIntoDictionary ("c:\MyTestData.xls", _
"TestCase", "TestCaseID", intTestCaseID)
Set objMyGlobalParameters = getTestParametersIntoDictionary ("c:\MyTestData.xls", _
"Global", "GlobalID", objMyTestParameters.Item("GlobalID"))
Set objMyTestParameters = mergeDictionaries (objMyGlobalParameters, objMyTestParameters)
objMyTestParameters.Item("XMLRequest") = getXMLTemplate (objMyTestParameters.Item("XMLTemplateFile"), _
objMyTestParameters.Item("XMLTemplate"))
objMyTestParameters.Item("XMLRequest") = setTestParametersInXMLRequest (objMyTestParameters)
objMyTestParameters.Item("XMLResponse") = sendXMLRequest (objMyTestParameters)
Msgbox objMyTestParameters.Item("XMLResponse")


Up next: Part V - Validate the response

8 comments:

Chandra said...

Hi,
I used your script to get the response from Webservice. I integrated with my DDT framework; it is working fine for one iteration, in second iteration giving error …..
ERROR: The system cannot locate the resource specified. (-2146697211)
At the below location….
‘ Select template and return
Set node = root.selectNodes("//" & strMyTemplate)

Please give me solution for this.
chandra.rao@enfs.com

Stefan said...

Hi,

What are your values for strXMLTemplateFile and strMyTemplate?

Regards

/Stefan

Stefan said...

Case closed.

The error was caused by wrong xml file path. I will try in future release include a "file exist" check to detect the error earlier.

Chris said...

What if the service is set via HTTPS?
How do you handle the credentials with or without a valid certificate?

Stefan said...

If the server certificate is valid the code should work as is using https (at least it does in my test enviroment). However I have one test environment where I get a certificate warning which I handle by adding this before the POST step:
Const SXH_SERVER_CERT_IGNORE_ALL_SERVER_ERRORS = 13056
WinHttpReq.Option(4) = SXH_SERVER_CERT_IGNORE_ALL_SERVER_ERRORS

Chris said...

Stefan: Thank you So much! I have no idea how long it took you to figure that out, but it seems to be working.
Genius, my friend!

-Chris

Sanjay Kumar said...

Hey, I tried your code... It gives me an error "A connection with the server could not be established" at the line : WinHttpReq.Send(strHeader & objDictionary.Item("XMLRequest") & strFoot)

Any Idea why it is....

Stefan said...

Did you try my example Web Service? If not are your URL correct?