
SoapUI Cookbook
By :

In this recipe, we take a look at how to generate tests for RESTful web services that already exist. The pro version of SoapUI has the REST discovery functionality to allow interactions with a RESTful API to be recorded and used to generate tests.
To provide an example of a RESTful web service, I have extended the previous recipe's invoice service to have full CRUD functionality. The interface now looks like this:
Resource: http://localhost:9000/invoiceservice/v1/invoice Supported Methods: POST invoice - Create Invoice. GET invoice/{id} – Get (Read) Invoice. PUT invoice/{id} – Update Invoice. DELETE invoice/{id} – Delete Invoice.
The invoice document is as follows:
{"Invoice": { "id": 12345, "companyName": "Test Company", "amount": 100 }}
The service's implementation is very basic. The create (POST
) method is not idempotent, and it will create new invoice objects on each successful request with IDs of the form invN
, where N is a sequence number that starts from 0, for example, inv0
, inv1
, and so on. The GET
, UPDATE
, and DELETE
methods will all return HTTP status 404 if an invoice with the specified ID has not previously been created. The invoices are stored in a Java HashMap
, so they will not persist when the server is restarted, and the HashMap
is empty on startup.
Example Service Code
We are not developing a service in this recipe. Use the prebuilt service from <chapter1 samples>/rest/invoice_crud
.
Start the service in the same manner as described in the previous recipe:
cd <chapter1 samples>/chapter1/rest/invoice_crud/target/classes java -cp "<apache-cxf-3.0.1 home>/lib/*:." rest.invoice.crud.v1.Server
To test its running, open a browser and go to http://localhost:9000/invoiceservice/v1?_wadl
, and you should see a WADL displayed with methods as described in the preceding code.
Port already in use
If you see this exception, then make sure that no other servers are running on port 9000, for example, the servers from the previous recipes.
The Mozilla Firefox browser is used to illustrate this recipe. Please download this if you don't already have it. If this isn't possible, other options will be described later.
Perform the following steps:
Internal Browser or Proxy Mode?
SoapUI offers two options to discover RESTful web services. The first option is to use the internal browser and the second one is to use the proxy mode. I would say that the internal browser option is only useful if:
GET
requests, as no other methods are possible.Otherwise, once set up, the proxy mode is a far more versatile option for testing in a lot of API scenarios including this recipe.
Discover Using: Proxy HTTP Recorded Requests: 0 Port: 8081 Status: Running Host (Internal Clients): localhost
For this example, we are only concerned with the details for internal clients. Using an external client involves pretty much the same steps, except that it may require network setup that is beyond the scope of this book. The host (localhost
) and the port (8081) are the key values to note. These will be used by whatever REST client we choose to use to do the actual service interactions.
REST Clients
There are many good and free options here. IDEs such as Eclipse and IntelliJ have a good REST client plugin. Browser-based REST clients are also very good; for Chrome, there is the Postman plugin, and for Firefox, the RESTClient add-on. When choosing which to use, consider that you will need to amend the proxy settings, at least temporarily, in order to route requests via SoapUI's proxy. You could also go for a command line option and use something like cURL (http://curl.haxx.se/docs/manpage.html). Choose whichever option is most convenient for you, but for this recipe I will illustrate the use of Firefox's RESTClient plugin.
RESTClient
, and click on Add to Firefox. Restart Firefox, and RESTClient should be available in the Tools menu. Click on the client to open it in a new Firefox tab.GET
, adding a URL of http://localhost:9000/invoiceservice/v1?_wadl
, and clicking on Send. You should see the WADL in the RESTClient response body and see the SoapUI proxy Recorded Requests incremented to 1.Nothing happened?
Make sure the service is still running; otherwise, connection refused messages will occur. The server exists after 10 minutes, which is easily adjustable in the source code for the Server
class.
Note that other requests via the Firefox browser will also increment the recorded requests. Any unwanted requests can be filtered out later.
application/json
; otherwise, status 415 Unsupported Media Type
messages will occur. To do this:Content-Type
and Value as application/json,
and then click on OK.Content-Type: application/json
in the Headers section on the next page.POST
http://localhost:9000/invoiceservice/v1/invoice
{"Invoice": { "id": 12345, "companyName": "Test Company", "amount": 100 }}
You should see the Response Header status code 200 OK
and a Response Body of:
{ "Invoice": { "id": "inv0", "companyName": "Test Company", "amount": 100 } }
PUT
http://localhost:9000/invoiceservice/v1/invoice/inv0
{"Invoice": { "id": 12345, "companyName": "Real Company", "amount": 200 }}
You should see the Response Header status code 200 OK
and a Response Body of:
{ "Invoice": { "id": "inv0", "companyName": "Real Company", "amount": 200 } }
GET
, and URL http://localhost:9000/invoiceservice/v1/invoice/inv0
. You should see a response of status code 200 OK
and the same body as earlier.DELETE
, and URL http://localhost:9000/invoiceservice/v1/invoice/inv0
. You should see a response of 200 OK
without any response body.404 Not Found
.TestSuite
, for example, TestSuite Rest Discovery
.requests
, TestSuite
, TestCase
, and TestSteps
for each of the requests in a new project called Project 1
. Finished!SoapUI sets up its own proxy to listen to all HTTP traffic routed through it. When you make a request through the REST client, SoapUI is able to extract the details and build up a list of sample requests. Then, when you have finished recording, SoapUI uses the list of requests to generate test artifacts in the same way it would if the requests had come from another source, for example, a WADL.
On inspection of the generated REST project, we can see that the REST discovery has provided a useful means of harvesting sample requests from a readymade service. You still need to create Assertions
and perhaps organize the generated TestSteps
. The REST discovery functionality could be useful when it comes to retrofitting tests, perhaps around a service that has been developed code-first, as in the above example. It could also be especially useful for services that don't present a WADL or similar definition and therefore cannot have test requests generated by other SoapUI means.
Change the font size
Change margin width
Change background colour