Forum Discussion

towardsQuality's avatar
towardsQuality
Occasional Contributor
2 years ago

How to change Test Case Status using Groovy

Hi! There is some integration and timing uncertainty within the product under test that has required me to utilize some Groovy code to retry a test step (a REST GET call) x number of times, with y a...
  • nmrao's avatar
    12 months ago

    towardsQuality 

    After looking at all the responses,

    Current steps:

    POST REST Request

    Groovy Script with retry logic

    GET REST Request

    Here is what I would  suggest or do in this scenario.

    Changes of sequence:

    POST REST Request

    GET REST Request (Disable the step)

    Groovy script with retry logic

    Reason being that the execution control will be at Groovy Script step and still be able to run the GET call. Also avoid stopping the test execution by disabling the GET call step.

    And there is no need to have any logic for Tear Down script of the test case as well.

    Assuming that the test steps are in same sequence and there is no other steps in between these.

    And here is the groovy script content goes:

    import com.eviware.soapui.model.testsuite.Assertable.AssertionStatus
    import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus
    def maxAttempts = 7
    def waiting = 10
    def doubleIt = { it * 2 }
    def currentWait = 1
    
    //Get the test step just before the current groovy script step, which is GET REST call step
    def step = context.testCase.testStepList[context.currentStepIndex-1]
    def isStepFailed = {
    	log.info "Executing test step : ${step.name}"
    	def result = step.run(testRunner, context)
    	log.info "Assertion : ${step.assertionStatus}"
    	log.info "Step result: ${result.status}"
    	result.status == TestStepStatus.FAILED ? true : false
    }
    
    /**
    * This will first wait for 10 sec, then 20 sec, then 40 sec so that number calls will be reduced, you can change it as needed
    */
    def waitFor = { 
         currentWait = (it == 1) ? currentWait : doubleIt(currentWait)
         log.info "Waiting for ${waiting * currentWait} seconds before attempting ${step.name} again"
        Thread.sleep(1000 * waiting * currentWait)   
    }
    
    for(item in 1..maxAttempts) {
    	waitFor(item)
    	log.info "Attempt: $item"
    	if (!isStepFailed()) {
    		break
    	} else {
                   //Test will be failed once GET call fails after exhaustings maxAttempts
    		if (item == maxAttempts) assert false, "GET instance failed after $item attempts"
    	}
    }
    return

    Please give it a try and see if it helps!

    By the way, no need to change the Test Case options unlike discussed earlier, keep the default