Ask a Question

Random String Generator for REST Request

Rememo
Contributor

Random String Generator for REST Request

Hi All,

 

I was wondering if anyone could help with being able to create random data for a POST request that contains about 1000 lines of json.  So it would just REPLACE "string" any time it is mentioned/displayed with random data...

 

Part of Example below:

"newBusinessRatingReferenceId": "string",
"offerOriginChannelEntCd": "string",
"offerOriginSubChannelEntCd": "string",
"originalOfferOriginChannelEntCd": "string",
"originalOfferOriginSubChannelEntCd": "string",
"ratingReferenceId": "string",
"schemaVersionNbr": "string",
"sourceSystemEntCd": "string",
"transactionEffDtTimeStr": "string",
"transactionProcessedDtTimeStr": "string",
"transactionSubEntCd": "string",
"transactionTypeEntCd": "string",
"transactionUserId": "string"

8 REPLIES 8
richie
Community Hero

Hey @Rememo,

Theres a number of ways to do this.

However, to answer your question people will need to know the field length of each attribute you want to populate with any old string. Theres no point generating a random string with 10 digits in it, if the field only supports 8.

Once we have field lengths we can then look at how to do it, although probably easiest will be inline scripting....or maybe the datagen option in the DataSource teststep

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

Thanks.

 

The fields posted successfully with "string" so could you please provide an example of replacing "string" for all with random data containing 6 letters.  I know how to replace a Name/Address etc but that would be DataGen...  I don't want to have to reference the properties from DataGen.

 

For my example I would just need this..

"newBusinessRatingReferenceId": "arfyui",
"offerOriginChannelEntCd": "wordte",
"offerOriginSubChannelEntCd": "tyuugi",
"originalOfferOriginChannelEntCd": "jjiiop",
"originalOfferOriginSubChannelEntCd": "lopuil",
"ratingReferenceId": "string",

richie
Community Hero

Hey @Rememo 

 

Ok - I've worked out a way to do it - but it's not very elegant - I mean like - it's really awful coding - it does the job - but I hope @ChrisAdams or @nmrao dont see it!  🙂

 

I was hoping I could bodge an inline scripting property expansion, but alas - my groovy is rubbish hence my solution.

 

Ok - you're test case object hierarchy will need to be as follows (you have name value pairs in your example so I'm taking a guess on this is JSON/REST:

 

TestSuite

---TestCase

-----GroovyScript

-----Properties

-----REST (sources the 6 digit values)

 

 

Your Properties step will need a 6 properties created called 'randomString1', 'randomString2','randomString3', 'randomString4', 'randomString5', & 'randomString6',

 

Your Groovy step will need the following code:

 

 

 

//THIS IS REALLY HORRIBLE CODE - BUT WHAT DO YOU EXPECT?  MY GROOVY'S RUBBISH!
import org.apache.commons.lang.RandomStringUtils

//generate a 6 digit random string and assign to the randomString1 variable
String randomString1 = RandomStringUtils.random(6, true, true)

//define the properties step and write the randomString1 value to the Properties step
def propertiesStep1 = context.testCase.testSteps["Properties"] 
propertiesStep1.setPropertyValue("randomString1", randomString1)


//generate a 6 digit random string and assign to the randomString2 variable
String randomString2 = RandomStringUtils.random(6, true, true)

//define the properties step and write the randomString2 value to the Properties step
def propertiesStep2 = context.testCase.testSteps["Properties"] 
propertiesStep2.setPropertyValue("randomString2", randomString2)


//generate a 6 digit random string and assign to the randomString3 variable
String randomString3 = RandomStringUtils.random(6, true, true)

//define the properties step and write the randomString3 value to the Properties step
def propertiesStep3 = context.testCase.testSteps["Properties"] 
propertiesStep3.setPropertyValue("randomString3", randomString3)


//generate a 6 digit random string and assign to the randomString4 variable
String randomString4 = RandomStringUtils.random(6, true, true)

//define the properties step and write the randomString4 value to the Properties step
def propertiesStep4 = context.testCase.testSteps["Properties"] 
propertiesStep4.setPropertyValue("randomString4", randomString4)

//generate a 6 digit random string and assign to the randomString5 variable
String randomString5 = RandomStringUtils.random(6, true, true)

//define the properties step and write the randomString5 value to the Properties step
def propertiesStep5 = context.testCase.testSteps["Properties"] 
propertiesStep5.setPropertyValue("randomString5", randomString5)

//generate a 6 digit random string and assign to the randomString6 variable
String randomString6 = RandomStringUtils.random(6, true, true)

//define the properties step and write the randomString6 value to the Properties step
def propertiesStep6 = context.testCase.testSteps["Properties"] 
propertiesStep6.setPropertyValue("randomString6", randomString6)


//normally I give credit in any code I produce to whoever I ripped it off from - however - this is all my own, so I have to take the blame myself this time!

 

 

 

So each one of I think 6 name value pairs in your JSON PAYLOAD should source the values from the Properties step - so in your payload you should look something like this

 

 

"Attribute1": "${Properties#randomString1}",

"Attribute2": "${Properties#randomString2}",

"Attribute3": "${Properties#randomString3}",

"Attribute4": "${Properties#randomString4}",

"Attribute5": "${Properties#randomString5}",

"Attribute6": "${Properties#randomString6}",

 

So when you now execute the test - your 6 attributes in your payload will be populated by those 6 random string values sourced from the Properties step. 

 

So - as you can see - there's nothing elegant in the code, not iterating the same code or anything.   The groovy bods will probably be able to do the above in 4 lines of code - but that's them!

 

if you dont like the above solution (and I can understand if you dont! :)) - perhaps @ChrisAdams will sort you out!

 

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

Ah... I think I may have confused you with example... I didn't want to do it through the Properties step as that would just be creating replacements for a specific field then referencing them in the Json Payload. eg:

def firstName= generator( (('A'..'Z')+('a'..'z')).join(), 7 )
def lastName= generator( (('A'..'Z')+('a'..'z')).join(), 9)
def addressLine = generator( (('A'..'Z')+('a'..'z')+('0'..'9')).join(), 20)

 

If I have a 500 fields with "string" I don't want to have to define them all in a Groovy step!  

 

I was looking for an easy way to basically do a REPLACE ALL "string" with random data in the JSON payload

 

richie
Community Hero

Oh...so literally the fields have "string" in them and you want to replace them all?

You've already identified the groovy method to do this....replaceall() why dont you just use that and drop the random requirement....adding random values arent really gonna add all that much to the level of rigour in your tests anyway...

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

Hello @Rememo 

 

Here is an attempt at your solution.  Drop this into a groovy test step to exercise it and add a "Properties" test step to catch the resultant new json. Hack it up as desired.  There might be portions that are helpful to your final resolution...

 

import groovy.json.JsonSlurper;
import groovy.json.JsonOutput;

log.info 'Test Step "' + testRunner.runContext.currentStep.name + '" start...';
log.info "";

// embellished some sample json I had laying around...
def String jsonStr = """
[
  {
    "createDate": "2004-01-01T00:00:00",
    "endDate": null,
    "lastUpdateDate": null,
    "lastUpdateUser": null,
    "instanceCode": "CLAIM",
    "roleCode": "ALL",
    "roleName": "All",
    "newBusinessRatingReferenceId": "string",
    "offerOriginChannelEntCd": "string",
    "offerOriginSubChannelEntCd": "string",
    "originalOfferOriginChannelEntCd": "string",
    "originalOfferOriginSubChannelEntCd": "string",
    "ratingReferenceId": "string",
    "schemaVersionNbr": "string",
    "sourceSystemEntCd": "string",
    "transactionEffDtTimeStr": "string",
    "transactionProcessedDtTimeStr": "string",
    "transactionSubEntCd": "string",
    "roleType": "DEVELOPER"
  },
  {
    "createDate": "2004-01-01T00:00:00",
    "endDate": "2021-01-12T00:00:00",
    "lastUpdateDate": null,
    "lastUpdateUser": null,
    "instanceCode": "CLAIM",
    "roleCode": "BACK_OFFICE",
    "roleName": "Back Office",
    "newBusinessRatingReferenceId": "string",
    "offerOriginChannelEntCd": "string",
    "offerOriginSubChannelEntCd": "string",
    "originalOfferOriginChannelEntCd": "string",
    "originalOfferOriginSubChannelEntCd": "string",
    "ratingReferenceId": "string",
    "schemaVersionNbr": "string",
    "sourceSystemEntCd": "string",
    "transactionEffDtTimeStr": "string",
    "transactionProcessedDtTimeStr": "string",
    "transactionSubEntCd": "string",
    "roleType": "WEB"
  }
]
""";

def jsonSlurper = new JsonSlurper();
def jsonObj = jsonSlurper.parseText(jsonStr);  
log.info "jsonObj=$jsonObj";

// I don't know the extent of the depth of your actual JSON, so the sample I used contains two groups... You might have to 
// eliminate a depth on your actual (or add more).
jsonObj.each { depth ->
   depth.each { element ->
      log.info "elementBefore=${element.value}";
      if (element.value == 'string') {
         randomString = org.apache.commons.lang.RandomStringUtils.random(6, true, true);
         element.value = randomString;      	
      };
      log.info "   elementAfter=${element.value}";
   };
};

jsonNewStr = JsonOutput.toJson(jsonObj);
log.info "jsonNewStr=$jsonNewStr";
// make sure to have a "Properties" test step to have a landing area for the resultant new json content.
testRunner.testCase.testSteps['Properties'].setPropertyValue('jsonNewStr', jsonNewStr);

// The resultant json will be something like...
//[
//  {
//    "createDate": "2004-01-01T00:00:00",
//    "endDate": null,
//    "instanceCode": "CLAIM",
//    "lastUpdateDate": null,
//    "lastUpdateUser": null,
//    "newBusinessRatingReferenceId": "M7MzVq",
//    "offerOriginChannelEntCd": "oLU3Qe",
//    "offerOriginSubChannelEntCd": "QWV5O8",
//    "originalOfferOriginChannelEntCd": "7ydvd3",
//    "originalOfferOriginSubChannelEntCd": "OlHycp",
//    "ratingReferenceId": "DgEiM5",
//    "roleCode": "ALL",
//    "roleName": "All",
//    "roleType": "DEVELOPER",
//    "schemaVersionNbr": "R8w1WO",
//    "sourceSystemEntCd": "KuPtvJ",
//    "transactionEffDtTimeStr": "ujlqUr",
//    "transactionProcessedDtTimeStr": "UdD7se",
//    "transactionSubEntCd": "Sn8lRS"
//  },
//  {
//    "createDate": "2004-01-01T00:00:00",
//    "endDate": "2021-01-12T00:00:00",
//    "instanceCode": "CLAIM",
//    "lastUpdateDate": null,
//    "lastUpdateUser": null,
//    "newBusinessRatingReferenceId": "6LUM3g",
//    "offerOriginChannelEntCd": "71CyqS",
//    "offerOriginSubChannelEntCd": "WVDGbU",
//    "originalOfferOriginChannelEntCd": "zqOwZD",
//    "originalOfferOriginSubChannelEntCd": "fiUk22",
//    "ratingReferenceId": "ow6Sjg",
//    "roleCode": "BACK_OFFICE",
//    "roleName": "Back Office",
//    "roleType": "WEB",
//    "schemaVersionNbr": "vGwmld",
//    "sourceSystemEntCd": "nvdMQx",
//    "transactionEffDtTimeStr": "3vQ6L6",
//    "transactionProcessedDtTimeStr": "PrxZsV",
//    "transactionSubEntCd": "84dzvX"
//  }
//]

log.info "";
log.info 'Test Step "' + testRunner.runContext.currentStep.name + '" done...';

 

Regards,

Todd

sonya_m
SmartBear Alumni (Retired)

Thanks a lot, everyone! What a great thread.

 

Hi @Rememo, could you check if the solution works for you? 


Sonya Mihaljova
Community and Education Specialist

nmrao
Community Hero

It isn't so simple to achieve that.

 

Here is one library that can help to achieve the same.

https://github.com/HannnnXiao/javafaker

 

Apart from that, the trick is to create the custom classes based on the REST API specification and collect the each field data type and length restrictions from it instead of hard coded values. This way, even if there are changes in the API specification, one can quickly redo it.

 

It may take a while to fully create the library and plug it with Events so that when a new request step is created, data is automatically populated for the request. One need to see if this is really needed compared to time required to the above development.



Regards,
Rao.
cancel
Showing results for 
Search instead for 
Did you mean: