Tuesday, June 4, 2013

A SoapUI Plugin for Runscope

Another week - another cool API-related service! This time it's Runscope - a web application that basically allows you to record and replay API requests and responses that get routed through their platform - with a bunch of additional bells and whistles.  It was launched publicly at GlueCon a couple of weeks ago - and although I'm not quite sure of the use case I couldn't resist creating a very simple SoapUI plugin that easily lets you run your requests through their platform instead of directly to the target endpoint.

To run your requests through Runscope you simply need to modify the endpoint as described at https://www.runscope.com/docs - obviously an easy task for a SoapUI RequestFilter - let's get busy!

The Plugin Code


The plugin code is extremely simple; the main artifact is a SoapUI RequestFilter that modifies the request endpoint as described in the Runscope documentation. Since a bucket-id is required, the plugin looks for a Project-level property named "RunscopeBucket" - if it exists its value will be used accordingly.

The filter is written in groovy:


(see the latest version at GitHub)

The only other thing needed in the plugin is a listeners.xml file that adds this listener to the SoapUI RequestFilter Registry:


The project as a whole looks as follows in IntelliJ


and can be found on GitHub at https://github.com/olensmar/soapui-runscope-plugin.

In action


Download the plugin from sourceforge and save it into the SoapUI/bin/plugins folder - when SoapUI starts you will see the following in the SoapUI log:


Now add a "RunscopeBucket" property to your SoapUI project and set it to a valid Runscope Bucket identifier:


All requests in your project will now be sent through Runscope - and recorded by it for inspection, replay, etc. You can see the modified endpoint in the Raw tab of the request:



(and of course you can see the captured requests in the Runscope console)

Be cautious though; when I say all requests, I mean all requests - included those in a LoadTest, SecurityTest, etc. If you forget to unset the "RunscopeBucket" property you can easily fill up your bucket at Runscope in no time.

Runscope has the option of not forwarding your request to its target endpoint - so you can "debug" and record the outgoing request without loading the target service - to enable that add a property named "RunscopeCapture" to your project and set it to "true" - this will modify the outgoing endpoint accordingly.

Wrapping up!


That's it - nice and easy. Download the plugin from sourceforge and have a go - let me know if you have any issues or want any improvements!

Thanks,

/Ole

Monday, May 27, 2013

SoapUI + Swagger = true!

Since I published the original version of the soapui-swagger-plugin in late 2012, Swagger has continued to gain traction within the API community. For those of you not familiar with Swagger, it's a metadata format for describing the ins and outs of a REST API - much like WSDL is for SOAP APIs - have a look at the Swagger website to learn more.

The initial version of the plugin allowed you to import Swagger definitions into SoapUI - making it extremely easy to send ad-hoc requests, create functional tests, load tests and API monitors for the Swagger-described API (and all for free!). When discussing the plugin with some users at APIStrat earlier this year, they requested the possibility to be able to export Swagger definitions as well, i.e. if you have a REST API defined in SoapUI - they wanted to be able to generate a corresponding Swagger definition that they (for example) could use with swagger-ui to provide your customers an online tool for trying out your API.

Obviously I couldn't resist the challenge, and although its taken me some time I'm happy to finally announce version 0.2 of the plugin that does exactly that; exports Swagger definitions for any REST API defined in SoapUI - which has some cool usage scenarios. Let's dive in.

REST APIs in SoapUI


Despite its contextually unfortunate name - SoapUI has had good support for testing REST APIs since 2008 (!). REST support was initially modeled around the WADL specification (an initial attempt at providing metadata for REST APIs) - fortunately the object model in Swagger plays pretty well with WADL, which makes the Swagger import/export feature in the plugin play seamlessly with SoapUIs REST support.

Exporting Swagger Definitions


Exporting Swagger definitions using the plugin is straightforward; make sure you have at least one REST API defined in your SoapUI project and right-click the project node in the SoapUI navigator; the popup menu now has an "Export Swagger" menu option:



Select it to bring up the following dialog:


The settings are as follows:

  • APIs : select which REST APIs in your project that you want to include in the generated Swagger definition
  • Target Folder : where to generate the files
  • API Version : the value for the api-version property in the generated definitions
  • Base Path: the base path that the generated resource listing will be hosted on. This is important to get right as API declarations are resolved relative to this (see example below)
  • Format : which format to use; Swagger technically supports both json and xml, although I would guess 99% of its users are using json at this time :-)

Press the OK button when you've set the options as desired; SoapUI will work a little and prompt you with the path of the generated Swagger resource listing. This is ready to go; feed it into any other tool that supports Swagger - for example you can use swagger-ui to provide a nice online UI for exploring the described API (see example below).

Usage Scenarios


Although the primary usage scenario may be the one described further down in this post - generating Swagger definitions for hosting them with swagger-ui - you could of course use the export feature of the plugin for things like:

  • WADL to Swagger conversion; if you have API definitions in WADL format you can simply import them into SoapUI (using the regular Add WADL functionality) and then export them as Swagger definitions with this Plugin
  • Swagger-creation; if you need a visual tool to build Swagger definitions "from scratch" you can use SoapUI to define your REST API which you can then export.


Hosting Swagger definitions with SoapUI


One thing you might want to do is provide your API users with a nice browser-based UI for trying out your API - which is precisely what the swagger-ui project is for (also from the Swagger folks). You can download swagger-ui from GitHub and just open it from your local file system in your browser - which will start you with something like:

(by default it displays the sample petstore Swagger definition)

Now how do you get swagger-ui to read the resource-listing generated by SoapUI? Unfortunately swagger-ui doesn't support file-based URLs so we need to do a bit of trickery with SoapUI to expose our Swagger for swagger-ui; the MockService functionality in SoapUI can be used as a miniature web-server, which is just what we need here (if you have a local web server running you can of course use that instead).

Start by creating a MockService in your SoapUI project via the Project menus "New MockService" option. Once created - double-click it to open the MockService window and select the "Options" button - which will bring up the following dialog:




Set the docroot to point at the folder where you generated the Swagger definition, configure the port as desired (so it doesn't collide with anything else you might be hosting on your machine), press OK and start the MockService with the "Run" button in the top-left corner of the MockService window. You now have a mini webserver running, ready to serve any documents you have in the specified docroot folder, but before we can use swagger-ui with it we need to make sure the MockService adds some HTTP Headers that swagger-ui expects. Select the "OnRequest Script" tab in the MockService window and enter the following:

mockRequest.httpResponse.addHeader( "Access-Control-Allow-Origin", "*" )
mockRequest.httpResponse.addHeader( "Access-Control-Allow-Methods", "GET, POST, DELETE, PUT" )
mockRequest.httpResponse.addHeader( "Access-Control-Allow-Headers", "Content-Type, api_key, Authorization" )

In SoapUI, this looks as follows;




Let's go back to the dialog for Exporting Swagger definitions and configure it accordingly:




Please note that Base Path configuration above matches the local ip that the MockService is running on (so the path can be resolved) and the Target Folder is the same as the docroot for the MockService configured above. Once exported we're all set; open a web-browser and enter "http://127.0.0.1:8181/api-docs.json" (change the port accordingly) - which should bring up the Swagger resource listing we generated above;




Now back to swagger-ui; paste the same endpoint in the URL field and press the "Explore"; swagger-ui will work a bit and presto, you should get something like the following;



Awesome - we've created Swagger definitions for some of the Google Maps APIs and can now do some simple API invocation from within swagger-ui!

Changes to the Import Swagger feature


The "Import Swagger" feature has been improved a little since last; the dialog invoked by the corresponding menu item now looks as follows:




Here you can now specify to import Swagger API Declarations directly (instead of always having to provide a Resource Listing) - which can come in handy for some of the API-mgmt platforms out there that provide API Declarations directly (APIHub for example).

A bonus under the hood: swagger4j


Version 0.2 of this plugin needed a more robust way to read and write Swagger definitions than the groovy scripts that were used in version 0.1 to just read them. I've separated this into a separate java library - swagger4j - which has no dependencies on SoapUI whatsoever and can as such used within any Java program that needs to read or write Swagger definitions. It's open-source (Apache licensed) and available over at GitHub - check it out, and don't hesitate to give me feedback so I can improve that as well.

Installation


Installing the plugin is straight forward; download it from sourceforge or build it yourself with maven (it's on GitHub). The download from sourceforge contains the required dependencies - all you have to do is unzip it into your SoapUI/bin folder.If you build it manually you will have to add these dependencies yourself to the SoapUI/bin/ext folder:


Next Steps

So what's next? You tell me! Please get in touch if you want to see any specific fixes, improvements, etc - I'd love to hear from you.

Thanks,

/Ole


Tuesday, March 5, 2013

Another #APIStrat Conference Recap

I had the great pleasure of attending the APIStrategy Conference in NY together with @lindybrandon and @davidyaches from SmartBear a little more than a week ago - it was a great event with a good mix of topics, people, discussions and hangouts. I've tried to sum up some of the stuff that has stuck with me over the following days – hopefully you will find some interesting tidbits in there.

Lots of Passion 


This is my major take-away from the conference; the API community is having a blast! Geeks, hipster coders, architects, business developers, senior marketers, sales and product owners - they were all there gathered for the feast - and they were feasting together. Historically I have often seen a divide; geeks are passionate, business is skeptical- or business is raving and the geeks don't get it. Here though they are all rowing in the same direction - helping and complementing each other - it was awesome to behold, and holds great promise for future developments in this movement.

Of course - there was quite a lot of competition as well. For example the panel discussions on API Management and PaaS sometimes had a "mine is bigger than yours" component that was quite enjoyable for the audience - but surely challenging for the participants. The players are both startups and existing enterprises that have adapted their offerings to the API space, both have their pros and cons; who will win in the end is definitely still out in the open.

Swagger FTW


Swagger is a metadata format for describing REST APIs, and as such it can be used to generate code, documentation, tests, mocks, etc. It's an open-source project created by the wordnik folks, now hosted by a spinoff named Reverb. When I first encountered it a couple of months ago I was a bit surprised given the existence of WADL which is an older standard that solves all the same problems. Given the situation at hand, Swagger has definitely succeeded where WADL has failed; it has been adopted by many of the API management and tool vendors at the conference, and it’s looking to be the primary choice for many REST projects out there (based on my experience talking to SoapUI users both at the conference and besides).

There are probably many reasons for its initial success (apart from a cool name); it is based on actual API usage, has a tooling ecosystem, prefers JSON and the Swagger-UI just looks great. WADL on the other hand is "just a spec", sounds suspiciously like WSDL and lacks the "underground appeal" of the Swagger community. Hats off to the Reverb team – hopefully they can govern and evolve Swagger in line with trends in the API community.

Academically, I find it interesting that a metadata format catches on at all in the REST community; much of the initial driver behind REST was to move away from metadata and specifications, and while the more biblical REST crowd talks about hypermedia APIs as a means to avoid metadata and tight coupling between client and API - the pragmatic users seems to realize the benefits of metadata in an enterprise setting (more on that below). In the end, I think whatever the API community finds best solves their problems to "get the job done" will prevail.

The religion of REST - and beyond


REST has been around for a while now - the original dissertation by Roy Fielding was published in 2001 - but it didn't really catch on until developers got fed up with the proliferation of WS standards and needed a much simpler way to consume data in the client AJAX applications around 2007-2008. Recent developments within the core REST community have me worried though; talking about "REST maturity levels" and "real REST" while quoting Mr. Fielding’s dissertation as their holy parchment gives at least me a bitter aftertaste; many of the current REST adoptions and APIs are perfectly fine and provide excellent value to their users even if they don't follow HATEOAS principles or use something like HAL to expose hyperlinks. If you're providing APIs I suggest you approach these with a grain of salt, the main goal of your API is to swoon its users, not follow design principles (although these could of course complement each other).

Back to the conference; while there was a lot of talk about the promise and implementation of hypermedia APIs and HATEOAS principles, the Netflix story told by Daniel Jacobson took things to the next level; REST wasn't a good fit for them as it put too much overhead on their client applications (tailored to 800 different clients!) which assembled their pages from a multitude of REST APIs. Their solution was to create an "orchestration layer" on the backend that assembled data from the internal APIs into what they called an "experience API". This was consumed by the device and exposed data selected specifically for that user – and as this API didn't follow any REST principles it doesn't qualify as such - it's just an API that works.

Incidentally - if you are old enough to remember (like I am) - this is similar to the move from RPC style web services to document style that happened around 10 years ago; instead of making multiple smaller calls to assemble a final result, the actual orchestration logic of all those pieces was meant to be done in one go on the server and returned in one document.

The Enterprise strikes back


So this is an interesting (but not totally unexpected) development; first, the coder community got tired of enterprise madness and SOAP and adopted REST as a means to actually deliver something of value within a reasonable time-frame. The enterprise SOA shops chugged along with their SOAP-based SOA projects, but eventually they started to realize that APIs are actually good for them too. This was not just from a technical point of view, but even more as a business enabler - allowing to bring their products to a whole new group of consumers (via APIs). Unfortunately though, the REST-based API community lacks solutions for some key requirements for many enterprises;
  • Security; transport-level security provided by SSL is far from enough for health care, banking, etc - how does REST support persistent signatures and encryption!?
  • Governance and Policies; how can enterprise APIs be governed through their entire lifecycle? Laura Merling from AT&T gave a great talk on how they are creating APIs with governance in place, and Lorinda Brandon wrote a great piece on the subject, check it out: Governance vs Innovation
  • Transactions and Reliable Messaging; is HTTP good enough for messaging requirements that are beyond request/response? What alternatives are there?

Many of the talks at the conference highlighted the need for solutions to these problems - and I'm sure they can be solved, I'm just hoping that we in 3 years’ time won't have the same WS-(death star) mess that the SOAP community got into when the major vendors initially tried to solve these problems on their own, and then got together in extremely sluggish committees to try to unite the standard into a common one.

SoapUI does REST damnit!!


I guess this is a little off-topic but I'll take the opportunity; several people I talked to at the conference regarding testing of their APIs with SoapUI squarely countered with "we don't do SOAP". <rant>This is so frustrating! SoapUI has had extensive REST support since version 2.5 released in 2008; resources, HTTP Verbs, representations, parameters, URL-templates, JSON, XML, content-negotiation, security, you name it. You could easily set it up to test true hypermedia APIs and now there is even a swagger plugin that allows you to import swagger definitions, and given all its other testing features (and that it's actually free) it should definitely be part of an API testing strategy </rant>.

Thank you!


I’ll end with a huge thanks to all at the conference for their presence and passion, and an extended thanks to Kin Lane for his insightful and extremely knowledgeable apievangelist.com blog and his commitment to the API movement. Hope to see you all at the next conference – please share your thoughts on the above and the conference in whatever medium you find appropriate.

/Ole
@olensmar


Tuesday, February 12, 2013

A groovy console for SoapUI

The never-ending quest for somewhat useful SoapUI plugins has come to a Groovy Console plugin - allowing you to run arbitrary groovy code from inside SoapUI. Why would you want to do that? Read on and find out.

Preamble


Quite often I've found myself in a scenario where I wanted to automate certain actions in SoapUI, for example the creation of a template project or TestCase, initialization of some properties in a certain way - or preparation of some external database. SoapUI already has pretty extensive scripting support - but these scripts are all event-driven, ie they occur before or after something happens in SoapUI, for example before the execution of a TestCase, or after a project loads. Wouldn't it be nice to have a "playing ground" for exploring the SoapUI object model and executing arbitrary groovy scripts? Mais oui!

Integrating the Groovy Console


Fortunately, groovy already contains a pretty complete Console implementation, the Groovy Console. It allows you to do just what I needed; run arbitrary scripts - load/save these from a file - inspect their results, etc. Since the console is swing component that can be easily embedded and configured in any swing application, putting it into SoapUI was pretty straight-forward. I opted to add a "Groovy Console" action to the popup menus of the Workspace, Project, TestSuite and TestCase nodes in SoapUI - the corresponding consoles will have these objects available for scripting.

From a code-point-of-view this follows the model of the previously created SoapUI plugins described earlier. The only caveat specific to this plugin was the handling of removal of objects and closing of projects, which is done by registering the corresponding listeners to catch these events. To avoid memory leaks, these listeners have to be released accordingly - have a look at the code at GitHub if you are curious how this is done.

The Result


As mentioned above - a "Groovy Console" menu option has been added which opens the corresponding Console in a standalone window;



Here you are free to type and run any scripts using the SoapUI API, and since we opened the console from the Workspace menu, a workspace object is available (as mentioned above, corresponding project, testSuite and testCase objects are available in the consoles opened from their objects menus).

Let's walk through a simple example.   Create an empty workspace (via the File menu) and open the Groovy Console from the workspaces right-click menu. In the console type the following;

project = workspace.createProject( "My Project", null )

press Ctrl-Enter and you will see a new project popping up in the Workspace:





Now let's add a TestSuite, TestCase and HTTP TestStep;

testSuite = project.addNewTestSuite( "TestSuite" )
testCase = testSuite.addNewTestCase( "TestCase" )
testCase.addTestStep( "httprequest", "HTTP Request" )

You will notice that when adding the TestStep a dialog will show up to fill in the endpoint for the TestStep.

Now open the TestCase window and run the TestCase (via scripting):

com.eviware.soapui.support.UISupport.UISupport.showDesktopPanel( testCase )
testRunner = testCase.run( null, false )

finally - lets show an alert with the run status:

com.eviware.soapui.support.UISupport.showInfoMessage( "TestCase finished with status $testRunner.status" )

You can easily save all this to a single file which you load and run as required - I've put it on Gist for you to marvel at :-)

Quirks


The integrated Groovy Console has some quirks that you should be aware of; opening another window via its File Men will create a Console that is "decoupled" from the SoapUI object model. Also - Console windows are not always closed correctly - depending on how you remove/close their corresponding objects containing project. I'll get back to fixing these (and any others you might find) if there is enough interest/nagging - be sure to let me know!

That's it


Download the plugin from here and save it to your soapui\bin\plugins folder (and restart SoapUI). The source code is at GitHub. SoapUI can as always be obtained from http://www.soapui.org.

Have fun exploring SoapUIs groovy APIs - and don't miss the great groovy webinars by the SoapUI team;
- Let's get groovy Webinar
- Let's get groovier Webinar

And please let me know if you have any troubles, suggestions or comments!

thanks for your time!

/Ole



Thursday, February 7, 2013

A ProgrammableWeb plugin for SoapUI

The ProgrammableWeb is one of the major players in the API-directory space - wouldn't it be neat if you could browse their directory from inside SoapUI and import an API directly into your SoapUI project from there? Of course it would! Let's get right to it and create a simple plugin for SoapUI that lets you do just that.

Prerequisites


The API directory at programmableweb.com holds at the time of writing over 8000 APIs in its database, and although the majority is based on REST principles, over 1800 are actually still using SOAP. Since SoapUI can easily import the WSDL for a SOAP based API to allow you to do some ad-hoc explorations of the APIs operations, let's add a dialog to SoapUI that allows you to browse those SOAP-based APIs and import them into SoapUI. Of course SoapUI could import REST APIs as well if they had WADL or swagger definitions, but since the ProgrammableWeb directory doesn't expose links for these metadata formats, we'll have to stick to SOAP/WSDL for now.

My initial thought was to use the ProgrammableWeb Atom-based API for browsing and extracting all SOAP APIs in their directory, but unfortunately the API currently has no easy way to search for these APIs, I would basically have had to go through the entire directory, page by page, (remember, over 8000 APIs) and manually extract those of interest. Instead, I opted to do something I never thought I would do, "screen-scrape" the web interface of programmableweb.com - which is of course extremely fragile since any change to the underlying HTML will make the plugin useless, but on the other hand - the URL http://www.programmableweb.com/apis/directory/1?protocol=SOAP returns a nicely formatted list of all SOAP APIs in the directory - making things so much easier. As an added advantage, this approach does not require me (or anyone else using the plugin) to have a ProgrammableWeb API key, as we are just extracting data and not making modifications.

Enough talk - let's look at how this baby actually works:

In Action


Before we dive into the code, here comes a screenshot of the actual dialog invoked from a new "Add API from ProgrammableWeb" action on the project popup menu:


As you can see you select one of the API categories on top and the list under will contain all SOAP APIs in that category. The WSDL endpoint for the API is shown at the bottom - pressing OK will import the WSDL directly into SoapUI for further exploration:


I've posted a short video of this in action further down - let's just have a quick look at the code first.

The plugin code


The plug-in code is straight-forward - just like the soapui-swagger-plugin I published a couple of weeks ago. I'm not going to go through all lines of code (you can do that on GitHub, see below), just highlight a few things.

First, the project structure:


As you can see this is a maven project using both groovy and java. The main reason for using groovy was (once again) its superiority when it comes to parsing; the GPathResult returned by the HTTPBuilder for the ProgrammableWeb HTML pages is easily searched for the relevant information. For example the following code is used to load the SOAP API listing and extract all the APIs into a Map of categories to collections.


And the code for extracting the WSDL from an APIs detail page is equally simple:


The remaining code in the AddWsdlFromProgrammableWebAction class is mainly boilerplate code for setting up the form and initializing its data. Since the form is created only once SoapUI will have to be restarted for new APIs to show up in these lists.

A very short video


Ok, here comes a short video showing you how this actually works;



Nice - isn't it!?

Download and installation


Installing the plugin is straight-forward, download it from here and drop it in the soapui\bin\plugins folder (you will need at least SoapUI 4.5 - download from http://www.soapui.org). Also you will need to add the http-builder-0.6.jar and xml-resolver.jar files to the soapui\bin\ext folder - which are needed for loading and parsing the HTML pages. If your're on a Mac you can find or add these folders "inside" the application bundle, presumably at /Applications/SmartBear/soapUI-4.5.1.1-SNAPSHOT.app/Contents/Resources/app/bin.

SoapUI will load these during startup, as seen in the SoapUI log:


Wrapping up



That's it - check out the code at GitHub (https://github.com/olensmar/soapui-programmableweb-plugin) - and have fun with the plugin - and please don't hesitate to comment, suggest or complain :-)

Thanks for your time,

/Ole

Thursday, January 31, 2013

Having fun with Cucumber, Groovy, Jacob, COM, TestComplete and Notepad

Finally I've had some more time to explore new stuff - and since BDD is steadily gaining in popularity I thought I'd try to see how one could achieve BDD with TestComplete - SmartBears indispensible tools for web and GUI testing. And even if you're not interested in TestComplete - please stay with me as I will use a bunch of other cool technologies on the way (as indicated by that seductive title).

The Cast


The main characters in this blog-post are:

  • BDD (Behavioral Driven Development) is an extension of TDD where you define behaviours in an agreed-upon vocabulary and use these to drive your tests (greatly simplified) - read more about the whole idea at http://dannorth.net/introducing-bdd/
  • Cucumber is one of the more popular BDD frameworks out there - here we will be using the java version (Cucumber-JVM) with its integrated support for the groovy language
  • Jacob is an open-source library that makes it really easy to call COM objects on the .NET platfrom from Java - and specifically from groovy via the scriptom library.
  • TestComplete is SmartBears premier tools for automated testing of Web and Desktop applications (for MS platforms)
  • Notepad is the text editor that we all resort to once in a while
Of course several of these could be replaced with others; Cucumber with JBehave, TestComplete with any application that can be automated over COM (Word, Excel, Outlook, you name it) - and notepad with anything you might want to test with TestComplete; your website or a desktop application for example.

The feature definition


I started out by using cucumber and BDD for specifying a simple feature scenario - here it comes in cucumber lingo:


In cucumber (and most other BDD frameworks) you express your requirements in a Given/When/Then kind of syntax - reasonably legible by both business and developers. Agreeing on the vocabulary used in these files is probably one of hardest parts in BDD - and there is much written about it - in this case I've chosen an imperative approach which skips the nitty-gritty steps of the underlying actions (read more about Declarative vs Imperative at http://benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories.html)

The groovy cucumber code


The next step is to write the code that will be invoked to execute these "steps". Cucumber has a nice groovy integration which makes the code pretty straight forward - here it is:



As you can see there are handlers for Given, When and Then "events" in the feature file - these are "found" by cucumber using the specified regular expression syntax which is used to match the correspond Given/When/Then statements in the feature definition and extract arguments from them. The "World" closure at the top of the file should return an object that will be implicitly available in your other handlers, thus the calls to runRoutine and runRoutineEx further down are actually calls to the methods in the created TestCompleteWorld class.

Calling COM from Groovy


Calling into Windows applications can be done in a number of ways, in this case I wanted to access TestComplete via its COM Automation interface (read more about COM automation at wikipedia). This is where the jacob library comes into the picture - it makes it extremely easy to call into COM objects from Java - and thanks to the scriptom library for groovy calling COM from groovy is even easier. Given this, the groovy code here is more or less a proxy for calls made to TestCompletes COM interface, which just "proxies" the calls from cucumber to TestComplete.

To keep this plumbing outside the stepdefs file I have hidden it in the TestCompleteWorld class created in the closure at the top. Here comes the constructor that launches TestComplete and sets it up for handling our calls:


(see the entire class at GitHub)

If you are familiar with COM this is pretty straight-forward; the code creates or connects to an existing TestComplete object and does most of the further automation by calling methods in TestCompletes Integration object - which invokes the corresponding functionality in TestComplete.

The TestComplete scripts


All right - let's have a look at the TestComplete side of things; the project is very simple:



The project specifies notepad under the TestedApps node in the project, and contains two JScript units; "NotepadSteps"  (which you can see in the screenshot) contains the actual handlers called from cucumber, and "NotepadStepsTest" which I used to test the handlers during development. The handlers themselves are pretty simple; they automate notepad (ie run it and invoke it's actions) and write some logging information to the TestComplete Log. Thanks to TestCompletes recording functionality it is easy to create handlers that invoke UI actions - as the recording can be converted to a script that you can refine as desired (which is what I did for the "I_load_the_file" method).

I have set the names of the handlers ("notepad_is_running", "I_load_the_file", etc) to be the same as the corresponding handlers in our groovy Stepdefs above - but this is just a convention, I could have named them anything valid.

The Intellij Project


The corresponding IntelliJ project for the above looks as follows:



Core components (as already described above) are:

  • NotepadStepdefs.groovy - the groovy handlers shown above 
  • TestCompleteWorld - the groovy class shown above
  • notepad.feature - the feature file shown above
Additional resources are:
  • a custom CukeRunner to run JUnit tests with Cucumber (an empty class with some annotations)
  • text files in the src/test/resources/data folder used in the tests themselves
  • the TestComplete project is in the src/test/resource/testcomplete folder
  • the maven pom.xml (although the tests don't run with maven yet - to be fixed)
  • the jacob dlls copied to the root folder of the project (so they can be found during execution). Jacob will choose the one corresponding to your architecture automatically

How it all fits together


Since a picture says more than many words - so here comes a diagram trying to give you an understanding of how all these components fit together:





(the 3 components in green are those that I had to code myself)

Verbally this translates to; when running my tests I use JUnit which uses a custom CukeRunner to invoke Cucumber, which reads the feature file and calls the corresponding handlers in the groovy Stepdefs. These in turn use the Jacob library to launch and automate TestComplete, which in turn automates Notepad via JScript handlers. Piece of cake.

Action!


Instead of showing you a bunch of screenshots of this running I've created a short video - please bare with the quality and enjoy that this actually works :-)




How would one use this?


Here at SmartBear we will be evaluating this framework for automating basic GUI tests of both SoapUI and LoadUI. Given there are three main artifacts required here (the feature files, the stepdefs and the TestComplete handlers) it makes for a pretty good fit for how we work; features are defined together with the product owner and the stepdefs and TestComplete scripts are created by devs and testers in our team - the clear separation between these could make for a nice workflow (but we'll see about that - and I promise to report back even if it fails).

Next Steps?


For us we will be looking at how to get this running from Jenkins (which will pose some challenges in regard to launching windows applications), and we will of course expand our feature vocabulary and corresponding scripts in line with our requirements.

For you? The sky is the limit!

The above code is on GitHub at https://github.com/olensmar/cucumber2testcomplete. - please don't hesitate to comment, complain, suggest or fork!

Thanks for your time,

/Ole

P.S. If anyone could suggest an easy way to get syntax-colored code into a blogger blog-post I would be very grateful, inserting screen-shots of editors seems kind-of flaky...

Thursday, December 20, 2012

Using mongoDB with soapUI

Using mongoDB with soapUI turns out to be incredible easy - mostly thanks to the gmongo project which provides a groovy layer on top of the mongo java driver. Let's have a quick look at some example on how this works.

Getting Started

Start by downloading the latest gmongo and mongo-java-driver versions and putting them in the soapUI\bin\ext folder - restart soapUI and you will see them getting picked up by soapUI as it starts (in the soapui log tab at the bottom of the main window):

If you don't already have mongoDB installed - download and install it on your machine and make sure it is running.

Writing Data to a mongoDB Collection

Let's start by writing some data to a mongoDB collection. I'm going to take the result from a call to the Flickr cameras API call which gives a list of all camera makers used by flickr users, and write each of these camera brands to my local database. The REST call to flickr is straight-forward:
Since Flickr requires an API Key I've put that in a project property so I can easily reuse it in all my other Flickr calls - the rest is straight forward for the flickr.cameras.getBrands call - you can see the response from Flickr to the right in the window above.

To write this to my mongoDB using a combination of a DataSource and DataSink TestStep - the DataSource uses the XML DataSource configuration to loop the brand elements in the response:

How this type of DataSource works is described in more detail at http://blog.smartbear.com/software-quality/bid/170520/How-to-Use-XML-DataSources-for-Response-Processing-in-soapUI.

Instead let's focus on the DataSink:


As you can see I've set up a Groovy DataSink with an extremely simple script to write the current rows data to a  mongo collection - this is called every time the DataSink TestStep is executed;

  • The connection to the database is set up the first time the DataSink is called and saved in the context
  • The current rows properties are written to the cameras collection; since properties is a Map it can be "streamed" directly into the collection using the << notation
That's it - the entire structure of my TestCase is as follows:
We have:
  1. Our REST Request that gets the list of camera brands
  2. Our DataSource that reads each row from the flickr response
  3. Our DataSink that writes each row to mongoDB
  4. A DataSourceLoop Step that ensures that we read (and write) each row
Running this unfortunately doesn't give us too much information. Lets' add another TestCase that reads this data from our cameras collection and uses it to make requests to flickr.

Reading from a mongoDB Database

The DataSource will be of type Groovy and looks as follows:
The script initializes its connection to mongoDB upon first execution and also creates a cursor for the cameras collection. Next it checks if there is another row and  in that case copies the row values to the DataSource properties. If there is no more data the result object is left empty - which is interpreted by soapUI that the DataSource has been exhausted.

We're going to use this data in a group-search request to Flickr - just to make sure that there are at least 3 Groups for each brand of camera. The request is straight-forward;

As you can see the ApiKey is being used here again - and the name property of the DataSource is being used in the text search field. When we run this we get something like:

As you can see we have a DataSource Loop at the end of the TestCase that will jump back to the Group Search Request for each row found in the DataSource. Pretty Neat - huh?

Making it easier

Ok, I admit that the above example was a bit overdone - let's just have a quick look at a groovy script step that would read all the data from the cameras collection and log it to the log:
import com.gmongo.GMongo

def gmongo = new GMongo()
def cursor = gmongo.getDB( "soapui" ).cameras.find()

while( cursor.hasNext() )
{ 
    def camera = cursor.next()
     log.info "Found camera with $camera.id names $camera.name" 
}

Dead simple - right?

Future Ideas

Some more ideas of what you could do with mongoDB in soapUI
so much fun - so little time :-)

Conclusion - wrapping up

Thanks to the gmongo library and the many scripting possilibities in soapUI - accessing a mongoDB database from soapUI is pretty straigh-forward.

You can download the gmongo distribution from https://github.com/mongodb/mongo-java-driver/downloads,  the java-mongo driver is available at https://github.com/mongodb/mongo-java-driver/downloads.

I suggest you dig into the gmongo documentation at https://github.com/poiati/gmongo - it has a lot of cool features for making mongo java programming much easier.

And as I'm sure you know - soapUI and soapUI Pro can be downloaded form http://www.soapui.org

Thanks for your time!

/Ole