Beginning soapUI Scripting 5: Groovy Assertions

So far we've looked at a few scripting "containers" in soapUI-- components where you can easily insert Groovy script to extend or customize functionality-- including Groovy Script test steps and set up and tear down scripts at the test case and test suite levels.  In this post we'll look at Groovy Script assertions, which are useful in situations where soapUI's built-in assertions don't quite fit the bill.

Script assertions can be added to a test request through the standard Add Assertion dialog, launched from the test request editor window:



Test Request Editor (Add Assertion button outlined in red)

Once you select Script Assertion (listed in its own Script category) as the type of assertion you want to add, click the Add button and provide a name for your new assertion to bring up an empty Script Assertion window:



Script Assertion Editor

As with other scripting components, script assertions come with several built-in variables.  We've already seen the log and context variables with Groovy Script steps and set up and tear down scripts, but script assertions also come with the messageExchange variable, which provides quick access to request and response data.

Here's a quick example of some script assertion code based on the periodic table service I've used in other posts (you can download the very, very small project here to play around with the script assertion yourself). It essentially replicates the functionality of a standard Contains assertion, looking for the appropriate string in a response from the service's GetAtomicNumber operation for the element hydrogen:

responseData = messageExchange.getResponseContent() log.info(responseData) assert responseData.contains("<atomicnumber>1</atomicnumber>")
The first line grabs the content of the test request's response (as a string) and assigns it to the variable responseData; it also illustrates the convenience of the built-in messageExchange variable: we're able to access test request data with a single method call (I'll look at some of its other methods in a separate post in the near future). The second line is strictly for informational purposes; it just writes the responseData string to the script log.  The assert keyword is introduced in the second line.  It asserts that the expression following the keyword is true (in this case, we're asserting that the responseData string contains the correct atomic number for hydrogen. If the asserted expression is false, the assert statement (and consequently, the entire script assertion) fails.

The assertion as written should pass, but try changing the substring in the contains method to something else-- changing the atomic number to 2, for example.  You'll see that the assertion is flagged as a failure in the UI just as a standard assertion failure would be flagged:



Script Assertion Failure

15 comments:

  1. Hi. I have read your post and it was useful for me. For some cases, i need to validate if the response (i) is not containing a value for an xml element (ii) is not having a particular xml element itself. Please let me know how can i do it through the groovy script.

    ReplyDelete
    Replies
    1. It sounds like you may be able to do some of that through a standard XPath assertion (no need for a script assertion), but if you have to or need to do it in a script, take a look at soapUI's XmlHolder class, which contains methods that let you use XPath expressions in scripts. I'm planning on doing a post of this soon...

      Delete
    2. Ok thanks. I will wait for your post.

      Delete
  2. Mike.. request you to please add some post regarding assertion using XPath or XQuery

    ReplyDelete
    Replies
    1. That was something I promised a while back, but I had to find a suitable service to use. The periodic table service I use in my other posts uses CDATA extensively, which means it can't be used with standard XPath and XQuery assertions. But I think I've found a service I can use now, so I'll be working on that post. In the meantime, I recommend the XPath and XQuery tutorials on w3schools.com.

      Delete
  3. Hi Mike, your post are very helpful and most important they are working without any error unlike other blogs. I have a situation, where I need to use CSV to provide assertion value. As I do not want to keep changing the assertion through Soap UI instead I want to put the value of assertion in CSV and then read it. (Same as did in blog "soapUI: A Simple Data-Driven Testing Technique"). But, using '#' in assertion is giving me error. I request you to please suggest some solution for this:
    startup failed: Script17.groovy: 3: unexpected char: '#' @ line 3, column 48. ta.contains(" " + "${#TestCase# ^ org.codehaus.groovy.syntax.SyntaxException: unexpected char: '#' @ line 3, column 48. at org.codehaus.groovy.antlr.AntlrParserPlugin.transformCSTIntoAST(AntlrParserPlugin.java:97) at

    ReplyDelete
    Replies
    1. Hi Nitesh-- I'm not sure what's going on here-- could you post or send via the contact form the original code as it appears in your script (without the error message). I see:

      ta.contains(" " + "${#TestCase# ...?

      Is that all part of your script? One thing I see is that you're enclosing a soapUI property expansion expression (${#TestCase#...) within quotes... I'm not sure what your intention is there-- the expression will be treated as a literal string. If you're trying to get at a test case property within code you should use getProperty() or some other similar method instead of property expansion expressions. Further complicating things is the '$' in there, which has a special meaning in Groovy when enclosed within double-quotes (see this page: http://groovy.codehaus.org/JN1525-Strings and the section that starts "Anything more complex than a variable..."). I think that's the real source of your particular error-- the $ and { is encountered so soapUI is expecting a little bit of code enclosed in the braces. I don't believe the property expansion expression is a valid piece of Groovy code (you can use it in certain places in soapUI, where soapUI will recognize it and handle it, but Groovy alone can't make sense of it-- the # sign in particular).

      I think you might want to try something like...

      ta.contains(" " + testCase.getPropertyValue("NameOfYourProperty"))

      Note "testCase" may have to be something else depending on where you have this Groovy script-- there's a testCase variable available in Test Case setup scripts, for example; if it's somewhere else you may have to get to your test case's object some other way (through methods of the context variable, the testSuite variable, etc.).

      Delete
    2. Hi Mike, sorry for being not clear in my questions. Now, my code is working but let me explain what was the issue (
      After following your code sample I was using ${#TestCase#employeeID} in my response to pass the value from CSV. And, I was trying to do the use the same syntax in Assertion and that was giving me error.
      But now, I am first reading the value of deviceID
      deviceID = context.expand('${#TestCase#deviceID}') and then passing it in assertion as
      assert responseData.contains("" + deviceID + "") which is working now.

      Thank you so much for all these blogs and being active here. Your blogs are very helpful and very knowledgeable.

      Delete
  4. Hi ,

    Thanks a lot it really solves my issue what exactly i was looking.
    very usefull post :)

    ReplyDelete
  5. Hi
    can you please let me know how to use Not contains

    ReplyDelete
    Replies
    1. I'm assuming since you posted here that you're talking about simulating not contains in a Groovy expression (not the Not Contains Assertion available in the UI)? The not operator in Groovy/Java is just the exclamation mark ("!"). Putting it in front of an expression that evaluates to a Boolean (true or false) will negate the expression-- so if expression evaluates to true, !expression evaluates to false, and vice versa. So for example, take this expression: assert responseData.contains("myTestString"). If I wanted to validate that the string "myTestString" was NOT contained in the response, I could simply change it to: assert !responseData.contains("myTestString")-- note the added ! in there.

      It may go without saying, but one thing to watch out for when using these sort of negative checks (checking for the absence of some token, etc.) is to have some sort of extra check(s) to make sure your response is valid or what you'd otherwise expect. If you just take your response and check that a string's not there, then that assertion would still pass if the response is empty, if it's returning an error message, etc. You want to make sure you're still checking for those other possibilities, too-- don't depend on the negative check alone to validate the response.

      Delete
  6. hello MIke, I am trying to add response validation (assertion) using groovy and would you please help me.

    ReplyDelete
    Replies
    1. Could you try reaching out via the contact form with details of your problem? I can't promise anything, but I'll try to take a look.

      Delete
  7. Hi Mike, I was trying to add assertion for a quote id in my response which is an eight digit number and generated new everytime a new request is sent. I want to do specifically using script assertions.


    else if(scenarioName == "Send valid OneStepDeal data currency pair EUR-USD with receiving_method = Draft Buy Base"){
    responseData = messageExchange.getResponseContent()
    log.info(responseData)
    assert responseData.contains("40008473")

    This above script is good for me, I only need to add something instead of 40008473 to take variable digit everytime. Please help

    ReplyDelete

Please be respectful of others (myself included!) when posting comments. Unfortunately, I may not be able to address (or even read) all comments immediately, and I reserve the right to remove comments periodically to keep clutter to a minimum ("clean" posts that aren't disrespectful or off-topic should stay on the site for at least 30 days to give others a chance to read them). If you're looking for a solution to a particular issue, you're free to post your question here, but you may have better luck posting your question on the main forum belonging to your tool's home site (links to these are available on the navigation bar on the right).