Forum Discussion
Still not clear what you are looking for exactly from the post.
This may just be helpful information for better understanding of response headers.
http://www.soapui.org/testing-dojo/best-practices/understanding-rest-headers-and-parameters.html
What I understnad for the script you posted is that
- You are getting http headers, not the coockie
Here is script assertion(for your HTTP Request 1 step) instead of additional groovy script for the same (as per my understanding)
- Define a custom property EXPECTED_COOKIE_SIZE and its value at test case level
//Assuming a custom property EXPECTED_COOKIE_SIZE defined with needed value at test case level def expectedCookieSize = context.testCase.properties['EXPECTED_COOKIE_SIZE'].value as int def cookie if (messageExchange.responseHeaders.containsKey('Cookie')) { log.info "Found Cookie in the response headers" cookie = messageExchange.responseHeaders['Cookie'].value log.info "Cookie value : ${cookie}, and its size is : ${cookie.size()}" assert expectedCookieSize == cookie.size, "Cookie size mismatch" } else { log.warn "Not Found Cookie in the response headers" }
The second question "I expect to do the second Request to Get some json data, but it is never successful." not clear, what do you mean by it? Could please add more details?
- nmrao10 years agoChampion Level 3
Here is slightly improved answer based on the fact that -
- to match data of any given header both in request and response
- provide name of the header you wanted to assert i.e., is response header compared with request
- Say a test case custom property HEADER_NAME and value as 'Cookie' in this case (can be any header in fact)
/** * checks if given HEADER_NAME in request vs response * also its value and size * Assumes, a custom test case property HEADER_NAME is defined with * appropriate value lie Content-Type, Cookie etc., any thing for that matter
* This can be used as Script Assertion **/ def key=context.testCase.properties['HEADER_NAME'].value def isHeaderInRequest = messageExchange.requestHeaders.containsKey(key) def isHeaderInResponse = messageExchange.responseHeaders.containsKey(key) assert isHeaderInRequest == isHeaderInResponse, "Header ${key} cound not found either in request or response" def headerValueInRequest = messageExchange.requestHeaders[key].value def headerValueInResponse = messageExchange.responseHeaders[key].value printLog("Request", key, headerValueInRequest) printLog("Response", key, headerValueInResponse) assert headerValueInRequest == headerValueInResponse, "${key} value mismatch between request and response" assert headerValueInRequest.size() == headerValueInResponse.size(), "${key} value size mismatch" def printLog = { message, key, value -> log.info "${message} - Header - \n${key} : ${value} \nsize : ${value.size()}" }Hope this is what you are looking for in the first place.
- swee10 years agoNew Contributor
Hi Rao
Before practicing your code, I would say appreciate very much.
I feel I need to give you more details about my questions.
My task is to use soapUI to test the API which is already deployed to test box. Before using soapUI, I have tried login from web browser, no matter FF or Chrome and open web development tool (click F12 as we known). From the network tab showing, I can see the first method is login, which is Post method, then lots of Get methods and another Post method which is logevent. From that Post method, I can see the token Id.
I thought I can use soapUI to do the same things. Am I right?
I recon, the first step of request is login to the box, which should be a Post method. Yes it seems works and got http headers:
Date Wed, 18 Nov 2015 20:08:32 GMT
Transfer-Encoding chunked
#status# HTTP/1.1 200 OK
Expires Thu, 01 Jan 1970 00:00:00 GMT
Keep-Alive timeout=10
Content-Type text/html;charset=UTF-8
Connection Keep-Alive
X-Powered-By Servlet 2.5; JBoss-5.0/JBossWeb-2.1
X-Powered-By JSF/1.2
Pragma no-cache
Cache-Control no-cache
Cache-Control no-store
But the size is quite different from what I got from web browser development tool Network tab showings. Why?
This is my first question.
Then I tried using groovy scripts and hope to get more details of Cookies but no luck so far.
After the first step of login, I expect to use the soapUI request with Get method to test the API - to get the bundle of json data which the API should return. It works on web browser of course. But I am stuck on soapUI...
I am wondering how to fetch the useful parameter from the first step and then HOW to re-use them to the following requests to test the API.
This is my second question.
Hope you can help?
Thank you very much.
Cheers
swee
- nmrao10 years agoChampion Level 3I will later go thru your reply and come back.
- nmrao10 years agoChampion Level 3
In case, if there are multiple headers to be verified unlike earlier script(handle single header), here you go the modified script.
Just in case if some one is interested.
/** * checks if given HEADER_NAMES in request vs response * also its value and size * Assumes, a custom test case property HEADER_NAMES is defined with * appropriate value(s) separated by comma like Content-Type, Cookie etc., any thing for that matter * This needs to used as Script Assertion **/ import groovy.transform.Canonical @Canonical class HeaderVerificationResult { String name def requestValue def responseValue def failureMessage = new StringBuilder() boolean result = false } Map<String, HeaderVerificationResult> verificationMap = [:] def keysString = context.testCase.properties['HEADER_NAMES'].value if (keysString) { keysString.split(',').each { key -> verificationMap[key] = buildModel(key) } } else { throw new Error('No header names provided') } def testResultFail = verificationMap.findAll{ it.value.result == false } def errorMessage = StringBuilder() testResultFail.each { log.info "Verifying Header : ${it.key}" errorMessage.append("\n${it.value.toString()}") log.info "Failure${it.value.failureMessage.toString()}" } if (errorMessage) { throw new Error(errorMessage.toString())} def buildModel = { key -> def currentResultObject = new HeaderVerificationResult(name: key) addMessageIfNotContainsHeader(messageExchange.requestHeaders.containsKey(key), 'Request', currentResultObject) addMessageIfNotContainsHeader(messageExchange.responseHeaders.containsKey(key), 'Response', currentResultObject) if (currentResultObject.requestValue != currentResultObject.requestValue) { currentResultObject.failureMessage.append('\nValue mismatch') } if (currentResultObject.requestValue.size() != currentResultObject.requestValue..size()) { currentResultObject.failureMessage.append('\nValue size mismatch') } if (!currentResultObject.failureMessage) ) { currentResultObject.result = true } currentResultObject } def addMessageIfNotContainsHeader = { value, message, object -> object.failureMessage if (!value) { object.failureMessage.append("\n${message} does not contain header") } else { if ('Request' == message) { object.requestValue = messageExchange.requestHeaders[object.name].value } else if ('Response' == message) { object.responseValue = messageExchange.responseHeaders[object.name].value } } }
- nmrao10 years agoChampion Level 3
There was little confusion from the link mentioned in the above reply.
So, there could be issues with script posted earlier in order to reading cookies from the response to verify its size. Appologies for the confusion caused.
Later gone thru couple of link as follows
https://siking.wordpress.com/2013/07/25/soapui-cookie-management/
https://en.wikipedia.org/wiki/HTTP_cookie
After looking at the wiki, come to know that when user get a response from the server, it will have cookies as header with name 'Set-Cookie'. So, these cookies needs to be set by the client for the following request. I believe, this what swee was mentioning in the initial post as 2nd step.
Tried the following in the soapUI:
- Have a HTTP request
- Hit to google.com
- The respone header shown as below:
HTTP/1.1 200 OK Date: Thu, 19 Nov 2015 08:21:36 GMT Expires: -1 Cache-Control: private, max-age=0 Content-Type: text/html; charset=ISO-8859-1 P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info." Server: gws X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN Set-Cookie: PREF=ID=1111111111111111:FF=0:TM=1447921296:LM=1447921296:V=1:S=Z6HUcCDRd0wdBvtq; expires=Thu, 31-Dec-2015 16:02:17 GMT; path=/; domain=.google.co.in Set-Cookie: NID=73=C-LEZiKs8PR0L1TsHIS-3Yi6BO1QV-ikRI34lJ8uutq6nxO4wenAPayYtkx9zlHHtajeGZiY6yVSgMZB4OlZ6417yjzf_gEx3ZsXJ4v389k65UVCm7YSYAWs8X4HGgEXaUGS11ZFrwA9oo51ELZNs5xJuWZ6PhbbLjfih-8; expires=Fri, 20-May-2016 08:21:36 GMT; path=/; domain=.google.co.in; HttpOnly Accept-Ranges: none Vary: Accept-Encoding Transfer-Encoding: chunked
This is how one could read those cookies:
if (messageExchange.responseHeaders.containsKey('Set-Cookie')) { log.info "Found Cookie in the response headers" def cookiez = messageExchange.responseHeaders['Set-Cookie'].value cookiez.each { cookies -> log.info cookies.toString() } } else { log.warn "Not Found Cookie in the response headers" }
output as follows:
Thu Nov 19 14:38:55 IST 2015:INFO:Found Cookie in the response headers Thu Nov 19 14:38:55 IST 2015:INFO:PREF=ID=1111111111111111:FF=0:TM=1447921296:LM=1447921296:V=1:S=Z6HUcCDRd0wdBvtq; expires=Thu, 31-Dec-2015 16:02:17 GMT; path=/; domain=.google.co.in Thu Nov 19 14:38:55 IST 2015:INFO:NID=73=C-LEZiKs8PR0L1TsHIS-3Yi6BO1QV-ikRI34lJ8uutq6nxO4wenAPayYtkx9zlHHtajeGZiY6yVSgMZB4OlZ6417yjzf_gEx3ZsXJ4v389k65UVCm7YSYAWs8X4HGgEXaUGS11ZFrwA9oo51ELZNs5xJuWZ6PhbbLjfih-8; expires=Fri, 20-May-2016 08:21:36 GMT; path=/; domain=.google.co.in; HttpOnly
So the above is half part and below one also sets cookies to next request.
//This script asstion reads the http response,
//collect the cookies for the next http request
//Provide the next step name where you want to set the Cookie to the request or
//Use property expansion for below def nextStepName = 'step2' def nextRequest = context.testCase.testSteps[nextStepName].httpRequest def headers = nextRequest.requestHeaders if (messageExchange.responseHeaders.containsKey('Set-Cookie')) { log.info "Found Cookie in the response headers" def cookiez = messageExchange.responseHeaders['Set-Cookie'].value def list = [] cookiez.each { cookies -> //def (name, value) = cookies.toString().split('=',2) list.add(cookies.toString()) } headers['Cookie'] = list } else { log.warn "Not Found Cookie in the response headers" } nextRequest.requestHeaders = headersAnd I am able to send the cookies from previous respone.
Hope this may be helpful.
Related Content
Recent Discussions
- 8 days ago