I am using SoapUI Pro 4.5.2 to read data from spreadsheets, put them into Soap requests to my web service, and get responses back to write to a spreadsheet. It's working.
I have two fields in the input data pertinent to my question:
Middle name is defined as a string of 4 characters, and as minOccurs = 1 and maxOccurs = 1.
Postal extension code (the 4-digit number that is optional after the normal 5-digit code) is defined as a string of 4 digits. This field is optional, so it is marked as minOccurs=0 and maxOccurs=1.
When I use the SoapUI UI interface to send a request, this works fine; if there's no value for middle name, SoapUI generates an empty tag and sends it (I guess because of the minOccurs=1). If there's no value for PostalCode, it does not send any tag at all (I guess because of minOccurs=0).
When SoapUI reads data from an Excel spreadsheet, however, the response to the same data is an error indicating that the extended postal code value of '' is not legal, because it must be 4 digits. It appears that SoapUI generates an empty tag for the extended postal code when reading data from the spreadsheet, and sends it.
I found the "Remove Empty Content" option for SoapUI requests, default to false. I set it to true, and now get an error back from validation indicating that middle name is required but not found. I'm guessing that the remove empty content removed all the empty content (reasonable enough), and middle name has to be there, even if empty, because of the minOccurs=1.
Do I have any way out of this tail-chasing problem? I suppose I'm looking for something like a conditional for the output of the postal extension code, so I can eliminate it if it's empty, even if reading values from the spreadsheet.
I am also curious if there are XSD fixes, but I greatly prefer a fix that doesn't involve changing the XSD -- that becomes a political matter.
EDIT FOR DETAIL:
To put input into the request: I have used the SoapUI UI to choose "properties" from the input spreadsheet for each of the input fields; when that's done, one ends up with values in the request fields like:
${SpreadsheetInput#FrstNm}
Where SpreadsheetInput is the name of the datasource step reading the spreadsheet, and FrstNm is one of the properties. I do this with the "Get Data" option off the popup menu you get by right-clicking the request input field, but there may be other ways.
So first your problem:
Remember that internally to SoapUI almost everything is a string. Doing something like:
<postCode>${SpreadsheetInput#PostCode}</postCode>
in your SOAP request, assuming PostCode is either blank or does not exist outright, will expand to:
<postCode></postCode>
and SoapUI will even optimize it to:
</postCode>
Then your validation kicks in, which says you do not need to provide this element, but if you do, it had better be 4-characters long. Which the above fails.
The solution:
You need to pragmatically (meaning you will have to write Groovy code) create this node in your request. There are several ways to handle this. The quick and dirty is with a Groovy step, that goes something like:
def postCode = context.expand('${SpreadsheetInput#PostCode}').trim()
if (postCode != null && postCode != '')
testRunner.testCase.setpropertyValue("postCodeNode", "<postCode>" + postCode + "</postCode>")
else
testRunner.testCase.setpropertyValue("postCodeNode", "")
Then in your request replace the original:
<postCode>${SpreadsheetInput#PostCode}</postCode>
with just:
${#TestCase#postCodeNode}
Notice, the XML node elements are part of the SoapUI property! Again: everything in SoapUI is just a plain string.
If you want something more hard-core, have a look at
dynamically create elements in a SoapUI request. This is mine.
Related
I'm trying to create a simple stress test using JMeter. I have mostly GET requests and a couple POST requests. My main goal is to make this test as reusable as possible. I want to implement it in a way that the user would have to provide a CSV file with the following headers:
method;path;postBody
The values would look something like:
GET;/path/to/resource;''
POST;/path/to/resource;'{"key":"value","key":"value","key":"value"}'
Now POST (PUT, PATCH etc ..) bodies differ from one request to another. Providing ${postBody} to Body Data tab does not work "${postBody}" as well.
Is there a way to achieve this? Command line solutions are more than welcome as well.
EDIT: To clarify, I'm using the UI interface. When I input ${postBody} in the Body Data tab the UI complains. When switching from the Body Data tab to another one I get the following prompt:
Remove "'" around the request and it should work.
Regarding the warning you get, it is not an error, it is just that in JMeter those 2 tabs are exclusive:
Parameters tabs is for input of parameters in the form as name=value
Body data is for your kind of requirement
So can you test my hypothesis which is to remove the quote around the request in CSV file ?
If it still fails, please show the logs.
You can remain in Body Data tab,
Add after pathPost your optional query parameters for GET request:
${pathPost}?${getPramaters}
Don't worry about the ? it's just seperate path from parameters
Also consider changing variable name to path, more suitable because it can be POST.
In JSON , seperate between values while in CSV default is also ,
I suggest you can your CSV delimiter, In CSV Data Set Config Choose different Delimiter as ; and add your data in CSV accordingly (remove extra ' characters):
POST;/path/to/resource;{"key":"value","key":"value","key":"value"}
Notice: Allow quoted data keep default value False
Preamble: First off - I am a complete novice, and have zero clue what I am doing, apologies in advance.
Question:
I have working SOAP messages in SoapUI (regular flavour) that I have valid responses to. I am trying to build a set of test steps that can complete a transaction lifecycle for testing.
I only just figured out that Property Transfer could be used to take a response from call A to be used in call B.
I have the source declared correctly, and the Target correctly, With the default namespace info I have successfully transferred the complete response of call A into the target property. Now I just need to cut that down to one element only. I have tried all manner of things, but I seem to be getting [null] every time (except where I don't include the bit to choose one element at all, as noted above).
I just don't know what the format of the line that specifies the desired field should be. I know I have to have the name of the desired field in it, near the end, but beyond that I am randomly trying all sorts.
Okay, I have it solved, after many stupid trials and errors. For posterity and so I can reference it myself in future, this is what I got going:
Inside the soap message response body, there is a tag ns1 (which I am guessing is namespace 1).
Inside that is a section called salesInvoiceReturn.
Inside that is another section called salesInvoiceDetails.
Inside that is a field that I need is called salesInvoiceSalesTax.
So my line in the XPath Source section that works reads:
//ns1:salesInvoiceReturn/salesInvoiceDetails/salesInvoiceSalesTax
Pressing the Run button shows me it captures the correct value into the Custom Property I selected. I don't seem to need any code at all in the Target section.
I would like to read the exact value of a variable I use to pass through an HTTP Request. I first read in many values of variables using the CSV Data Set Config. For the username, it is in the form of an email address. So, I have a variable called "email" in the Data Set Config. In the actual HTTP Request, for "name", I call it "username". For the "Value" field for this same "username", I added a time() function to it like this so I would end up creating unique users in my tests:
${email}${__time()
When I view the "Request" in a View Results Tree, I can see my parameter is listed correctly:
username=email1%40email.com1390854377360
I do not care if this is correct in real world terms. I already know that is not a valid email. That is ok for now.
What I want to know is how can I log that email that I just created on the fly? I would like to not have to pull in the whole request every time also and then use some type of Regular Expression extractor. It just seems like there should be an easy way to do this.
I think there are 2 ways,
Beanshell Pre/Post processors : you can write custom code in which you can log all your variables in some custom log file
Simple data writer : you can configure it and check save url,save field names,save response data field checkboxes that will give you complete data but in that later postprocessing on result file is required to get all usernames (email in your case).
first approach is easier and allows you create your own logging format(easy to retrieve and use somewhere else).
second approach is somewhat tedious and requires post processing.
I need help understanding AJAX. I am going through the tutorial on W3C schools ( creating a button that opens text file on the server and displays the result in a div)
One part of the tutorials seems abstract to me, without sufficient explanation. I am sure its a pre-requisite that I have missed or not aware of, detailing below
To avoid getting a cached result in response to an XMLHttpRequest made to the server, the tutorial says one needs to ADD A UNIQUE ID to the URL parameter in the XMLHttp Open Method which has been done (in the tutorial) by adding a ?, another character (t) and an = after the file extention followed by joining a random number to the URL (using Math.random()). See code below.
A simple GET request would be like:
xmlhttp.open("GET","demo_get.asp,true); \\I can understand this
Unique ID added to URL
xmlhttp.open("GET","demo_get.asp?t=" + Math.random(),true); \\ I can't undersatnd this
'?' , 't' & a random number generator added to demo_get.asp - Why T, why not P Q R Z ?? Why "?" after .asp
Should the compiler not go bonkers and report an error if arbitary characters are added to the file location. How is the part of the URL after the file extention handled as in this case ?t= + Math.random()
This has been a case of much agony and frustration for the last 3 days cause I don't get which part of JS i have missed here, what do you call this concept and where can I read it ??
This apart, specifying message headers while sending data - What are HTTP headers and what do they mean. How do I decide what the parameters of the setRequestHeader() method shall be ?
Please help. Rest of Ajax is clear to me.
(I haven't read on the second part - the message headers. I have asked that query here to avoiding posting another question later, just in case it turns out to be as eluding and enigmatic as the UNIQUE ID concept - Apologies in case its a direct simple question I ought to read up myself)
Cache compares the requested URL with those present with it, if a unique id is added to the URL, it does not match and the browser treats it as a fresh GET request, which then is forwarded to the server. This is a standard way to bypass / disable browser caching.
Please refer this document for a better understanding of browser Caching.
See Page No 4, which explains the same thing as stated above.
http://www.f5.com/pdf/white-papers/browser-behavior-wp.pdf
Is there an existing library that would do this?
I want to be able to have code on the client side where the user chooses something, it makes a call to the server, and the server sends back "for this option, you need a have a text field called foo and a select field called bar with the following options, this one is selected, etc", and then the client side builds the next part of the form from that information. Or if they choose a different option, a different set of fields and values is returned from the server and populated on the screen. Also it might cascade so after the first selection we need a select field with some options, and then depending what they select on that select field the next field might be another select field or it might be a text input field.
Has anybody done anything like that? Is my best choice to have the AJAX call return some html that I just stuff into a div, or can I do it field by field and value by value?
If it matters, the back end is going to be written in Perl/MASON, and the front end will be using Javascript/JQuery/JQuery-UI.
I would use jquery and submit AJAX calls to whatever backend system you choose. Have this backend system compute the necessary changes and return the info as JSON. Let JQuery parse it for you and append the necessary form elements. However, it seems like under alot of use cases these decisions could be made on the client side without even talking to the server just as we pre validate form input before allowing posting to the server. I don't, however, have your requirements in front of me so I am sure there is a reason you want to get the info back from the server.
P.S. please do not return pure html from the back end to the client....ever.