Forum Discussion

ahart's avatar
ahart
Occasional Contributor
11 years ago

[Resolved] How can I modularize/do this better?

I have a bunch of web service operations that follow a similar pattern. A request is made to one operation to initiate an asynchronous extract. It returns immediately with a "requestId" assigned. Every operation, regardless of the data it is extracting, follows this same pattern, returns the same status info.

Then, we call another operation using that requestId as a parameter. We also can include a "chunkNumber" parameter, which is to identify which "chunk" of the results is to be returned. For example, if we have a total of 95 records extracted, and the chunkSize is 10, then there would be 10 "chunks" available for download, 1 through 10, with the last chunk containing only 5 records.

If we pass in a chunkNumber that is 0, then we do not return any of the results extracted, we simply return the status metadata about the request: whether it is pending, completed, inprogress, etc., the number of rows extracted if it is completed, the number of chunks available, the chunkSize, etc.

So, to setup a SoapUi test suite for one of these operations, I have the following test steps:

(1) RequestData
(2) Xfr Requestid from (1) to steps (3) and (8)
(3) GetData for chunk 0 for the request.
(4) Delay
(5) Conditional: Repeat until NOT PENDING or INPROGRESS (check the status returned in 3, go back to 3 if it is not completed or in error)
(6) Groovy Script: dumps out the status info and does a goto step (10) if there are no results
(7) "initChunkNumber" Properties Step: define "chunkNumber" property set to 1
(8) GetData for chunk ${"initChunkNumber#chunkNumber}
(9) Groovy Script: gets the chunkRequested in (8) and if < chunkCount increment the chunkNumber, update the property in (7), GOTO (8)
(10) Print out a "Finished Message"

So, I'm pretty sure that all of this could be condensed into a single Groovy Script test step. I would like to know how to do that, but I am having problems with how to iterate a test step varying some request parameter, all in script. Seems like it should be a common use case, so if someone can point me at an example, I'd appreciate it.

Ideally, instead of having to do this for every pair of request/get operations, I would like to be able to modularize this so that I could pass in a requestId, maybe pass in either a test step, or the operation to perform, and have this same functionality of hitting it until it is done, then iterating through all of the chunks to be retrieved.

Is that possible?

3 Replies

  • ahart's avatar
    ahart
    Occasional Contributor
    Not that I expect any replies, but I thought I would share my progress on this in case it might help someone else:

    I copied those ten steps described previously to a separate test case. I then added two test case level properties, one to define the operation to be invoked for the extract and one for the fetch.

    Initially, I tried expanding these properties in the requests. However, I ran into a peculiarity: anywhere else in a groovy script where I used an XmlHolder and tried modifying the requests I would then get an error when the "$" character was encountered. Consequently, I was forced to eliminate all property expansions and do everything with Groovy scripts.

    I do wonder if this is a known limitation: when you have properties in a request, e.g., ${myProperty}, you will always encounter this error, or is there something I'm not doing correctly?

    So, now I have a startup script that uses DOM to delete all existing nodes under the <body> tag of the request and then rebuild it using the operations specified in the properties.

    The original test case now contains a "Run TestCase" step where it sets up the properties, and then runs the new test case to initiate the extract, poll it until done, find out how many chunks are available, and then iterate through them fetching all chunks.

    One other problem is that my original "Schema Compliance" assertions are failing because it expects the response
    for the operation I used when I create them initially. So, I disabled them, and next I will have to see if they can be dynamically created when the module is invoked with a particular set of operations.

    But, the goal of not replicating all these steps for every pair of extract/fetch operations has been accomplished. All I have to do is add similar "Run TestCase" steps for each web service operation that follows this pattern.
  • ahart's avatar
    ahart
    Occasional Contributor
    Another Followup:

    But, inexplicably (to me), the same SoapUi tests will NOT work properly when I try to incorporate them into a JUnit test, so they work in the SoapUi, but do not work when I try to run them using SoapUiTestRunner. Which pretty much scuttles the whole idea of doing them this way and using them in integrated test cases.
  • PaulDonny's avatar
    PaulDonny
    Regular Contributor
    Wow.

    I have actually accomplished a similar task utilizing several different methods. One of my favorite methods was to set up example test steps that was accessed from the groovy script, the request and assertions being placed into a controller request and then storing the results. This allows for easy maintenance work of your requests and helps to keep xml out of your code.


    There is a lot of options for what you are attempting to accomplish but it depends greatly on how much time and effort you want to put into this project and whether or not it is worth it in the end. Understanding what you are attempting to accomplish was quite difficult but if you have any specific questions to SoapUI and groovy development (IE, How could I use a controller script to run and control the flow of my test cases) than you will likely get a much better, quicker answer.