Forum Discussion

francisbrochu's avatar
francisbrochu
Occasional Contributor
8 years ago
Solved

Problem with a gotoStep in sql.eachrow

I have a Groovy script with a SQL request and I want to execute some test steps for each row. I put some log.info in each of my scripts to have a follow up. In my code just below, even if I see my log.info line in the script log and the step name change very quickly, it doesn't seem to go to step 2 because I don't see the log.info line of my step 2 which is at the very first line of my Groovy script.. 

 

I would like for each of my sql rows to execute step 2 and 3 and then, when finished, go to step 4.

 

My code at step 1 :

 

import groovy.sql.Sql
com.eviware.soapui.support.GroovyUtils.registerJdbcDriver("oracle.jdbc.OracleDriver")

//
scripts = testRunner.testCase.testSuite.project.testSuites["Script Library"];
scripts.testCases["BaseDonnees"].testSteps["Connexion"].run(testRunner, context);

def sql = Sql.newInstance(context.connexion.path,context.connexion.username,context.connexion.password,context.connexion.driver)
//def rownum = context.expand( '${#TestCase#totalTests}' )

def sqlRequete = '''SELECT BLABLABLA'''

def keyset = null; //A place to keep the column names
sql.eachRow(sqlRequete) { row ->
//If the keyset is null create one and add the column names
if (keyset == null) {
//We want all the column names exept the one named 'id
keyset = row.toRowResult().keySet().findAll{ it }
}
keyset.each() { k ->
context.setProperty("$k",row."""$k""")
}

log.info(context.SEQ_CLASSE_VIRTUELLE + '-' + context.SEQ_SITE_COURS)

testRunner.testCase.getTestStepAt(2).setName("Script - BD - Liste des enseignants classe virtuelle [idSite:" + context.SEQ_SITE_COURS + "][CV:" + context.SEQ_CLASSE_VIRTUELLE + "]")
testRunner.gotoStep(2)
}

testRunner.gotoStep(4) //Fin du test automatisé - tout ce qu'il y avait dans la requête BD a été analysé

 

My code at step 2 :

 

import groovy.sql.Sql
com.eviware.soapui.support.GroovyUtils.registerJdbcDriver("oracle.jdbc.OracleDriver")

log.info('ETAPE2')

//
scripts = testRunner.testCase.testSuite.project.testSuites["Script Library"];
scripts.testCases["BaseDonnees"].testSteps["Connexion"].run(testRunner, context);

def sql02 = Sql.newInstance(context.connexion.path,context.connexion.username,context.connexion.password,context.connexion.driver)
//def rownum = context.expand( '${#TestCase#totalTests}' )

def sqlRequete02 = '''SELECT SECOND BLABLABLA'''

log.info('REQUETE SQL 2 = ' + sqlRequete02)

def keyset = null; //A place to keep the column names
sql02.eachRow(sqlRequete02) { row ->
  //If the keyset is null create one and add the column names
  if (keyset == null) {
    //We want all the column names exept the one named 'id
    keyset = row.toRowResult().keySet().findAll{ it } 
  }
  keyset.each() { k ->
	context.setProperty("$k",row."""$k""")
  }

  testRunner.gotoStep(3)	//Validation - Contenu réponse service
}

testRunner.gotoStep(1) //LOOP - Liste des classes virtuelles
  • Looks like there are multiple goto steps in your scripts.
    It would be good to control all the steps from one step.

    Once the control goes to a particular step, it does not return to calling step back. So, better to use "run" the step like how you did in the initial part of your first script.

    If you are controlling everything from one step of the test case, depending on the sequence of the steps, there is a possibility that rest of the steps executed again once the current controlling script is completed, so it needs to be handled as well. To do this, add another groovy script, say name it as "exitScript" which only contains below statement.

    log.info "Test finished"

    In the current script (in which you are controlling running all the steps), add a last statement gotoStep for exit script so that it can skip the unwanted execution of other steps.

    Hope this is clear and helpful in your case.

3 Replies

  • nmrao's avatar
    nmrao
    Champion Level 3

    Looks like there are multiple goto steps in your scripts.
    It would be good to control all the steps from one step.

    Once the control goes to a particular step, it does not return to calling step back. So, better to use "run" the step like how you did in the initial part of your first script.

    If you are controlling everything from one step of the test case, depending on the sequence of the steps, there is a possibility that rest of the steps executed again once the current controlling script is completed, so it needs to be handled as well. To do this, add another groovy script, say name it as "exitScript" which only contains below statement.

    log.info "Test finished"

    In the current script (in which you are controlling running all the steps), add a last statement gotoStep for exit script so that it can skip the unwanted execution of other steps.

    Hope this is clear and helpful in your case.

    • francisbrochu's avatar
      francisbrochu
      Occasional Contributor

      If I try to summarize my script.

       

      Step 1 :

      Script with a sql.eachrow and in this loop I want to call Step 2, (then Step 3) and do the same with the next row. Once the loop is finished, I call Step 4 (which looks like log.info('Test finished') as you described).

       

      Step 2 :

      Execute the script then go to Step 3.

       

      Step 3 : 

      Execute the script then go back to Step 1.

       

      Step 4 :

      The step is reached only when the loop in Step 1 is finished.

       

      ------------------------------------

       

      The only thing I'm not sure to understand in your explanation is : Can I call a step with gotoStep() in a eachRow() loop ? I must prefer run() ?

       

      Can you give me an example of calling a test step with run() ? I'm not familiar with this command.

       

      Thanks a lot,

      • francisbrochu's avatar
        francisbrochu
        Occasional Contributor

        So, as explained, I changed gotoStep by run().

         

        In my eachrow loop, I do :

         

        sql.eachRow(sqlRequete) { row ->
          //If the keyset is null create one and add the column names
          if (keyset == null) {
            //We want all the column names exept the one named 'id
            keyset = row.toRowResult().keySet().findAll{ it } 
          }
          keyset.each() { k ->
        	context.setProperty("$k",row."""$k""")
          }
          
          testStep = testRunner.testCase.getTestStepAt(2) 
        testStep.setName("Script - BD - Liste des enseignants classe virtuelle [idSite:" + context.SEQ_SITE_COURS + "][CV:" + context.SEQ_CLASSE_VIRTUELLE + "]") testStep.run(testRunner,context) }

        And then I'm able to execute my script logic explained in my previous post.

         

        Thanks !