cancel
Showing results for 
Search instead for 
Did you mean: 

Paramaterize the REST query parm NAME value rather than just the PARM value?

SOLVED
Community Hero

Paramaterize the REST query parm NAME value rather than just the PARM value?

Hey,

 

I have a number of GET requests with a number of query parameters that emulate an SQL query filter.

 

Essentially I have 4 namespaces (databases) with multiple datasets (tables) and my GET request retrieves this info - but there are a number of additional query parameter functionality available to allow the user to filter the GET accordingly.

 

the following is an example of one of the possible requests:

 

GET --> /api/1/{namespace}/{dataset}?attributename=value

 

The above query would equate to the following in SQL

 

select * from database.table where attributename = value;

Now this 'attributename' can be ANY field in the table - I want to be able to parameterize this 'attributename' - but I've only ever parameterized query parm values in SoapUI - not the actual parm names.

 

Please see the image to provide a bit more clarity

 

PARMNAME.PNG

 

 

As you can see - in the request I've setup - the query parm's name is 'attribute' - I woudl like some way to parameterize this so I can say do a GET  and return a record then do a property transfer grabbing the json node name rather than just the node value and populate the query parameter's NAME as well as the VALUE.

 

If I can't parameterize this - it means a lot of hardcoding requests in the projects section - and that seems an awfully inefficient way of doing things.

 

I hope Ive explained what I mean clearly!

 

I'm totally stumped and don't know if ReadyAPI! actually does include a facility for what I need.

 

thanks to all!

 

richie 

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
1 ACCEPTED SOLUTION

Accepted Solutions
Frequent Contributor

Re: Paramaterize the REST query parm NAME value rather than just the PARM value?

Hi @richie,

 

You may take a look at following solution if you're interested in it

// Step 1: create 4 folders with your properties file.
    // 4 folders named with your database name
    // each properties file named with your table name under current database
    ./namespace1/table1.properties
    ./namespace1/table2.properties
    ...
    ./namepsace4/table16.properties

// Step 2: create a config file to construct relationship of database and table
    // assume that namespace1 / table1 is name of database / table
    // (Example: the config file named with config.groovy)
    database {
        namespace1 = ["table1", "table2", "table3", "table4", "table5"]
        namespace2 = ["table6", "table7", "table8", "table9", "table10"]
        namespace3 = ["table11", "table12", "table13", "table14", "table15"]
        namespace4 = ["table16", "table117", "table18", "table19", "table20"]
    }

// Step 3: set global property (in test case level)
    testRunner.testCase.setPropertyValue("namespace_index", "0")
    testRunner.testCase.setPropertyValue("table_index", "0")

// Step 4: Groovy step to load config file and set property
    def index = context.expand('${#TestCase#namespace_index}').toInteger()
    def config = new groovy.util.ConfigSlurper().parse(new File('./config.groovy').toURI().toURL())
    def _map = config.database
    Map.metaClass.takeAt = {int num ->
        def keys = _map.keySet() as String[]
        def key = keys[num]
        ["$key": _map.get(key)]
    } //add a extension method to get a sub map
    def map = config.database.takeAt(index) // return a submap
    def namespace = map.keySet() as String[]
    testRunner.testCase.setPropertyValue("namespace", namespace[0]) //namespace name
    testRunner.testCase.setPropertyValue("namespaceMap", groovy.json.JsonOutput.toJson(map))
    testRunner.testCase.setPropertyValue("namespaceCount", config.database.size().toString())
    

// Step 5: Groovy step to set property of table
    def map = new groovy.json.JsonSlurper().parseText(context.expand('${#TestCase#namespaceMap}'))
    def key = map.keySet()[0]
    testRunner.testCase.setPropertyValue("tableCount", map.get(key).size().toString())

// Step 6: Groovy step to load properties file
    def props = new Properties()
    def map = new groovy.json.JsonSlurper().parseText(context.expand('${#TestCase#namespaceMap}'))
    def index = context.expand('${#TestCase#table_index}').toInteger()
    def tableName = map.entrySet()[0].value[index]
    testRunner.testCase.setPropertyValue("dataset", tableName)
    new File("./${tableName}.properties").withInputStream {
        props.load(it)
    }

    //remove property
    def teststep = testRunner.testCase.testSteps["Step7"]
    teststep.getPropertyList().each{
        if (! it.name.equalsIgnoreCase("namespace") || ! it.name.equalsIgnoreCase("dataset"))
            teststep.testRequest.removeProperty(it.name)
    }

    //add property
    for (p in props) { //set all properties into REST step
        testRunner.testCase.testSteps["Step7"].testRequest.setPropertyValue(p.key, p.value)
    }

// Step 7: REST step to query
    // parameterize "namespace" and "dataset"
    namespace = ${#TestCase#namespace}
    dataset = ${#TestCase#dataset}

// Step 8: Groovy step to control table loop
    def table_index = context.expand('${#TestCase#table_index}').toInteger()
    def tableCount = context.expand('${#TestCase#tableCount}').toInteger()
    def namespace = context.expand('${#TestCase#namespace}')

    if (table_index + 1 < tableCount) {
        testRunner.testCase.setPropertyValue("table_index", (++table_index).toString())
        testRunner.gotoStepByName("Step6")
    } else {
        log.info("Query all tables with parameters under $namespace")
    }

// Step 9: Groovy step to control namespace loop
    def namespace_index = context.expand('${#TestCase#namesapce_index}').toInteger()
    def namespaceCount = context.expand('${#TestCase#namespaceCount}').toInteger()

    if (namespace_index + 1 < namespaceCount) {
        testRunner.testCase.setPropertyValue("namespace_index", (++namespace_index).toString())
        testRunner.gotoStepByName("Step4")
    } else {
        log.info("Query all namespace done")
    }

 

Thanks,

/Aaron

View solution in original post

9 REPLIES 9
Frequent Contributor

Re: Paramaterize the REST query parm NAME value rather than just the PARM value?

Assumed that you have a lot of key-value pair as request parameter.

//Example

testRunner.testCase.testSteps[StepName].testRequest.setPropertyValue(ParamName, ParamValue)

 

Step 1: Load properties(key-value) or setup in script

Step 2: Send your query request with parameter

Step 3: Loop if need (remove previous parameter name if need)

//remove property
testCase.getPropertyList().each{
    testRunner.testCase.removeProperty(it.name)
}

 

 

Thanks,

/Aaron

Community Hero

Re: Paramaterize the REST query parm NAME value rather than just the PARM value?

Hi @aaronpliu

 

I dont know whether I'm being an idiot - but I'm missing something essential (my groovy code skillset comes from code snippets you guys provide -  and thats not an excuse - I try  - but I my groovy sucks - just need to make that clear!).

 

you are correct - I do have lots of different table's attributes and SQL operations  I need to specify as the query parms on my rest requests

 

You specify the following:

 

testRunner.testCase.testSteps[StepName].testRequest.setPropertyValue(ParamName, ParamValue)

QUESTION 1: so above line sets properties for a particlar request's step - right?

 

Your next instructions say as follows:

 

Step 1: Load properties(key-value) or setup in script

Step 2: Send your query request with parameter

Step 3: Loop if need (remove previous parameter name if need)

//remove property
testCase.getPropertyList().each{
    testRunner.testCase.removeProperty(it.name)
}

 

OK - I'm lost at the initial code snippet where you are setting ParmName, ParmValue on the test step. 

QUESTION2: Why are you setting the property values on the test step  - if step1 is loading in a lists of parmnames, values via a script etc? shouldn't i be getting them rather than setting them?

 

QUESTION3: I'm a bit confused on the test step hierarchy you envision - would it be something like the following?

 

Step1 - 'Properties 1' step (name=value pairing of the various parms and values)

Step2 - 'Groovy' step  as follows:

testRunner.testCase.testSteps[StepName].testRequest.getPropertyValue(ParamName, ParamValue)

Step3 - 'REST Request' step with usual template parms set as usual

Step4 - 'Groovy' step as follows:

//remove property
testCase.getPropertyList().each{
    testRunner.testCase.removeProperty(it.name)
}

 

QUESTION 4:  How would I tell ReadyAPI! that the parameters specified in the properties are actually query parameters and values rather than any other REST API parameter type?

 

I hope I've been  clear in my request.

 

 

Thank you!

 

richie

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
Frequent Contributor

Re: Paramaterize the REST query parm NAME value rather than just the PARM value?

Hi ,

Please see my comments for your questions.

QUESTION 1: so above line sets properties for a particlar request's step - right?

>>Right. that code snippets would be treated as a separate "Groovy" step or put it into "Setup Script" of certain REST step. If you need to dynamically setup a parameter in step request, then applied it. the precodition is that the "parameter" name is available for your request. Usually, all of request paramters should be loaded when you import your REST / SOAP which defined in source file, right?

QUESTION2: Why are you setting the property values on the test step  - if step1 is loading in a lists of parmnames, values via a script etc? shouldn't i be getting them rather than setting them?

>>This is based on your screenshot attached. assumed that you have a REST request with some parameters, and then you would like to dynamically set a parameter name once, you may need to "get" one of them and "set" it in your request, right? so in .setPropertyValue(paramName, paramValue), "paramName" is your parameter name, you should get it first.

QUESTION3: I'm a bit confused on the test step hierarchy you envision - would it be something like the following?

>>It depends on your requirement. if you want to run your REST request step with different parameter name / value

(Example)

TestCase Setup Script:

// initialize a property "index" for loop
testCase.setPropertyValue("index", "0")

Step 1: "Properties" step (it would load all key-value from external file or you added manually)

 

Step 2: "Groovy" step

//setup size of properties in order to loop run
def propsList = testRunner.testCase.testSteps["Properties"].getPropertyList()
def index = context.expand('${#TestCase#index}').toInteger()
testRunner.testCase.setPropertyValue("CountOfProps", propsList.size().toString())
// setup parameter for REST step
testRunner.testCase.testSteps["RestStepName"].testRequst.setPropertyValue(propsList[index].name, propsList[index].value)

Step 3: "REST" step

 

Step 4: "Groovy" step

def index = context.expand('${#TestCase#index}').toInteger()
def max = context.expand('${#TestCase#CountOfProps}').toInteger()

if (index + 1 < max) {
    // go to run step 2, here 'Groovy' name is step 2 name
    testRunner.testCase.setPropertyValue("index", (++index).toString())
    testRunner.gotoStepByName("Groovy")
}
// note that your "REST" step will be added more parameters, if you just want to run "REST" step with one parameter, then you need to "remove" others or setup empty

QUESTION 4:  How would I tell ReadyAPI! that the parameters specified in the properties are actually query parameters and values rather than any other REST API parameter type

 

>> if you added parameter, it's "query" by default. if you added as header, then you need to use:

(Example)
def stringMap = new com.eviware.soapui.support.types.StringToStringMap
def stringMap = new StringToStringMap()
stringMap.put('Cookie', 'xxxxxxxxxxx')
testRunner.testCase.testSteps[YourStepName].testRequest.setRequestHeaders(stringMap)

another parameter is in "path", it should be defined in source as a part of available endpoint.

 

Any enquires, please post your questions here, the community will notice it and more people to figure it out with different solutions.

 

 

 

Thanks,

/Aaron

Highlighted
Contributor

Re: Paramaterize the REST query parm NAME value rather than just the PARM value?

@aaronpliu @richie

I faced the similar issue while working on rest request parameters.

below are the observation:-

Scenario-1: we are already defined the property name in the params then we can easily set the value from testCase,testSuite,etc,

as well as by using the above groovy.

Scenario-2: we have to add the property name at runtime that can be done by groovy for that below step will be helpful.

  1) add the property name in the params by using below lines:

       req.addProperty(propertyName)

   2) then we are able to set the value for the property using below lines.

       req.setPropertyValue(propertyName,propertyValue)

 

here req is the instance of testStep that we want to update.

 

hope this will be helpfull !!.

 

Did my reply answer your question? Give Kudos or Accept it as a Solution to help others.Smiley WinkSmiley Happy

Community Hero

Re: Paramaterize the REST query parm NAME value rather than just the PARM value?

@aaronpliu &@ashu248

 

WOW guys - I'd give you more kudos if I could - I really appreciate you laying this all out for me - this is far more help than I'd expect - so thanks so much.

 

 

I'm gonna start putting a script together based on the response detail you've provided - but I have several follow up questions if that's ok?  I'll ask them one at a time.

 

Q1. Ok - As I mentioned before - my query parameters in my REST requests all correspond to either table.attributes and their values or certain operators (like '_count=15' limits the resultset to a maximum of 15 records) say I have a properties file with. If I am loading in a name/value pair properties file which corresponds to the QUERY PARMS on the GET request - what should I do in the 'Projects' section of ReadyAPI!

What I mean by this is typically within the 'Projects' tab, I would create my GET REST request with all the Template, Header and Query parms. But if I'm building the GET request Query parms via the name/value pairs in the properties file - how will this work?

 

e.g. my typical GET request will appear as follows:

 

GET --> /api/1/{namespace}/{dataset}?Table_AttributeName1=value&Table_AttributeName2=value

 

Bit of background info:
There are 4 namespaces (databases)
There are 25 datasets (tables)
Each table has between 30 and 60 attributes and I need to query each attribute at least once

If the query parms are created at runtime, this means that I simply need to specify the namespace and dataset template/URI parameters within the 'Projects' tab - rather than add in a huge list of query parms in the Projects section like I would normally when creating a GET REST request???

 

Cheers lads,

 

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
Frequent Contributor

Re: Paramaterize the REST query parm NAME value rather than just the PARM value?

Hi @richie,

 

You may take a look at following solution if you're interested in it

// Step 1: create 4 folders with your properties file.
    // 4 folders named with your database name
    // each properties file named with your table name under current database
    ./namespace1/table1.properties
    ./namespace1/table2.properties
    ...
    ./namepsace4/table16.properties

// Step 2: create a config file to construct relationship of database and table
    // assume that namespace1 / table1 is name of database / table
    // (Example: the config file named with config.groovy)
    database {
        namespace1 = ["table1", "table2", "table3", "table4", "table5"]
        namespace2 = ["table6", "table7", "table8", "table9", "table10"]
        namespace3 = ["table11", "table12", "table13", "table14", "table15"]
        namespace4 = ["table16", "table117", "table18", "table19", "table20"]
    }

// Step 3: set global property (in test case level)
    testRunner.testCase.setPropertyValue("namespace_index", "0")
    testRunner.testCase.setPropertyValue("table_index", "0")

// Step 4: Groovy step to load config file and set property
    def index = context.expand('${#TestCase#namespace_index}').toInteger()
    def config = new groovy.util.ConfigSlurper().parse(new File('./config.groovy').toURI().toURL())
    def _map = config.database
    Map.metaClass.takeAt = {int num ->
        def keys = _map.keySet() as String[]
        def key = keys[num]
        ["$key": _map.get(key)]
    } //add a extension method to get a sub map
    def map = config.database.takeAt(index) // return a submap
    def namespace = map.keySet() as String[]
    testRunner.testCase.setPropertyValue("namespace", namespace[0]) //namespace name
    testRunner.testCase.setPropertyValue("namespaceMap", groovy.json.JsonOutput.toJson(map))
    testRunner.testCase.setPropertyValue("namespaceCount", config.database.size().toString())
    

// Step 5: Groovy step to set property of table
    def map = new groovy.json.JsonSlurper().parseText(context.expand('${#TestCase#namespaceMap}'))
    def key = map.keySet()[0]
    testRunner.testCase.setPropertyValue("tableCount", map.get(key).size().toString())

// Step 6: Groovy step to load properties file
    def props = new Properties()
    def map = new groovy.json.JsonSlurper().parseText(context.expand('${#TestCase#namespaceMap}'))
    def index = context.expand('${#TestCase#table_index}').toInteger()
    def tableName = map.entrySet()[0].value[index]
    testRunner.testCase.setPropertyValue("dataset", tableName)
    new File("./${tableName}.properties").withInputStream {
        props.load(it)
    }

    //remove property
    def teststep = testRunner.testCase.testSteps["Step7"]
    teststep.getPropertyList().each{
        if (! it.name.equalsIgnoreCase("namespace") || ! it.name.equalsIgnoreCase("dataset"))
            teststep.testRequest.removeProperty(it.name)
    }

    //add property
    for (p in props) { //set all properties into REST step
        testRunner.testCase.testSteps["Step7"].testRequest.setPropertyValue(p.key, p.value)
    }

// Step 7: REST step to query
    // parameterize "namespace" and "dataset"
    namespace = ${#TestCase#namespace}
    dataset = ${#TestCase#dataset}

// Step 8: Groovy step to control table loop
    def table_index = context.expand('${#TestCase#table_index}').toInteger()
    def tableCount = context.expand('${#TestCase#tableCount}').toInteger()
    def namespace = context.expand('${#TestCase#namespace}')

    if (table_index + 1 < tableCount) {
        testRunner.testCase.setPropertyValue("table_index", (++table_index).toString())
        testRunner.gotoStepByName("Step6")
    } else {
        log.info("Query all tables with parameters under $namespace")
    }

// Step 9: Groovy step to control namespace loop
    def namespace_index = context.expand('${#TestCase#namesapce_index}').toInteger()
    def namespaceCount = context.expand('${#TestCase#namespaceCount}').toInteger()

    if (namespace_index + 1 < namespaceCount) {
        testRunner.testCase.setPropertyValue("namespace_index", (++namespace_index).toString())
        testRunner.gotoStepByName("Step4")
    } else {
        log.info("Query all namespace done")
    }

 

Thanks,

/Aaron

View solution in original post

Community Hero

Re: Paramaterize the REST query parm NAME value rather than just the PARM value?

Hey @aaronpliu

 

well if it isn't broke, don't fix it - so I'm happy to defer to your greater knowledge in this regard and steal your approach as it appears your approach is more efficient than what I would put together anyway!

 

I cant thank you enough - I don't know whether this is actually beyond me - I know this is pretty basic coding - but it still falls far outside my skillset. I'm hopeful I can apply what you provided - but it depends on the answer you provide to see if I can actually get my head around this or not.

I have a number of questions based on your approach if thats ok? I will BOLD the questions and also highlight in RED text too. I have specific questions on each of the steps listed in your response.  

 

I do however, understand if there are too many questions and this is just too much work for you to answer.

 

Considering the code snippet:

// Step 1: create 4 folders with your properties file.
    // 4 folders named with your database name
    // each properties file named with your table name under current database
    ./namespace1/table1.properties
    ./namespace1/table2.properties
    ...
    ./namepsace4/table16.properties

Q1.  Can you confirm that I create properties files that contain the tables?

Q2.  So your step 1 is to create 4 folders (1 for each namespace) and 1 properties file for each dataset/table - right?  Does the tableX.properties file contain name/value pairs of the table's attributes and attribute values for a single record?

Q3.  Can you please confirm that each tableX.properties file contains a name/value pair mapping of the attributes contained within the table and an example data record (e.g. so each attribute is mapped to a single record's value)?

 

Next question relates to the next bit of code:

// Step 2: create a config file to construct relationship of database and table
    // assume that namespace1 / table1 is name of database / table
    // (Example: the config file named with config.groovy)
    database {
        namespace1 = ["table1", "table2", "table3", "table4", "table5"]
        namespace2 = ["table6", "table7", "table8", "table9", "table10"]
        namespace3 = ["table11", "table12", "table13", "table14", "table15"]
        namespace4 = ["table16", "table117", "table18", "table19", "table20"]
    }

Q4.  So I create a flat file entitled 'config.groovy' and the contents of the file will be as follows?

database {
namespace1 = ["table1", "table2", "table3", "table4", "table5"]
namespace2 = ["table6", "table7", "table8", "table9", "table10"]
namespace3 = ["table11", "table12", "table13", "table14", "table15"]
namespace4 = ["table16", "table117", "table18", "table19", "table20"]
}

re: the following code snippet:

 

// Step 3: set global property (in test case level)
    testRunner.testCase.setPropertyValue("namespace_index", "0")
    testRunner.testCase.setPropertyValue("table_index", "0")

Q5.  Can you confirm that I create 2 custom properties on the test case.  1 entitled 'namespace_index' and set the value to '0' and 1 entitled 'table_index' and set the value to '0'??

 

re: the following code snippet:

// Step 4: Groovy step to load config file and set property
    def index = context.expand('${#TestCase#namespace_index}').toInteger()
    def config = new groovy.util.ConfigSlurper().parse(new File('./config.groovy').toURI().toURL())
    def _map = config.database
    Map.metaClass.takeAt = {int num ->
        def keys = _map.keySet() as String[]
        def key = keys[num]
        ["$key": _map.get(key)]
    } //add a extension method to get a sub map
    def map = config.database.takeAt(index) // return a submap
    def namespace = map.keySet() as String[]
    testRunner.testCase.setPropertyValue("namespace", namespace[0]) //namespace name
    testRunner.testCase.setPropertyValue("namespaceMap", groovy.json.JsonOutput.toJson(map))
    testRunner.testCase.setPropertyValue("namespaceCount", config.database.size().toString())

Q6.  The bottom 3 lines set properties.  Does this mean that I don't actually have to create the 3 properties on teh testcase and the script will do it for me?

 

On the 3rd line from the bottom it reads:

    testRunner.testCase.setPropertyValue("namespace", namespace[0]) //namespace name

Q7.  the commented //namespace name.  Are you saying replace 'namespace[0]' with the namespace name so it reads 'geography[0]' if namespace is 'geography'?

 

re: the code snippet:

// Step 5: Groovy step to set property of table
    def map = new groovy.json.JsonSlurper().parseText(context.expand('${#TestCase#namespaceMap}'))
    def key = map.keySet()[0]
    testRunner.testCase.setPropertyValue("tableCount", map.get(key).size().toString())

Q8.  Can you confirm what this is actually doing please?  I can see that you've expanded the namespaceMap property on the TestCase, but then you are setting a 2nd property entitled 'tablecount'.  Can you please explain what this is doing? 

 

re: the code snippet:

// Step 6: Groovy step to load properties file
    def props = new Properties()
    def map = new groovy.json.JsonSlurper().parseText(context.expand('${#TestCase#namespaceMap}'))
    def index = context.expand('${#TestCase#table_index}').toInteger()
    def tableName = map.entrySet()[0].value[index]
    testRunner.testCase.setPropertyValue("dataset", tableName)
    new File("./${tableName}.properties").withInputStream {
        props.load(it)
    }

Q9.  I can see the comment indicates that this loads a properties file - can you confirm what this snippet actually does please?  does it load tableX.properties files?  The final 3 lines makes me think it does load a specific tableX.properties file - each test will only hit 1 specific namespace/table.?

 

The last 3 lines are as follows:

    testRunner.testCase.setPropertyValue("dataset", tableName)
    new File("./${tableName}.properties").withInputStream {
        props.load(it)

Q10.  There are 2 instances of 'tableName' - do I replace these with the actually dataset/tablenames?

 

re: the following code snippets at the end of 'step6'

    //remove property
    def teststep = testRunner.testCase.testSteps["Step7"]
    teststep.getPropertyList().each{
        if (! it.name.equalsIgnoreCase("namespace") || ! it.name.equalsIgnoreCase("dataset"))
            teststep.testRequest.removeProperty(it.name)
    }

    //add property
    for (p in props) { //set all properties into REST step
        testRunner.testCase.testSteps["Step7"].testRequest.setPropertyValue(p.key, p.value)
    }

Q11.  Can you confirm what the '//remove property' snippet does please? yes obviously it removes a property - but why are you mentioning 'step7' in this?
Q12.  Can you confirm 'what property' it is actually removing?
Q13.  If I'm correct and the properties being added earlier at the tables' attributes (e.g. tableX.properties), does this mean that this is delete all the properties previously loaded in, earlier in steps?

 

Q14. Can you confirm what the '//add property' snippet does please?
yes I get that it adds a property - but I don't understand - surely the tableX.properties files have already been added in earlier in the script?

Q15.  the line ' testRunner.testCase.testSteps["Step7"].testRequest.setPropertyValue(p.key, p.value)' - can you confirm what 'p.key' and 'p.value' actually mean please?

 

I have a dataset entitled 'certificate-commodity-type' and this sources data from the [mdm].[vw_CertNom_CommodityType] table (its SQLServer).

 

re: the code snippets for steps 7, 8 & 9

// Step 7: REST step to query
    // parameterize "namespace" and "dataset"
    namespace = ${#TestCase#namespace}
    dataset = ${#TestCase#dataset}

// Step 8: Groovy step to control table loop
    def table_index = context.expand('${#TestCase#table_index}').toInteger()
    def tableCount = context.expand('${#TestCase#tableCount}').toInteger()
    def namespace = context.expand('${#TestCase#namespace}')

    if (table_index + 1 < tableCount) {
        testRunner.testCase.setPropertyValue("table_index", (++table_index).toString())
        testRunner.gotoStepByName("Step6")
    } else {
        log.info("Query all tables with parameters under $namespace")
    }

// Step 9: Groovy step to control namespace loop
    def namespace_index = context.expand('${#TestCase#namesapce_index}').toInteger()
    def namespaceCount = context.expand('${#TestCase#namespaceCount}').toInteger()

    if (namespace_index + 1 < namespaceCount) {
        testRunner.testCase.setPropertyValue("namespace_index", (++namespace_index).toString())
        testRunner.gotoStepByName("Step4")
    } else {
        log.info("Query all namespace done")
    }


Q16.  Can you confirm what these steps (steps7, 8 & 9) actually do please?

 

I am just trying to work out my test case object hierarchy using the steps you've provided.  The place I'm using aren't java/groovy coders - so fortunately (or unfortunately - I always like to learn new things) - I need to create the tests using the OTB functionality and only extend the existing OTB functionality using groovy script when absolutely necessary. I suspect you've done all the work in groovy - so I think I need to grab what I can from what you've done but create the tests using the OTB functionality.

 

 

Thanks man,

 

richie

 

With this in mind I am thinking that 

 

I initially the tableX.properties files for each of the datasets/tables I am querying.
I create a groovy.config file that indicates the different tables for each of the 4 namespaces.

I then have a groovy step containing step3, step4, step5, step6,

I then have a GET REST request grabbing certain attributes to build the Query parms on the GET.

I then have a follow up JDBC step to confirm the GET worked correctly (retrieves the data I expect)

 

Q17. Does that seem ok from  your greater understanding?

 

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
Frequent Contributor

Re: Paramaterize the REST query parm NAME value rather than just the PARM value?

@richie, there are so many questions from you. I'm sorry let you feel confusion. I really hope that the solution is best practice to you if my understanding is correct.

I'd like to explain more details to you but seems no more spare time to list it out one by one. [I may response to you if I am free Smiley Happy]

 

In my understanding, one test case, several test steps, including a REST step. then that's enough to run all of namespace / tables through loop structure.

 

Therefore, namespace (database) / dataset (tables) would be defined as properties file. each properties file including all attributes against one table.

(Exampe)
./namespace1/table1.properties

attribute1=123

atrribute2=abc

atrribute3=xxxxxx

...

These attributes will be loaded into REST step as query parameter (ie: /{namepace}/{dataset}?attribute1=123&attribute2=abc)

 

if you load different attribute from various tables, perhaps attribute is different. in order not to impact each other, remove all of attributes (keep namespace / dataset since they are in "path" as a part of API), then load again.

I know you want to parameterize PARAM NAME / PARAM VALUE, actually, you can load all attributes to REST step once, and populated value if need, otherwise leave as blank, it will not be a parameter in Request URL.

 

Some of properties defined in test case level is to as pre-condition to run via loop structure.

 

you need to add steps in your test case if follow my post, including "Groovy step" / "REST step", others are description.

 

 

Thanks,

/Aaron

Community Hero

Re: Paramaterize the REST query parm NAME value rather than just the PARM value?

Hey @aaronpliu

 

I need to think about what you've written and do a bit of googling.  I can create a framework without using yoru instructions - it just won't be efficient as I'll have to manually create a request for each permutation with a different table attribute defined a request parm in teh Projects section.

 

I'll do a bit of reading scrape the detail you've provided and see if I can put something together that allows me to dynamically build the query parms - I know I cant do this in the projects section so will need groovy for this - I should also higlight that I dont want multiple query parms - my requests will have a maximum of 3 query parms picked out from teh available table attributes.

 

as I say - I just need to think about this a bit - I'll never be able to use your method and the hard coding each request option in the Projects tab just isnt an option for me as its a rubbish way of doing it.

 

I'll close this post off and mark it as answered and then create a new one with a few specific questions once I've researched a bit.

 

thanks man,

 

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