Thursday, December 1, 2011

Going end-to-end with Soap UI

One cool thing we managed to do with Soap UI is create some real end-to-end tests. Many times you might test almost an entire feature. It simply takes to long to test it all, and you settle for some manual testing of those final things.
One example we had was a web service that, when called, would change the status of something in the database and then publish a file on a network share. Testing the database change is simple but the file part was too hard, or at least I thought it was...

My scenario looked something like this:

GIVEN an existing order
WHEN the order status is changed to "Processed"
THEN the order changes status to "Processed"
AND an event for "Processed" is published to an XML file

The Given means to setup something either using a Test Request step or a JDBC Step.
The When is the actual service call, a Test request step.
The Then we did by asking another service to give us the status of the order. But it could have been done by a JDBC step.
The And is the interesting part. That required a bit of Groovy script programming.

Checking that a file exists
This is dead simple in Groovy:
def file = new File(orderStatusFilePath);
assert file.Exists();

Finding the newest file
In my case I did not know the file name. I knew that I file would be published in a folder and that I had to grab the latest one. Maybe this is something bad in our design, but thats the way it is - how do we test it?

First, lets declare our search criteria. I want files that are at most 1 day old:
def today = new Date()
def criteria = {file -> today - new Date(file.lastModified()) < 1}

Then, I want to find the newest file. I always use a setting in my test suite for storing file paths. The actual searching might seem complex, but its really just a matter of listing the files that match our criteria, define how we want them compared, sort them using that comparison and take the last one. 

def orderStatusFilePath = 
        context.expand( '${#TestSuite#OrderStatusFilePath}' )
def xmlFile = new          File(orderStatusFilePath).listFiles().findAll(criteria).sort() {
   a,b -> a.lastModified().compareTo b.lastModified()

Its worth noticing that a File object in Groovy can point to a particular file or a directory. In my first example I located a single file. This last example used a file to locate a directory. I found this solution using Google for maybe half an hour, there is tons of material on Groovy out there!

Parsing XML
Just finding that file made me very happy - but not satisfied. Since it is an XML file, why not look inside and see that the correct status was set. That is the kind of testing you'll often do once or twice and then trust it works forever. By making it a part of the test suite, we'll know.

Groovy has some real good support for XML. First, create a parser based on our file contents.

def parsedXML = new XmlParser().parseText(xmlFile.Text)

Then, within that XML document, find the tag <Status> and get the text within.
def eventStatus = parsedXML.status.text()

And now - for the icing on the cake, assert!
assert 'Processed' == eventStatus

In conclusion
Testing service calls and databases has been part of our test suites in Soap UI in the past. But adding file checking and XML parsing really boosted those suites. They have now become real end-to-end tests. And I thought I saw a small tear in the eye of my test leader...

I have just begun to use Groovy test steps in my test suites but they seem really powerful. The only downside is that its hard for a non-developer to grasp the concepts in detail. But I think that if we name our steps using the Given-When-Then syntax, what lies behind the steps becomes less important.

But what if Soap UI came with this feature built-in? That would be sweet!

No comments:

Post a Comment