Ask a Question

One Excel Datasource and Multiple Test cases using Specific Test Case ID within source

davecoleman
Contributor

One Excel Datasource and Multiple Test cases using Specific Test Case ID within source

Hi, I have the following excel source file 

Test Case IDCustomerID
test001Cust 001
test002Cust 002
test003Cust 002

 

I want to setup Testcases for e.g. Test002 that is picks up the value of "Cust 002" (which changes from day to day) and check the response via assertion that its correct.

 

how do I parse the excel file and find "test002" and input that value to that testcase only?

 

I would envisage the layout to be:

- Datasource

- "test001"REST step

- "test002" REST step

- "test003" REST step

- datasource loop

 

Looks like Groovy script is needed but there could be 100 testcases and associated data in the source file.

Thanks Dave

other examples with no answers: https://community.smartbear.com/t5/ReadyAPI-Questions/How-to-use-DataSource-and-DataSource-Loop-in-m...

https://community.smartbear.com/t5/ReadyAPI-Questions/One-datasource-Excel-and-Multiple-Test-Cases/m...

8 REPLIES 8
davecoleman
Contributor

Working through a Proof of concept i have come up with the below solution:

- A groovy script goes to each testcase as per the testcase Identifier in the data source.

 

davecoleman_0-1642074955749.png

Datasource excel

davecoleman_1-1642075012728.png

Groovy to decide on which step to go to:

import com.eviware.soapui.support.XmlHolder

def testcaseNo = context.expand('${Data Source#TestcaseId}')

log.info (testcaseNo)

if (testcaseNo=="test001")
{
log.info ("go to test step: " + testcaseNo)
testRunner.gotoStepByName (testcaseNo)
}
else if (testcaseNo=="test002")
{
log.info ("go to test step: " + testcaseNo)
testRunner.gotoStepByName (testcaseNo)
}
else if (testcaseNo=="test003")
{
log.info ("go to test step: " + testcaseNo)
testRunner.gotoStepByName (testcaseNo)
}
else if (testcaseNo=="test004")
{
log.info ("go to test step: " + testcaseNo)
testRunner.gotoStepByName (testcaseNo)
}
else if (testcaseNo=="test005")
{
log.info ("go to test step: " + testcaseNo)
testRunner.gotoStepByName (testcaseNo)
}

 

Groovy after each step to move to the loop and start again on next row:

import com.eviware.soapui.support.XmlHolder

testRunner.gotoStepByName ("Data Source Loop")
log.info ("moved to the Data Source Loop")

It will work for myself but there may be better solutions out there.

 

 

Hi Dave,

 

You have Datasource's which I guess means you have the licensed version of SoapUI.

 

Datasources and datasource loops are for data driven (aka functional) tests whereby you exercise one or more service calls using the datasource values as parameters for the service call(s).

 

The most simplest example might look like

ChrisAdams_1-1642084146795.png

 

Assuming the data source content looks like this....

Customer IDCustomer Name
1John
2Paul
3George
4Ringo

 

The Datasource would look like this....

ChrisAdams_2-1642084350134.png

 

The service call being exercised then needs to pick up the Customer Id to use in this iteration.  E.g.

ChrisAdams_0-1642085441794.png

 

The $ syntax above reads the current customerId value from the datasource.

You can type this directly, or use the nifty Get Data option.  Click in the Value cell and ensure the cursor is there.  Sometimes you have to double-click.  Then right-mouse click to open the context menu.  Select Get Data.

The Get Data screen allows you to navigate around your Workspace to select the value you want to pull in.  E.g.

ChrisAdams_4-1642084722097.png

 

If you've followed this far, you'll see that using the datasource and 'Get Data' you can exercise one service call with almost unlimited values.  You don't need separate service call test steps per row in the datasource.

 

You could then extend the test to call additional services to form sort of use case.  E.g.  Get Customer, Amend Customer, Customer places order.  Each step would be called once per iteration...

ChrisAdams_0-1642086085467.png

 

 

IMHO, the data-driven tests are the best feature of ReadyAPI and are definitely worth persevering with.

 

Here is a link to SMartBears own guide... https://support.smartbear.com/readyapi/docs/testing/data-driven/index.html?sbsearch=Data%20Driven%20...

 

That makes sense (and I use each day) if you want to use data from "Row 1" in each "Test Step Request".

 

but in my example, I will have different assertions for each "Test Step Request".

e.g. Row 1 data for Customer ID1 will have credit limit of 1000 and current sale = 1200 so ASSERTION is FAILED CREDIT CHECK.

Row 2 data for CUSTOMER ID 2 will have credit limit of 1000 and current sale = 900 so ASSERTION wil be to check that response is PASSED CREDIT Check. 

 

Each test step will have a different test result. I could create multiple Test cases in ReadyAPI but that would mean having multiple datasources to manage with 1 test entry in each excel. messy.

Ah, the assertions are hard-coded into each test step?

 

You could added the expected results to your datasouce; take out the hard-coded assertions from the test step and create a groovy script to perform the assertion on every iteration.

 

E.g.  Modify the datasource to include the params for each test and the expected result.

 

Customer IdCustomer NameCredit LimitSaleExpected Credit Check Result
1John1000800PASS
2Paul9001000FAIL
3George800200PASS
4Ringo700900FAIL

 

Update the Datasource to reference the new columns....

ChrisAdams_1-1642092632959.png

 

Remove the hard-coded assertions from Test Steps 001, 002, 003 etc.  No screenshot here.

 

Add a groovy script step.....

ChrisAdams_0-1642092465279.png

 

Open the Assertion Groovy Step and create you check.  Here's a pseudo-like example.

// Let's get the params and expected result for our test.
def customerId = context.expand( '${Customer Data Source#customerId}' )
def customerName = context.expand( '${Customer Data Source#customerName}' )
def creditLimit = context.expand( '${Customer Data Source#Credit Limit}' )
def sale = context.expand( '${Customer Data Source#Sale}' )
def expectedCreditCheckResult = context.expand( '${Customer Data Source#Expected Credit Check Result}' )

log.info("Testing Customer ${customerId} ${customerName}.  Credit Limit ${creditLimit}.  Sale ${sale}.  Expected Result ${expectedCreditCheckResult}.");

// Get the result of the credit check from the test step.
// Big assumption here, so this is just an example, but assuming the response from the SOAP Request contains the result.
// Use Get Data to find the path to the variable of interest...
def actualResult = context.expand( '${SOAP Test Request#CreditCheckResult}' );

// Assert!
assert (expectedCreditCheckResult == actualResult);

 

This assertion will use the data and expected result in current row.  No need for a test step per row because of assertions.  I think this achieves what you're asking for.

 

Going futher...

Worth noting, that if the assertion fails, the test stops.  You might only be 3 rows in out of a thousand and it's stopped.

 

I personally don't like this, so I go further.... Instead of the assertion, I check the result and use a datasink step to report this test row.  E.g.

 

ChrisAdams_3-1642093788191.png

 

Then configure the datasink...  Note how we pull the values from the datasource and the step that performs our check.

ChrisAdams_2-1642093760014.png

 

Lastly, update the Assertion step and make it return the result instead of the assertion.....

// Let's get the params and expected result for our test.
def customerId = context.expand( '${Customer Data Source#customerId}' )
def customerName = context.expand( '${Customer Data Source#customerName}' )
def creditLimit = context.expand( '${Customer Data Source#Credit Limit}' )
def sale = context.expand( '${Customer Data Source#Sale}' )
def expectedCreditCheckResult = context.expand( '${Customer Data Source#Expected Credit Check Result}' )

log.info("Testing Customer ${customerId} ${customerName}.  Credit Limit ${creditLimit}.  Sale ${sale}.  Expected Result ${expectedCreditCheckResult}.");

// Get the result of the credit check from the test step.
// Big assumption here, so this is just an example, but assuming the response from the SOAP Request contains the result.
// Use Get Data to find the path to the variable of interest...
def actualResult = context.expand( '${SOAP Test Request#CreditCheckResult}' );

// Assert!
//assert (expectedCreditCheckResult == actualResult);

// Let's not assert.  Just return the result.
if (expectedCreditCheckResult == actualResult) {
	
	return "PASS";
	
} else {
	
	return "FAIL";
	
}

 

So, for each row in the datasource, we can call our service.  We then run a check (or assertion) in the following step.  Finally, we can report out the result.  The result file will be the same as the datasource, but with the result of the check tagged on the end of each row.

 

This is actually my typical approach.  I can then import the text file into Excel and format it nicely.

 

 

thanks for all the detail here. I'm going to work through some examples. 

Hey @davecoleman,

I never bothered responding to this as @ChrisAdams was doing a cracking job and i couldnt have even come close to adding anything, but i just wanted to mention something in regards to your hardcoded assertions.

Obviously i dont know what youre asserting against in your responses, however if the testdata tests are changing everyday im guessing the expected results are changing everyday. With this in mind, i just wanted to highlight you can parameterise your assertions within the GUI, rather than hardcode them. I do this as much as possible (along with some other "tricks" (i.e. setup scripts, project/testsuite/testcase level properties, setup testsuites, reusable code, parameterisation) when creating a ReadyAPI project so i can lift and shift my ReadyAPI project to point at completely different environments with completely different data without having to change anything in project). If you know the assertion values for each testcase, you could include these in your Excel Datasource as an additional field for each test case. You could then parameterise your assertion to point to these values, removing the need to change hardcoded values.

Ok, that was all i wanted to mention,

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
sonya_m
SmartBear Alumni (Retired)

Thank you, Chris and Rich!

 

@davecoleman did you manage to make it work using the suggestions? Please let us know the solution you came up with🙂


Sonya Mihaljova
Community and Education Specialist

I haven't returned to this work since my last update @sonya_m . The approach is sound around the assertion comparison and I may have more questions at that time on completion of that.

cancel
Showing results for 
Search instead for 
Did you mean: