One of the unsung features in the Automated Test Framework is that you can use it to test your Scripted REST APIs. I’m a fan of having as much robotic coverage as possible, so backstopping API development with tests is a good thing. Let’s look at how to do that.
I will use an example of a relatively recent API that I developed, the commenting system on this very blog. I’ll create a test that:
- given a blog post, asserts does not already have a test comment
- will attempt to POST a comment unauthenticated (which should fail)
- will POST a comment authenticated (which should succeed)
- read the comment and assert that it now exists
I will set it up as a parameterized test so that I can avoid hard-coding parameters. At the moment I only have a single value I want to test against, but once created adding new values is trivial.
First I will create the Parameter Definition to get that out of the way.
After creating, I will define the variable.
Now I will create my test data. As I said previously, adding extra test cases is as simple as creating new records here.
With that entered, we can now define all our API calls which will use the full path to posts in terms of the parameter definition.
To start with, we’ll add a test step to do the inbound call to the getComments endpoint of our Scripted REST API.
The getComments endpoint is designed to work unauthenticated, so I will leave the Basic authentication field blank. I will use the Parameterized value for the query parameter named “p”, which is all that is required for reading comments.
From here, I will add two assertions. In the first I will assert that the response status code is 200. The status code will be asserted after every REST Request step in this entire test. In addition, I will assert that the JSON response does not contain a comment with the text “Test comment”. This is the negative pre-condition assertion to make sure we don’t have a value already that will make it appear as if later steps worked if they didn’t.
It is worth noting that that Assert JSON Response Payload Element test step has some quirks. If asserting on a simple name/value pair of a simple JSON packet, it looks XPath-like with a syntax of “/result/name/”. When getting values out of complex data structures like arrays, there is this odd thing of repeating an element. In this case, the JSON is structured like this:
{
"result": {
"comments": [
{
"text": "api explorer",
"time": "2019-07-17 09:17:00",
"author": "Dave Slusher"
}
]
}
}
Note that result.comments is an array. In order to read the text field of the array elements, repeat the comments field, so the syntax is /result/comments/comments/text
. There is more info on this syntax on the docs site.
Having satisfied that there is no pre-existing data to generate a false positive, the next step is to try to POST a comment. The first time will be done with no authentication profile defined, which is intended to fail.
To demonstrate an alternate way of generating the requests, this time I will create the request with the REST API Explorer. This is convenient when testing POST steps because it allows the use of the API Explorer’s payload builder.
By using the REST API Explorer, you don’t have to know all the details of the API ahead of time. It can definitely be a time saver.
After first picking the endpoint, then I will use the Request Body Builder to structure the payload. For the purposes of sending this packet, I will hardcode the path and not worrry about authentication. After it creates the test step, I will adjust those.
Once the request has successfully been submitted, there will be a button that creates the test step from the request that was just sent.
Now that the test step was created, I will go back in and remove the hard-coded path I used to create and replace with the Parameters.full_path value from the Data Pill Picker.
Following this, we add an assertion on the status code like we did on the first call. In this case, what is expected is a 401 because there is not authentication profile defined. I will add this assertion, then repeat the whole process but this time choosing the profile I have create with the user and password for a valid user on the system. Following that POST step, I will assert for a 200 status code.
After having done all this, I will repeat the API call from the very first step but this time it should find the “Test comment” that was sent via POST in the previous REST step.
Having done all that, I now have a pretty complete test against my commenting API, at least for the minimal functionality. There is certainly room for adding in edge cases, like malformed JSON payloads or empty parameters. I will leave this as an exercise for the reader. You should have a pretty good idea of how to exercise the basic functionality.
Here is an overview of the completed test.
To verify that it runs successfully, I gave it a trial run and it worked.
That should give you a taste of how to use the Automated Test Framework to test endpoints of Scripted REST APIs on your instance. The trickiest part of the whole undertaking is the format of the assertions for the JSON response payloads. If you are someone who has struggled with that and arrived here via Google, with any luck this post helped move your towards success.
Feel free to share your experiences in the comments. I am curious how much traction this currently has in practice for real-world development. As always, I look forward to feedback. Happy developing!
Share this post
Twitter
Facebook
Reddit
LinkedIn
Email