Thursday, May 26, 2011

SoapUI Pro / Groovy - Scripts and scripted assertions

I am putting these scripts and scripted assertions up here for a couple reasons. One - I am very forgetful where I've put different assertions and don't like scouting around my large projects trying to find a specific assertion. I refuse to reinvent the wheel, if I already invented it. Two - I hope to help anyone who has run into similar requirements and issues.

Hope you enjoy





Verify Elements of Each Type are Descending by Score

import com.eviware.soapui.support.XmlHolder
import java.util.*

def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context );
def holder = groovyUtils.getXmlHolder( messageExchange.responseContentAsXml )
def nodeCount = holder["count(//ns1:Response[1]/ns1:search[1]/ns1:results[1]/ns1:e)"]
def currentType, currentScore = ""
def typeList = []
def found = false
def index = 0

currentType = holder.getNodeValue( "//ns1:Response[1]/ns1:search[1]/ns1:results[1]/ns1:e[1]/ns1:result[1]/ns1:type[1]" )
currentScore = holder.getNodeValue( "//ns1:Response[1]/ns1:search[1]/ns1:results[1]/ns1:e[1]/ns1:result[1]/ns1:score[1]" )
typeList.add( [ currentType, currentScore ] )
nodeCount = nodeCount.toInteger()

for ( i = 2; i < nodeCount; i++ ){
  currentType = holder.getNodeValue( "//ns1:Response[1]/ns1:search[1]/ns1:results[1]/ns1:e[" + i + "]/ns1:result[1]/ns1:type[1]" )
  currentScore = holder.getNodeValue( "//ns1:Response[1]/ns1:search[1]/ns1:results[1]/ns1:e[" + i + "]/ns1:result[1]/ns1:score[1]" )
  typeSize = typeList.size()
  for ( y = 0; y < typeSize; y++ ){
    if ( typeList[ y ].contains( currentType ) ){
      index = y
      found = true
      break
    }
  }
  if ( found ){
    previous = typeList[ index ]
    assert previous[ 1 ] >= currentScore
    found = false
  }
  else
  {
    typeList.add( [ currentType, currentScore ] )
  }
}




The Universal SLA Assertion (makes managing sla assertion values a one-stop-shop)

def sla_time_taken = messageExchange.getTimeTaken();
def sla_time = context.expand( '${#Project#sla_time}' ).toInteger();

assert sla_time_taken < sla_time;




Header Information Assertion

def headers = messageExchange.getResponseHeaders();
def map_key = context.expand( '${#Project#map_key}' );
def map_val = context.expand( '${#Project#map_val}' );

assert headers.get(map_key).toString() == map_val;




Verifying Order of Response Elements by Element Value Assertion

import com.eviware.soapui.support.XmlHolder;

def bo_host = context.expand( '${#Project#project_host}' );
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context );
def holder = groovyUtils.getXmlHolder( messageExchange.responseContentAsXml );
def nodeCount = holder["count(//ns1:Response[1]/ns1:search[1]/ns1:results[1]/ns1:e)"];
def expectedCount = context.expand( '${#Project#expected_return_count}' );

nodeCount = nodeCount.toInteger();
assert nodeCount == expectedCount;
previousPlayCountValue = holder.getNodeValue( "//ns1:Response[1]/ns1:search[1]/ns1:results[1]/ns1:e[1]/ns1:result[1]/ns1:track[1]/ns1:playcounts[1]" ).toInteger();

for( int i = 2; i <= nodeCount; ++i ){
    currentPlayCountValue = holder.getNodeValue( "//ns1:Response[1]/ns1:search[1]/ns1:results[1]/ns1:e[$i]/ns1:result[1]/ns1:track[1]/ns1:playcounts[1]" ).toInteger();
    assert previousPlayCountValue >= currentPlayCountValue;
    previousPlayCountValue = currentPlayCountValue;
}




Gregorian Date String Builder

def gCalendar = new GregorianCalendar();
def returnString = null;

gCalendar.timeInMillis = System.currentTimeMillis();

return gCalendar.get(Calendar.YEAR) + "-" +\
    gCalendar.get(Calendar.MONTH) + "-" + ( gCalendar.get(Calendar.DATE) - 1 ) +\
    " " + gCalendar.get(Calendar.HOUR_OF_DAY) + ":" + gCalendar.get(Calendar.MINUTE) +\
    ":" + gCalendar.get(Calendar.SECOND);



Random Non-Repeating IDs String Builder

def standard_count = context.expand( '${Properties#standard_count}' ).toInteger();
def track_range = context.expand( '${Properties#track_range}' ).toInteger();
def generator = new Random();
def random_int = generator.nextInt( track_range );
def random_int_string, return_string = random_int.toString();
def jump_string = "";

for ( i = 1; i < standard_count; i++ ) {
    if ( ! return_string.contains( jump_string ) && return_string != "" && random_int < track_range ) {
        return_string = return_string + ", " + jump_string;
    }
    else {
        i--;
    }
    random_int = generator.nextInt(track_range);
    jump_string = random_int.toString();
}

return return_string;




Reversing IDs String Builder

def original = context.expand( '${Properties#tracks}' );
def tokens = original.tokenize(", ");
def size = tokens.size();
def newValue = "";

newValue = tokens[ 0 ];
tokens.remove( 0 );
for ( current in tokens ) {
    if ( current != null && current != "" ) {
        newValue = newValue + ", " + current;
    }
}

return newValue;




Shuffle IDs String Builder

def original = context.expand( '${Properties#tracks}' );
def tokens = original.tokenize(", ");
def size = tokens.size() - 1;
def newValue = "";
def generator = new Random();

if ( size > 0 ) {
    int r = generator.nextInt(size) + 1;
    newValue = tokens[r];
    for ( i in 1..size ) {
        r = generator.nextInt(size + 1);
        newValue = newValue + ", " + tokens[r];
        tokens.remove(r);
        size = tokens.size() - 1;
    }
}
else {
    newValue = original;
}

return newValue;




Response Elements Values String Builder

def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context );
def holder = groovyUtils.getXmlHolder( context.expand( '${Publish Playlist#ResponseAsXml}' ));
def nodeValue = holder.getNodeValue( "//ns1:Response[1]/ns1:warning[1]/ns1:fail_to_add[1]/ns1:e[1]/text()" );
def i = 1;

return_string = context.expand( '${Properties#blacklisted_track_ids}' );

while ( nodeValue != null ) {
    if ( ! return_string.contains( nodeValue ) ) {
        return_string = return_string + ", " + nodeValue;
    }
    i++;
    nodeValue = holder.getNodeValue( "//ns1:Response[1]/ns1:warning[1]/ns1:fail_to_add[1]/ns1:e[" + i.toString() + "]/text()" );
}

return return_string;




Random Hex String Builder

def generator = new Random();
def r = generator.nextDouble();

return Double.toHexString(r)[4..16];




Random Characters String Builder

def generator = new Random();
def count = ( context.expand( '${Search Properties#search_string_length}' ).toInteger() );
def r = generator.nextInt( count +1 ) +1;
def token_string = Long.toString( Math.abs(generator.nextLong() ), 36);

return token_string.getAt( 1..count );