Forum Discussion

armygrad's avatar
armygrad
Contributor
10 months ago

Assertions

Hi, is there any way of comparing an assertion of what is returned to data held in a data source i.e. an excel spreadsheet.

  • You're almost there....

    Branch in brackets is undeclared, that's one issue.

    The other issue is that you're not pulling in the value from the test request response.

    You want to ensure that some value/node in your test request response matches some datasource value.  You have the datasource value in the variable datasourceDiary.  You need the one from the response.

    Use 'Get Data' to get the value of interest from the test request response.  If you call it 'valueFromResponse', then the IF would look like...

    if (datasourceDiaryRequest.contains(valueFromResponse) ) {

     The contains thing is a method that checks one string contains another.  E.g.

    
    "my source string".contains("source")   //returns true
    
    "my source string".contains("cat")   // returns false

     

  • ChrisAdams's avatar
    ChrisAdams
    Champion Level 3

    Hi,

    I do this all the time.  But, as Humashankar wrote you have options...

    Firstly where?

    • SmartAssertion : You could add a SmartAssertion to the test step. Whilst I haven't used this in anger, in the cell of interest in Valid Value, right-click.  From the context menu, select Get Data.  You should now have additional context menus that allows you to navigate to you test and the datasource step.
    • Script Assertion : You could apply a Script Assertion to the test step.  See later...
    • Groovy Script Step : In the past I've added a Groovy step after the test request step.  From here, I can access the test step and the data source and assert as I see fit.
    • Datasink and Groovy Scripts : The above are great for rapid feedback to spot a failure.  However, there is a price.  If you have a long running data-driven test, the whole test stops and fails on the first failed assertion.  This can be really frustrating.  For long running tests, use a different approach.  I create a Groovy Step that returns a PASS/FAIL string (more later).  In the Datasink step, I call the Groovy script step and the datasink saves the Pass/Fail in a CSV.  Once the test has finsihed, I load the CSV into Excel and I can see all my failures.

    Script Assertion Open the test step of interest, near the bottom of the screen there will be an Assertion tab.  Use the + to create a Script Assertion.  In the Add Assertion window, select Script.

    In the empty window, you can then write the script. Here, the Get Data functionality is your best mate. Use it to get the datasource value of interest and then get the value from test step and use assert to compare the two E.g.

    def datasourceCustomerName = context.expand( '${CustomerDataSource#CustomerName}' );
    def responseCustomerName = context.expand( '${Some REST Test Request#Response#declare namespace ns1=\'urn:some.domain:msrefdata:domain:1\'; //ns1:customerArray[1]/ns1:customerName[1]}' )
    
    assert datasourceCustomerName.contains(responseCustomerName);

    Groovy Script Create a Groovy step after your test request.  As with the Script Assertion, use get data to create the datasource value variable and the response value and compare.  It will look almost identical to the above.

    Datasink and groovy  Sorry, this will take a bit longer to explain, so I'll leave my response here.  If you're interest in this approach, then I'll take the time to explain in detail.

  • Humashankar's avatar
    Humashankar
    Champion Level 3

    Interesting problem statement to deal with - thanks for posting out here

     

    Hi - I hope that you are Doing good !!

    There are optiosn to achive this
    The data returned by an API call with data held in an external data source, such as an Excel spreadsheet

    -You can create Data Sources in SoapUI and link them to your test cases. 
    Then, you can use assertions to compare the response data with the expected values from your data source

    -write Groovy scripts to mimick data and perform custom assertions. You can write a Groovy script to read data from an Excel spreadsheet and compare it with the response data from your API call

    Hope this helps

    Thank you very much and have a fantastic day!
    Warm regards

     

  • If you could explain the data sink approach that would be Awesome thanks, my data source will have over a 100 rows.

    • ChrisAdams's avatar
      ChrisAdams
      Champion Level 3

      Hi,

      I can't build a real test, so you'll have to use your imagination.

      Here's a basic flow for a data-driven test....

      For each row in the datasource, we're going to call a Get Customer by Id service.  Imagine this returns a response that contains id, forename, surname and DOB for the customer with that id.

      We then 'check' the forename and the surname.  Not assert.

      Finally, we then persist some details using the datasink.

      Here's my datasource....

      Here is the Groovy for Check Forename...

      // Use Get Data to get the values from the datasource and response.
      def datasourceForename = context.expand( '${Data Source#forename}' );
      
      // This isn't valid, just an example....
      def responseForename = context.expand( '${Get Customer by ID - REST Requestt#Response#declare namespace ns1=\'urn:some.company:domain:1\'; //ns1:/ns1:forename[1]}' )
      
      boolean check = "FAIL";  // Initiaise our check variable
      
      if (datasourceForename.contains(responseForename) ) {
      	check = "PASS";
      }
      
      return check;

      Simply compare the datasource and response values and return PASS or FAIL as a string.

      You can imagine the content of Check Surname!

      Now the datasink.... I typically use File as the type.  Here's an example config...

      Note the values column above.  What I'm doing here is for each iteration of the datasource, I'm recording id, forename, surname and the results of the forename and surname check as a row in the CSV.

      Another hint, don't try and guess what to put in the value column.  Click (or maybe double-click) in the value cell and you can right-click and use your mate Get Data.  Note, when pulling from a Groovy step, you want the result, e.g.

      Once the test runs, you have a CSV with your test results.

      I typically use Excel then to import my results into a nicely formatted sheet.  E.g. red cells for Fail, green for Pass.

       

  • Chris

    many thanks this is great, just another quick question.if i wanted to groovy script the response would it be something like this.

    // My Thinking....
    def responseForename = context.expand( '${Get Customer by ID - REST Requestt#Response#declare error message}' )

    Again many thanks

    ArmyGrad

    • ChrisAdams's avatar
      ChrisAdams
      Champion Level 3

      Hi,

      Yes, it would be something like that.  But, do use 'Get Data' to do the thinking for you.  No trial and error, just select the nugget of interest and away you go.

      I've said it elsewhere, but Data Driven tests and Get Data are two of the most useful features in ReadyAPI.

  • Im getting an error from groovy, i dont know if im not declaring something

     

     

    • ChrisAdams's avatar
      ChrisAdams
      Champion Level 3

      It looks like you're trying to reference Branch, but it's undeclared.  Can you share the Groovy Script for context.

  • Thanks its pretty much your stuff, im not sure if its Branch as its named in the DAta  source or BranchCode thats in the json response

     

    • ChrisAdams's avatar
      ChrisAdams
      Champion Level 3

      You're almost there....

      Branch in brackets is undeclared, that's one issue.

      The other issue is that you're not pulling in the value from the test request response.

      You want to ensure that some value/node in your test request response matches some datasource value.  You have the datasource value in the variable datasourceDiary.  You need the one from the response.

      Use 'Get Data' to get the value of interest from the test request response.  If you call it 'valueFromResponse', then the IF would look like...

      if (datasourceDiaryRequest.contains(valueFromResponse) ) {

       The contains thing is a method that checks one string contains another.  E.g.

      
      "my source string".contains("source")   //returns true
      
      "my source string".contains("cat")   // returns false

       

  • Thank you so much

     

    Regards ArmyGrad There is a reason i am not a developer

    • ChrisAdams's avatar
      ChrisAdams
      Champion Level 3

      Me neither!  Just a tester who's picked this up along the way!

      I'm glad I was able to help though.