Forum Discussion
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
Assuming the data source content looks like this....
Customer ID | Customer Name |
1 | John |
2 | Paul |
3 | George |
4 | Ringo |
The Datasource would look like this....
The service call being exercised then needs to pick up the Customer Id to use in this iteration. E.g.
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.
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...
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%20Tests
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.
- ChrisAdams3 years agoChampion Level 3
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 Id Customer Name Credit Limit Sale Expected Credit Check Result 1 John 1000 800 PASS 2 Paul 900 1000 FAIL 3 George 800 200 PASS 4 Ringo 700 900 FAIL Update the Datasource to reference the new columns....
Remove the hard-coded assertions from Test Steps 001, 002, 003 etc. No screenshot here.
Add a groovy script step.....
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.
Then configure the datasink... Note how we pull the values from the datasource and the step that performs our check.
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.
- davecoleman3 years agoContributor
thanks for all the detail here. I'm going to work through some examples.
- richie3 years agoCommunity HeroHey 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
Related Content
- 3 years ago
- 3 years ago