Generating SoapUI tests with REST discovery (Pro)
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.
Getting ready
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.
Note
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.
Tip
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.
How to do it...
Perform the following steps:
Note
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:
- You are only testing
GET
requests, as no other methods are possible. - You are discovering services via web pages like in the Swagger example in the SoapUI online help (http://www.soapui.org/REST-Discovery/api-with-internal-browser.html).
- Or you need to test using HTTPS, which, at the time of writing, the proxy cannot support.
Otherwise, once set up, the proxy mode is a far more versatile option for testing in a lot of API scenarios including this recipe.
- To start, go to File Menu | New Project and select options the Discover REST APIs using and SoapUI internal proxy. Click on OK, and you should see the default details of the SoapUI proxy:
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.Tip
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.
- Download the RESTClient add-on in Firefox by going to Tools Menu | Add-ons, search for
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. - Next, we need to configure Firefox's proxy settings to point to SoapUI's proxy:
- Open Preferences | Advanced | Network.
- Under Connection, next to Configure how Firefox connects to the Internet, click on Settings.
- Select Manual proxy configuration and enter the SoapUI proxy details as shown in the following screenshot.
- Click on OK.
- Now, we are ready to use the RESTClient via the SoapUI proxy. As a first test, request the WADL like before, by selecting a method of
GET
, adding a URL ofhttp://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.Tip
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.
- Before we try posting or putting any invoice data, we need to change the request's content type to
application/json
; otherwise, status415 Unsupported Media Type
messages will occur. To do this:- Click on the RESTClient's Headers menu and select Custom Header.
- In the Request Header pop up, enter Name as
Content-Type
and Value asapplication/json,
and then click on OK. - You should see
Content-Type: application/json
in the Headers section on the next page.
- Now, let's do some actual requests! First, let's create an invoice. Set the following values:
- Method:
POST
- URL:
http://localhost:9000/invoiceservice/v1/invoice
- Body:
{"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 } }
- Method:
- Next, update the invoice:
- Method:
PUT
- URL:
http://localhost:9000/invoiceservice/v1/invoice/inv0
- Body:
{"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 } }
- Method:
- Next, get the invoice, method
GET
, and URLhttp://localhost:9000/invoiceservice/v1/invoice/inv0
. You should see a response of status code200 OK
and the same body as earlier. - Now, delete the invoice, method
DELETE
, and URLhttp://localhost:9000/invoiceservice/v1/invoice/inv0
. You should see a response of200 OK
without any response body. - Lastly, try to get that invoice again and you should see a response of status code
404 Not Found
. - Now, to generate the SoapUI test artefacts, perform the following steps:
- Go back to SoapUI and click on Done. The window should change and present you with a tree view of all the requests you submitted.
- Next, click on Generate services and select Services + TestSuite. Then, enter a name for the
TestSuite
, for example,TestSuite Rest Discovery
. - Click on OK to create TestCase.
- A Success pop up should be displayed; click on OK to close discovery, and you should see all the generated
requests
,TestSuite
,TestCase
, andTestSteps
for each of the requests in a new project calledProject 1
. Finished!
How it works...
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.
There's more...
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.
See also
- For more information on HTTP Monitor SoapUI Docs (open source), go to http://www.soapui.org/HTTP-Recording/concept.html