Now that i am learning + working on some really cool technology stuff, i thought of sharing one of the best hacks i have written in soapUI Open Source version.

People who have evaluated the soapUI Pro version (Trial or Licensed), must have liked few of the features which are handily + heavily used. One such feature which is exhaustively used is “DataSource” & “DataLoop”. Very simple concept (just looping) and comes very handy when you have to perform the test on the set of data values stored in specific location (say XLS, Text file).

Here is how you can also do it without procuring soapUI Pro license. Yes, you read it right “without procuring soapUI Pro License”. i.e., using few set of Groovy script lines.
In your testcase, add a Groovy Script teststep and name it as “Groovy Script – DataSource”. Paste the following code into newly created teststep.

/*
@Author : Pradeep Bishnoi
@Description : Data Source to read .txt file and pass the value to corresponding property.
@GroovyTestStepName : "Groovy Script - DataSource"
*/

import com.eviware.soapui.support.XmlHolder
def myTestCase = context.testCase
def counter,next,previous,size
File tickerEnumFile = new File("D:/Input.txt") //make sure input.txt file already exists and contains different set of values sepearted by new line (CR).
List lines = tickerEnumFile.readLines()
size = lines.size.toInteger()
propTestStep = myTestCase.getTestStepByName("Property - Looper") // get the Property TestStep
propTestStep.setPropertyValue("Total", size.toString())
counter = propTestStep.getPropertyValue("Count").toString()
counter= counter.toInteger()
next = (counter > size-2? 0: counter+1)
tempValue = lines[counter]
propTestStep.setPropertyValue("Value", tempValue)
propTestStep.setPropertyValue("Count", next.toString())
next++
log.info "Reading line : ${(counter+1)} / $lines.size"
propTestStep.setPropertyValue("Next", next.toString())
log.info "Value '$tempValue' -- updated in $propTestStep.name"
if (counter == size-1)
{
propTestStep.setPropertyValue("StopLoop", "T")
log.info "Setting the stoploop property now..."
}
else if (counter==0)
{
def runner = new com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner(testRunner.testCase, null)
propTestStep.setPropertyValue("StopLoop", "F")
}
else
{
propTestStep.setPropertyValue("StopLoop", "F")
}

Now create a Property teststep and name it as “Property – Looper”. Add few user-defined properties with following name : “Total” , “Value” , “Count” , “Next” , “StopLoop”.

Then add the TestRequest Step, in which you want to pass the data read from the data source. Let’s name it as “GEC_Symbol_Enumeration” or anything. Now open your request and the tag which you want to parameterize and put the property expansion code i.e., ${Property- Looper#Value}

And lastly, add another Groovy Script teststep and name it as “Groovy Script – Data Loop”. Also, paste the following code into newly created teststep.

/*</pre>
@Author : Pradeep Bishnoi
@Description : Data Source Looper responsible for looping a specific teststep.
@GroovyTestStepName : "Groovy Script - Data Loop"
*/
def myTestCase = context.testCase

def runner
propTestStep = myTestCase.getTestStepByName("Property - Looper") // get the Property TestStep
endLoop = propTestStep.getPropertyValue("StopLoop").toString()

if (endLoop.toString() == "T" || endLoop.toString()=="True" || endLoop.toString()=="true")
{
 log.info ("Exit Groovy Data Source Looper")
 assert true
}
else
{
 testRunner.gotoStepByName("Groovy Script - DataSource") //setStartStep
}

And we are done. Now you can execute your testcase and see it will loop across the specified testrequest step with input values read from the provided input file.

Refer this snapshot for quick understanding and issue resolution.

I hope this will help.

NOTE : This code might look dirty & complex. Also, you will find dependencies over the variable/teststep names to be used. Well if you can cleanse it, then please share. This will help other :)

Till next blog enjoy looping & happy sharing!!

About these ads
Comments
  1. Prashanth says:

    Hello Pradeep,

    This is Prashanth and I have been following your blogs for quite sometime and it has been a great help for me.

    I had a small clarification from you regarading adding assertions when we parametrize data using datasource step/datasource loop.

    The scenario goes like this:

    1) We have created a data sheet which has multiple values for a given “From Currency tag (We have maintained only one request wherein the below values are parameterized using datasource)

    a. INR(Valid currency)

    b. XYZ(Invalid alphabetic currency

    c. 123 (Invalid Numeric currency)

    2) Now, these values get called by a datasource and gets looped one by one into the XML Request.

    3) Now, we intend to add separate Assertions” for each of the above data (step1); like

    a. INR(Valid currency): Assertions should be “Success”

    b. XYZ(Invalid alphabetic currency : Assertions should be “Fail

    c. 123 (Invalid Numeric currency)”; Assertions should be “Fail”

    Could you please let us know as to how we could achieve this

    • Hi Prashanth,

      For you case, the first thing which floats over my mind is include another column in the input XLS and write a small groovy script between the datasource. This groovy script will be responsible for enabling and disabling the required set of assertion in the test request step.

      I hope this will be of some help, even this month long delay.

      Best Regards
      {Pradeep Bishnoi}

  2. Vasanth says:

    Hello Pradeep,
    This is vasanth. Could you please send me the .txt file, so that i can get a clear idea to how to define the data. My email id is vasanthtce@gmail.com

  3. Wil says:

    Dear Pradeep,

    Can I also get a copy of your .txt, which was used with this example. I am currently working with SOAPUI and I would like to trying to simulate your example. I am running into confusion with your “Property” definitions (Total, value, count..) are those properties use for your looping or are they the test data that will be enter into my soapui message. my email is carbonbase_lifeform@hotmail.com. your help will be greatly appreciated.

  4. george says:

    Hi Pradeep,

    Can you send me a copy of the input.txt file as well, its not clear what the format should be.
    Please send to dqtester@gmail.com

  5. Randolph says:

    Question for input.txt – what if I have 2 inputs (1 is for username, 1 is for password) that I want to add to property value? How would I update the your existing code to get the password value in the next line?

    I’m trying to understand what this code does?

    next = (counter > size-2? 0: counter+1)
    tempValue = lines[counter]
    propTestStep.setPropertyValue(“Value”, tempValue)

    Thanks,

    • Hi,
      If you have 2 inputs either you can use 2 different file and read them in same way at same time. OR
      maintain the input separated by a special character and split them after getting the value in a variable.
      For example :
      Username | Password
      abc | 123
      pqr | 1234
      xyz | 987

      Now on reading each line one by one you will get both username & password (“abc | 123″). So write a small method and split this data and then store these 2 values in 2 different variables. Done!

      Code line you have asked for does following :
      – Storing the value of the “next” index to be displayed. If reached maximum size of array (size -2) then set it to 0 else current value +1 is next item index number.
      – reading the line [index number] from the file and storing the read value in tempValue. Ex : line[2] –> would return “pqr | 1234″
      – Setting the value in the property teststep after getting it into the temp variable.

      Hope this explanation would be of some help.

      Regards,
      {Pradeep Bishnoi}

  6. Suresh says:

    Hi Pradeep,
    I am new bie to SOAPUI. I have created a soapui project in soapui 3.6.1 that sends xml request.
    I am trying to papameterise two values in that request.
    Can you please explain, the purpose of ‘Value’ property in your above code?
    Also, I need to have 2 text files that holds test data. How can i acheive this in single groovy script ?

    Regards,
    -Suresh

  7. farislinux says:

    Hi Pradeep,

    I have 100 lines in my text file. how do I run the test step ? do I need to select loop option and click run button ?

    Thanks

    • Hi,
      The script will be able to handle the case, no additional changes are needed to run it for 100 lines input. Since, the script is reading the input text file till end of file, and each line would be considered as an new input value.

      Regards,
      {Pradeep}

  8. farislinux says:

    Thanks & it worked like charm !

  9. Marcin says:

    Hello Pradeep,

    Great work!

    I wonder if these scripts can be used as load test in SoapUI. I mean will counter be shared among threads or each thread will maintain its own counter?

    • Hi Marcin,

      My best guess would be : ‘it will not work’. However haven’t tried it yet. If you have tried & found something interesting, please do share with other readers :)

      {Pradeep}

    • Happy hippo says:

      I thought script of such size would be multi-threaded but not. So the only real use – load test – is not possible:( The Smartbear company made it not easy to implement because the variables are shared during execution and multiple thread pick the same values which is smoething to avoid. In the end, we made our plugin in our company to prevent this.
      Smartbear should be aware there are servers where you cannot use Pro version just because of licensing, it would be fair to be able to develop scripts on user machine and execute for free on another – noone would pay two licenses and we certainly will not.

  10. Fearghal says:

    Pradeep,
    Excellent piece of scripting. I have been working with a few industry applications that use webservices to drive events into them to generate some form of change. To drive events in I have been updating the xml in SoapUI manually and then executing the action. With this type of scripting I can now create a file with the necessary input values.
    I have tested the code as above but the loop does not loop. I have to manually drive it by clicking on the execute function. I can see the values change in the Property – Looper file, but I still have to execute the action to the point where I see StopLoop change to T.
    I know it works as I had it working on an XP machine. I am now trying to replicate the same on a new Win7 machine.

    • Fearghal says:

      Forget the loop issue… I edited the DataLoop file and copied the name for the DataSource file and renamed the DataSource file. It was the name of the file for the return on the loop I had created with two –. Excellent work. Tried and tested……

  11. suhasini says:

    i get ERROR:java.lang.NullPointerException: Cannot invoke method setPropertyValue() on null object; at this line
    propTestStep.setPropertyValue(“Total”, lines.size.toString())
    In the property-Looper , what should be the Total value ??

    • Just wondering if you have created a property type teststep & it contains the variable named ‘Total’ ? This can only lead to such an error. Please cross check the same & refer blog content again.
      {Pradeep}

  12. Jag says:

    Hi, I tried useng your script but ran into some trouble. After debugging and refactoring I ended up with a WAY simpler version.
    All you need is 3 test steps:
    #1 a groovy script looper
    #2 a “looper-props” Property that has the dynamic parameters (in my case only one named “Value”)
    #3 a TestRequest, in my case a simple soap request that uses ${looper-props#Value} as a value.

    here it is Groovy Script – looper:

    def size
    File valueFile = new File(“C:/myValueFile.txt”) //make sure file already exists and contains different set of values separated by new line (CR).
    List lines = valueFile.readLines()
    size = lines.size.toInteger()
    propTestStep = context.testCase.getTestStepByName(“looper-props”) // get the Property TestStep

    for( counter in 0..size-1) // loops and runs a test case for each line in the file
    {
    tempValue = lines[counter]
    propTestStep.setPropertyValue(“Value”, tempValue)
    log.info tempValue
    testRunner.runTestStepByName(“MySoapTestRequest”);
    }

    Have fun!

    Note: As a perfectionist I also disable MySoapTestRequest so it isn’t run one last time after the looper did it’s job

  13. paddu says:

    HAi PB…
    Can u let me know how to write the responses of each iteration to an external output file say Excel..I am trying alot bt not getting the correct output..
    Each iteration the created workbook is being overriden and the response of the last iteratiuon is there in the excel.Can u help me out in this issue?
    Thanks in advance…

  14. Naman says:

    Hi Pradeep,

    Awsome piece of code. Cheers !! I have one concern that whether the datasource which is providing the data can be shared among all threads. I am asking from perspective of load testing. I have one testcase which i have to call concurrently by passing different values at same instant. I want to know whether this code can be use for load testing or not. TIA

  15. Saj says:

    Thanks Pradeep.
    I used the information here – your’s and Jag’s – to build the version of scripts I wrote.

    I am using SOAP UI Free version. I had multiple goals –
    externalize the groovy scripts (I wanted to edit/manage the script outside of the soapui editor),
    dynamically load the groovy scripts,
    build a library of scripts so that the code can be shared etc.

    Good news is that I was able to achieve all of these and I am happy with the results. I had to browse through so many soapui related websites to find the details I need. But I really appreciate the details you provide in your blogs. I will share my code shortly – but I wanted to let you know that the end results are pretty good.

    Following is the file loader script: FileLoader.gvy

    class FileLoader {

    def _status;
    def _log;

    FileLoader( org.apache.log4j.Logger logIn ) {
    this._log = logIn;
    }

    def loadFile( String paramFile ) {
    def size
    File valueFile = new File(paramFile) //make sure file already exists and contains different set of values separated by new line (CR).
    if(!valueFile.exists()) { // Checks whether the passed parameter File exists
    _log.warn(“Failed to load parameter File: $paramFile” );
    return;
    }

    def tempValue, value;

    List lines = valueFile.readLines()
    size = lines.size.toInteger();

    if (size == 0 ) {
    _log.warn(“Empty parameter file: $paramFile” );
    return(null);
    }
    _status = “Ready”;
    return(lines);
    }

    def loadPropertyFile(String paramFile) {
    // Working on implementing the property based files.
    }

    def isReady() {
    _log.info(” Script is ready”) ;
    return (true);

    }
    }

  16. Mazhar Shaikh says:

    Hey Pradeep – Thanks a lot. The above blog was great help.

  17. Abi says:

    Hi pradeep!!

    i use rest services and am currently working on calling external file and loading properties based on the user input. i have placed the groovy script for this in “load Script” available in the project overview. my problem arises when i launch the testrunner. testrunner does not load the groovy script present and also it does not take values from the global properties ( i have placed the end points in global properties). also, all the test steps fail in testrunner. i have to integrate soapui with hudson.

    Can u help me in calling all the properties and groovy scripts from testrunner ??

  18. jagga says:

    Hi pradeep,
    could you please explain this with a simple example,
    as i’m not able to understand.

    screen shots will help more….

  19. Rao says:

    Thank you Pradeep for your wonderful constants efforts and sharing best pieces to the community helping to achieve their goals.

    @Saj, wanted to achieve the same, maintain the groovy code outside soapui. Would you please share the details?

  20. Shubham says:

    This was a useful and an interesting read. I used your code snippet in my SOAPUI project and it worked fine. However, I have to declare the value of ‘Count’ parameter as 0 in the ‘Property – Looper’ test step before the first run of the test. Otherwise, I was getting an error – java.lang.NumberFormatException: For input string: “”.
    To eliminate any user intervention I parameterized ‘Count’ parameter from Project custom properties “${(#Project#Count)}” so that at the time of initial run it take the value ‘0’ from Project custom properties and pass it to the script and henceforth take the value from the script itself. Upon running the test case, the script threw an error as it was reading the value ${(#Project#Count)} instead of reading a 0.
    I have few clarifications on above scenario:
    1.) Did I miss on any initial configuration which was the reason the code was not getting a value of 0 for the first iteration?
    2.) How can I parameterize the ‘Count’ variable in ‘Property – Looper’ test step from Project custom properties so that it picks the actual value instead of the parameterized text “${(#Project#Count)}”?
    3.) Is there any other way to set the Count parameter 0 for the initial run (first iteration) like using the setup script?

    Many Thanks!
    Shubham

  21. Shubham says:

    Adding to my previous question:
    4.) I want to execute all Test Suites for different nodes/endpoints. Is there a way I can use this data source to loop all Test Suites in my project? I am trying to pass different endpoint using the .txt file.
    Thanks!

  22. Shiny says:

    Hi Pradeep,

    I have a property file with values:
    Item=77499
    Customer Name=Test
    and I want to store both key and value in SOAPUI properties.
    what is the procedure to pass both values in tag for execution at single instance?

    Thanks,
    Shiny

  23. Theodor says:

    Nice. Very nice indeed!

  24. AT says:

    Hi Pradeep.

    I have a requirement to pass multiple values in a parameter in a single request and assert the response of each result returned.
    For example, I’ve the following parameters in the body of the REST request:
    Student_RollNo
    Student_Name
    Student_Class

    I would like to pass multiple rows (each column maintained in an xls file or a datasource represents a parameter of the REST request) in a single request.

    Kindly help.

    -AT

  25. Hanh Vo says:

    Hi Pradeep,

    I have a excel file with 3 columns and many rows. I used Datasoure to read it and I saw values in Datalog of Datasoure. I want to compare values in Datalog with other value in Groovy script but I had a difficulty in reading values from this Datalog to Groovy script. Please help me how to read values from this Datalog to Groovy script.

    Thanks,
    Hanh

  26. Joe Black says:

    Hello Pradeep,
    This is Joe Black. Could you send me the .txt file please. I seem to be missing something defining the text file data. My email is jbfblack@gmail.com
    Thank you in advance – Joy and Peace today.

  27. […] DataSource & DataLoop using Groovy in soapUI | Learn … – May 19, 2012 · Now that i am learning + working on some really cool technology stuff, i thought of sharing one of the best hacks i have written in soapUI Open Source version…. […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s