Ask a Question

How do we handle empty string dynamically in assertions in ReadyAPI

SOLVED
krispokkuluri
Occasional Contributor

How do we handle empty string dynamically in assertions in ReadyAPI

ERROR: An error occurred [empty String], see error log for details

Hi i have a need to validate two data sources using nested loop on multiple records in several tables Steps

  1. Build a Rest Request
  2. get the datasource
  3. getting the data from db as expected result
  4. write a groovy script inorder to get a value to be validated with db
  5. Asert the values are equal

Issue : I have multiple empty values in the data sources from the api(actual value) and expected value db Question : When i run my script i am getting this error ERROR: An error occurred [empty String], see error log for details for empty values asserted . Please help as i am on a deadline and am aunable to find a solution online .

6 REPLIES 6
richie
Community Hero

Hey @krispokkuluri,

Im struggling to understand from your description

Are you saying that you have a REST request that returns a response and you follow this up with a jdbc test step and you want to assert that a value in the REST response is the same as the value returned by the JDBC?

If you can provide examples of the REST response payload along with the JDBC response as well as the groovy script youre using, someone will be able to help.

Cheers,

Rich
if this helped answer the post, could you please mark it as 'solved'? Also if you consider whether the title of your post is relevant? Perhaps if the post is solved, it might make sense to update the Subject header field of the post to something more descriptive? This will help people when searching for problems. Ta
krispokkuluri
Occasional Contributor

@richie My apologies , I thought i was clear in my head , yes you are absolutely right . Please find the snippets in attachment .I hope it is clearer

 

Reiterating where i am getting this issue  .

In the UI i beleive you are able to see a few empty values so when i try to validate it with db empty values i am getting that error .

DB : There's nothing i can do as it's coming from a stored proc .

Groovy : This is where i am seeking help to modify my logic such that i could handle such empty strings . Kindly help

 

jdbc output file for jdbc output .

 

This is my beloow groovy scipt for logic and assertion .

double commitmentqauterQ1 = commitmentQ1 ? commitmentQ1.toDouble() :1 ;
double ContractDomainqauterQ1 = contractDomainQ1 ? contractDomainQ1.toDouble() : 1 ;
double tierPriceqauterQ1 = tierPriceQ1 ? tierPriceQ1.toDouble() : 1 ;
int prorateddaysQ1 = proratedQ1.toInteger();
int QtyQ1 = planqtyQ1? planqtyQ1.toInteger() : 0 ;
double PriceQ1 = tierPriceQ1 ? tierPriceqauterQ1 : intelPrice.toDouble()
def planCostQ1 = (PriceQ1.toDouble() * QtyQ1.toInteger() * prorateddaysQ1.toInteger() * ContractDomainqauterQ1.toDouble() * commitmentqauterQ1.toDouble()).round(1)
def expectedCostQ1 = queryplancostQ1.toDouble().round(1)
//log.info("planCostQ1 $planCostQ1")
//log.info("expectedCostQ1 $expectedCostQ1" )
assert planCostQ1 == expectedCostQ1
log.info("Assertion passed !! $planCostQ1 | $expectedCostQ1")

Hi,

 

The below example and function show how you can test for an empty string.  Just create a brand new Groovy script step, paste in the contents and click Go in the Groovy window.  Ensure you can see the logging for the answers....

 

def value = "1.12";
log.info("value ${value} is empty?  ${ isEmpty(value)}");

value = "1";
log.info("value ${value} is empty?  ${ isEmpty(value)}");

value = "";
log.info("value ${value} is empty?  ${ isEmpty(value)}");

value = null;
log.info("value ${value} is empty?  ${ isEmpty(value)}");

def isEmpty(stringvalue) {

    if(stringvalue == null) {
    	    return true;
    } else {
		if((stringvalue.length() == 0) ||
			(stringvalue == "") ) {
			return true;
		} else {
			return false;
		}
	}
}

 

Also, Groovy Double does not have a tryParse function unlike other languages, but it does throw an exception which might help...  Next example...

def myValue = "1.12";
log.info("is ${myValue} parsable as double?  ${canBeDouble(myValue)}");

myValue = "1";
log.info("is ${myValue} parsable as double?  ${canBeDouble(myValue)}");

myValue = "abc";
log.info("is ${myValue} parsable as double?  ${canBeDouble(myValue)}");

def canBeDouble(theValue) {
	try {
		  def a = Double.parseDouble(theValue);
		  return true;
	} catch (NumberFormatException e) {
		  //the parseDouble failed and you need to handle it here
		  return false;
	}
}

 

You can then maybe use these examples, or modify them, to test suspect values from the db before trying the assert.

krispokkuluri
Occasional Contributor

Hi @ChrisAdams ,

 

The above code snippet worked like a  charm  but i am not so good at coding do you mind helping me modify it to the above logic  that i mentioned  below kindly help

def tierPriceQ1 = context.expand( '${plantestautomation source#Q1TierPriceScallingFactor}' )
def tierPriceQ2 = context.expand( '${plantestautomation source#Q2TierPriceScallingFactor}' )
def tierPriceQ3 = context.expand( '${plantestautomation source#Q3TierPriceScallingFactor}' )
def tierPriceQ4 = context.expand( '${plantestautomation source#Q4TierPriceScallingFactor}' )

def intelPrice = context.expand( '${plantestautomation source#PlanQ1HistoricalFormula#$[\'FinalPrice\'][\'IntelPrice\']}' )


//log.info(intelPrice )
//scaling factor
def contractDomainQ1 = context.expand( '${plantestautomation source#Q1CD}' )
def contractDomainQ2 = context.expand( '${plantestautomation source#Q2CD}' )
def contractDomainQ3 = context.expand( '${plantestautomation source#Q3CD}' )
def contractDomainQ4 = context.expand( '${plantestautomation source#Q4CD}' )
//scaling factor for commitmentment
def commitmentQ1 = context.expand( '${plantestautomation source#Q1Commitment}' )
def commitmentQ2 = context.expand( '${plantestautomation source#Q2Commitment}' )
def commitmentQ3 = context.expand( '${plantestautomation source#Q3Commitment}' )
def commitmentQ4 = context.expand( '${plantestautomation source#Q4Commitment}' )
//prorated for Quarters
def proratedQ1 = context.expand( '${prorated jdbc#ResponseAsXml#//Results[1]/ResultSet[1]/Row[1]/PRORATED[1]}' )
def proratedQ2 = context.expand( '${prorated jdbc#ResponseAsXml#//Results[1]/ResultSet[1]/Row[2]/PRORATED[1]}' )
def proratedQ3 = context.expand( '${prorated jdbc#ResponseAsXml#//Results[1]/ResultSet[1]/Row[3]/PRORATED[1]}' )
def proratedQ4 = context.expand( '${prorated jdbc#ResponseAsXml#//Results[1]/ResultSet[1]/Row[4]/PRORATED[1]}' )
//plan cost derived from query for validation
def queryplancostQ1 = context.expand( '${plantestjdbc#Q1Cost}' )
def queryplancostQ2 = context.expand( '${plantestjdbc#Q2Cost}' )
def queryplancostQ3 = context.expand( '${plantestjdbc#Q3Cost}' )
def queryplancostQ4 = context.expand( '${plantestjdbc#Q4Cost}' )
//plan quantity derived from JSON response
def planqtyQ1 = context.expand( '${plantestautomation source#PlanQ1Qty}' )
def planqtyQ2 = context.expand( '${plantestautomation source#PlanQ2Qty}' )
def planqtyQ3 = context.expand( '${plantestautomation source#PlanQ3Qty}' )
def planqtyQ4 = context.expand( '${plantestautomation source#PlanQ4Qty}' )
/*
//Tier Group Formula

def Q1TierGroupFormula = context.expand( '${plancostcalculation#ResponseAsXml#//Response[1]/e[*]/Q1TierGroupFormula[1]}' )
def Q2TierGroupFormula = context.expand( '${plancostcalculation#ResponseAsXml#//Response[1]/e[*]/Q2TierGroupFormula[1]}' )
def Q3TierGroupFormula = context.expand( '${plancostcalculation#ResponseAsXml#//Response[1]/e[*]/Q3TierGroupFormula[1]}' )
def Q4TierGroupFormula = context.expand( '${plancostcalculation#ResponseAsXml#//Response[1]/e[*]/Q4TierGroupFormula[1]}' )
*/




//First check for commitment
/*String [] Quater = new String[5];
//Quater[0] = "Q1";
//Quater[1] = "Q2";
//Quater[2] = "Q3";
Quater[3] = "Q4";
for (int i=0; i<5; i++)
{
log.info("Quater :" + Quater[i]);
}*/
//log.info(commitmentQ1);
//log.info(tierPriceQ1)

double commitmentqauterQ1 = commitmentQ1 ?  commitmentQ1.toDouble() :1 ;
double ContractDomainqauterQ1 = contractDomainQ1 ? contractDomainQ1.toDouble() : 1 ;
double tierPriceqauterQ1 = tierPriceQ1 ? tierPriceQ1.toDouble()  : 1 ;
int prorateddaysQ1 = proratedQ1.toInteger();
int QtyQ1 = planqtyQ1? planqtyQ1.toInteger() : 0 ;
double PriceQ1 =  tierPriceQ1 ? tierPriceqauterQ1 : intelPrice.toDouble()
def planCostQ1 = (PriceQ1.toDouble() * QtyQ1.toInteger() * prorateddaysQ1.toInteger()  * ContractDomainqauterQ1.toDouble() * commitmentqauterQ1.toDouble()).round(1)
def expectedCostQ1 = queryplancostQ1.toDouble().round(1)
//log.info("planCostQ1  $planCostQ1")
//log.info("expectedCostQ1 $expectedCostQ1" )
assert planCostQ1 == expectedCostQ1
log.info("Assertion passed !! $planCostQ1 | $expectedCostQ1")
//log.info("intelPriceQ1 :$intelPrice" )
//log.info("Qty: $QtyQ1") 
/*log.info(Qty) 
log.info( prorateddays) 
log.info(tierPriceqauter) 
log.info(ContractDomainqauter ) 
log.info(commitmentqauter) 
log.info(intelPrice) 
log.info(intelPrice) 
//Qty  $prorateddays  $tierPriceqauter  $ContractDomainqauter  $commitmentqauter)
*/
//Q2
double commitmentqauterQ2 = commitmentQ2 ?  commitmentQ2.toDouble() :1 ;
double ContractDomainqauterQ2 = contractDomainQ2 ? contractDomainQ2.toDouble() : 1 ;
double tierPriceqauterQ2 = tierPriceQ2 ? tierPriceQ2.toDouble()  : 1 ;
int prorateddaysQ2 = proratedQ2.toInteger();
int QtyQ2 = planqtyQ2? planqtyQ2.toInteger() : 0 ;
double PriceQ2 =  tierPriceQ2 ? tierPriceqauterQ2 : intelPrice.toDouble()
def planCostQ2 = (PriceQ2.toDouble() * QtyQ2.toInteger() * prorateddaysQ2.toInteger()  * ContractDomainqauterQ2.toDouble() * commitmentqauterQ2.toDouble()).round(1)
def expectedCostQ2 = queryplancostQ2.toDouble().round(1)
assert planCostQ2 == expectedCostQ2
log.info("Assertion passed !! $planCostQ2 | $expectedCostQ2")
//log.info("planCostQ2 :  $planCostQ2")
//log.info("QtyQ2: $QtyQ2") 
//log.info(PriceQ2)
//log.info(tierPriceqauterQ2) 
//log.info(tierPriceQ2)
//log.info(ContractDomainqauterQ2 ) 
//log.info(commitmentqauterQ2) 
//log.info(prorateddaysQ2)

//Q3
double commitmentqauterQ3 = commitmentQ3 ?  commitmentQ3.toDouble() :1 ;
double ContractDomainqauterQ3 = contractDomainQ3 ? contractDomainQ3.toDouble() : 1 ;
double tierPriceqauterQ3 = tierPriceQ3 ? tierPriceQ3.toDouble()  : 1 ;
int prorateddaysQ3 = proratedQ3.toInteger();
int QtyQ3 = planqtyQ3? planqtyQ3.toInteger() : 0 ;
double PriceQ3 =  tierPriceQ3 ? tierPriceqauterQ3 : intelPrice.toDouble()
def planCostQ3 = (PriceQ3.toDouble() * QtyQ3.toInteger() * prorateddaysQ3.toInteger()  * ContractDomainqauterQ3.toDouble() * commitmentqauterQ3.toDouble()).round(1)
def expectedCostQ3 = queryplancostQ3.toDouble().round(1)
assert planCostQ3 == expectedCostQ3
log.info("Assertion passed !! $planCostQ3 | $expectedCostQ3")
//log.info("planCostQ3 :  $planCostQ3")
//log.info("intelPriceQ3 :$intelPrice" )
//log.info("QtyQ3: $QtyQ3")
//Q4
double commitmentqauterQ4 = commitmentQ4 ?  commitmentQ4.toDouble() :1 ;
double ContractDomainqauterQ4 = contractDomainQ4 ? contractDomainQ4.toDouble() : 1 ;
double tierPriceqauterQ4 = tierPriceQ4 ? tierPriceQ4.toDouble()  : 1 ;
int prorateddaysQ4 = proratedQ4.toInteger();
int QtyQ4 = planqtyQ4? planqtyQ4.toInteger() : 0 ;
double PriceQ4 =  tierPriceQ4 ? tierPriceqauterQ4 : intelPrice.toDouble()
def planCostQ4 = (PriceQ4.toDouble() * QtyQ4.toInteger() * prorateddaysQ4.toInteger()  * ContractDomainqauterQ4.toDouble() * commitmentqauterQ4.toDouble()).round(1)
def expectedCostQ4 = queryplancostQ4.toDouble().round(1)
assert planCostQ4 == expectedCostQ4
log.info("Assertion passed !! $planCostQ4 | $expectedCostQ4")
//log.info("planCostQ4 :  $planCostQ4")
//log.info("intelPriceQ4 :$intelPrice" )
//log.info("QtyQ4: $QtyQ4")

  

Hi,

 

Sorry, I'm not willing to refactor as there is so much in your script.

 

In terms of coding, it seems you're better than you think.  You're even using ternary operators.... E.g. double commitmentqauterQ1 = commitmentQ1 ? commitmentQ1.toDouble() :1 ;

 

Focus on the values that could be empty.  For those values, use one of my examples to see if it can detect empty, missing etc.

 

Decide whether to only assert if all values are available and can be converted.  Decide what you should do if some values are empty.  E.g. fail or skip.

 

 

 

 

krispokkuluri
Occasional Contributor

I want to assert that the values are empty from the script but i want say log only the values that are empty and assert it so the script doesn't fail as it is a valid scenario I was thinking to check post the assert if it is an empty string it gives me a chance to assert if empty but not sure how to do that or if that makes any sense at all.

 

P.S : I am pretty new  to coding and readyapi as on whole so i would be really grateful if you could just give an idea on how i could do this .

 

cancel
Showing results for 
Search instead for 
Did you mean: