Dave Slusher

5 minute read

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.

Initial Creation of the Test

First I will create the Parameter Definition to get that out of the way.

Add Exclusive Parameter

After creating, I will define the variable.

Define Exclusive Parameter Variable

Now I will create my test data. As I said previously, adding extra test cases is as simple as creating new records here.

Enter test data

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.

Create an Inbound REST Request Test Step

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.

Choose Paramters.full_path from Data Pill Picker

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.

Assert No Existing Test Comment

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.

Choose the Test Step to Send Inbound REST Request with API Explorer

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.

Choose the postComment endpoint

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.

Use the Request Body Builder to create the Payload

Once the request has successfully been submitted, there will be a button that creates the test step from the request that was just sent.

Create the Test Step from API Explorer

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.

Adjust the Parameters of the Created Test Step

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.

Post the Blog Comment Again but with Valid Profile

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.

Do the Final Assertion on Submitted Comment

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.

Final List of Test Steps

To verify that it runs successfully, I gave it a trial run and it worked.

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!


Comments