Forum Discussion

dva1946's avatar
dva1946
Occasional Contributor
13 years ago

Groovy Script Loop HOWTO

This will be a quick HOWTO with hopes of adding much more shorty.

1. Set variables at the TESTSUITE level. Double-click on testsuite, click on properties in the bottom of the larger window. Set things like DB login here.

2. Set testcase-related variables at the TESTCASE level. Use same process.

3. Test Steps (basic):
Datagen File
Groovy Script - Goto
Property Transfer
TestStepA
TestStepB
Groovy Script - Main Loop

4. Groovy Script - Goto (a single line is all that is necessary)
testRunner.gotoStepByName( "Groovy Script - Main Loop")

5. Groovy Script - Main Loop

Below is an actual script which has been modified to not show private information, but it is A FULLY FUNCTIONAL SCRIPT. You should be able to COPY THIS SCRIPT AS-IS and modify for your needs.

// Database connection:
// All these properties are defined at the TEST SUITE LEVEL
// Properties used:
// DenServer25
// Password
// sid
// Database
// DBport

// Extract global property value as local Variables
def scriptDenServer25 = context.expand( '${#TestSuite#DenServer25}' )
def scriptPassword = context.expand( '${#TestSuite#Password}' )
def scriptSid = context.expand( '${#TestSuite#sid}' )
def scriptDatabase = context.expand( '${#TestSuite#Database}' )
def scriptDBport = context.expand( '${#TestSuite#DBport}' )

//** Resolve db connection **//
import groovy.sql.Sql
import com.eviware.soapui.support.GroovyUtils.*
log.info "Connecting to DB here";
com.eviware.soapui.support.GroovyUtils.registerJdbcDriver("oracle.jdbc.driver.OracleDriver")
//***************************************//

log.info "Running Query for TestCase - My R&D";

sql = Sql.newInstance("jdbc:oracle:thin:@${scriptDenServer25}:${scriptDBport}:${scriptSid}", "${scriptDatabase}", "${scriptPassword}", "oracle.jdbc.pool.OracleDataSource")

// **TESTCASE** //
def scriptMOD = context.expand( '${#TestCase#MOD}' )
def scriptLIMIT = context.expand( '${#TestCase#LIMIT}' )

// **MAIN QUERY ** //

def aa = 0
def bb = 0
sql.eachRow("select offering_id from h_offering where service_type = ${scriptMOD} and deleted_flag = 0 and ROWNUM <= ${scriptLIMIT} order by offering_id") { row ->

testRunner.testCase.setPropertyValue( "dbofferingID", "$row.OFFERING_ID" )
log.info "Set Property dbofferingID = $row.OFFERING_ID";

// Now run desired test steps. Must send each individually.

testRunner.runTestStepByName("Property Transfer to ABC");
testRunner.runTestStepByName("getMyStuff");

//** Add loop to only run a step one time **//
while (aa < 1) {
testRunner.runTestStepByName("getAuth");
testRunner.runTestStepByName("isAct");
testRunner.runTestStepByName("getAuthServ");
aa++
}
//******************************************//

testRunner.runTestStepByName("Delete It");
bb++
}
log.info "Records Processed = $bb";

sql.close()

// END OF GROOVY SCRIPT - MAIN LOOP //

6. DESIGN THEORY:

a. The objective is a compact Test Suite / Test Case which connects to a database for all it's looping data. This of course eliminated HARD-CODED most source data.

b. Before you can use this design, you must understand properties at the TESTSUITE & TESTCASE level.

c. TESTSUITE properties provide DATABASE CONNECTIONS.

d. TESTCASE properties allow setting and retrieval of values within the testcase. This provides the real power for the looping process.

e. First you build a teststep for Datagen static values.

f. Next you add a "Groovy Script-Goto" teststep.

g. Next add two simple (and known) teststeps.

h. Now add the "Groovy Script - Main Loop" teststep.

i. Now edit this script and make it run.

j. For now, I am not going to explain this script, as it already has lots of comments.

LEARNING LOOP DESIGN
This was not easy, in fact it took weeks of research, trial-n-error and failure before everything in it was mastered.

Have fun!
  • abavas's avatar
    abavas
    New Contributor
    Good one!!

    My test case contains following steps
    1.Soap request (getAsset)
    2.Property transfer
    3.soap request
    4.Groovy script

    My Script is
    def aa =0
    while (aa < 3)
    {
    testRunner.gotoStepByName( "getAsset")
    aa++
    }

    When I run the test case I expect it to run 3 times, but it runs indefinelty, can any one help me on this
  • dva1946's avatar
    dva1946
    Occasional Contributor
    I am not too sure why you loop continually.

    Also, I am not sure why you don't have a goto as your 1st step.

    I would do something like this:

    Define AssetID property TestCase.

    1. Groovy Script-Goto
    2. Property transfer
    3. Soap request (getAsset)
    4. Groovy Script Loop

    #1 only has one line in it: testRunner.gotoStepByName( "Groovy Script - Main Loop")

    #4 Groovy Script Loop:

    def aa =0
    while (aa < 3)
    {
    aa++

    // set property (which you defined in the testcase property)
    testRunner.testCase.setPropertyValue( "AssetID", "$aa" )

    testRunner.gotoStepByName( "Property transfer")
    //property transfer gets AssetID and sets it into the getAsset step
    testRunner.gotoStepByName( "getAsset")

    log.info "aa = $aa";
    }

    log.info "Records Processed = $aa";

    See if this help,
    Dave
  • Aaronliu's avatar
    Aaronliu
    Frequent Contributor
    Hi,
    try it yourself...your while loop is right


    def aa = 0
    while (aa < 3)
    {
    //testRunner.gotoStepByName( "getAsset")
    def testStep = testRunner.testCase.testSteps['getAsset']
    testStep.run( testRunner, context )
    aa++
    }
  • abavas's avatar
    abavas
    New Contributor
    Thanks for yout time Dave and Aaronliu.

    My previous code was contiously looping bcos variable aa is set to '0' when ever Groovy-loop is step is entred.

    So I changed the code like ,

    My test case contains
    1.Soap request
    2.Property
    3.Propery transfer
    4.Groovy loop

    I defiened tht count as variabled and I modified the code
    //def aa =0
    targetStep = testRunner.testCase.getTestStepByName( "Properties-strorderID")
    def i= targetStep.getPropertyValue("currentCount")
    log.info("i is" + i)
    def count= targetStep.getPropertyValue("maxcount")
    while (i < count)
    {
    log.info("enetered loop")
    testRunner.gotoStepByName("soap request")
    sleep 10000
    i++
    log.info("now i is" + i)
    targetStep.setPropertyValue("currentCount",i)
    }


    Ir-respective of my max count "Is called only twice", Wen I run the script alone its running properly, when I run the test case its looping only twice
  • dva1946's avatar
    dva1946
    Occasional Contributor
    More enhanced Query Select with ROWNUM <= NN:

    //Testcase property
    def scriptLIMIT = context.expand( '${#TestCase#LIMIT}' )

    sql.eachRow("select * from (select service_name from service where admin_state_id = 2 order by service_name)tmp where ROWNUM <= ${scriptLIMIT}") { row ->

    The query will now output "order by service_name" will output from the beginning.
  • I was trying to do the same thing and worked with what was in the forum but found that all I really had to do is add this to my groovy loop

    if( context.loopIndex == null )
    context.loopIndex = 0

    if( ++context.loopIndex < 25 )
    testRunner.gotoStepByName( "DataGen" )

    1. DataGen
    2. Soap Request
    3. Groovy loop