DEV Community

InterSystems Developer for InterSystems

Posted on • Originally published at community.intersystems.com

Automate API Testing with IrisApiTester: A Developer's Guide

Image description
   

 

Hello, community!

 

After creating the app IrisApiTester, I saw that it could have more potential, and with some adjustments, it could become a powerful collaborative tool.

 

I asked myself a few questions::

  • Could the API collections be shared with the entire team?
  • Could I use it to perform unit tests?
  • Is it beneficial for integration tests??
  • What will happen if I add a CI/CD continuous integration layer??

 

After considering possible answers, I decided to give it a try. When I finished my work, I discovered that all the responses were affirmative (with some nuances xD). Ultimately, I have decided to write this article and share my experience with you. I hope it can help us exchange our knowledge and potentially improve the application together..

 

The article should come in handy for you, I think. It might make you consider some new applications, or you may realize that it is beneficial for that test you didn’t know how to perform in an Agile way, but you will finally be able to execute now with my tips.

 

To keep the article short and sweet, I will divide it into several sections. In this way, you will have the option of going directly to the part you need or just reading everything in full.

 

If you want to carry out the tests step by step, I assume you already have an instance of the IrisApiTester docker image downloaded and running. However, if this is not the case, you can find the data you need in the article I wrote earlier:

https://community.intersystems.com/post/iris-api-tester

 

Point 1 - Sharing Postman collections between the team:

 

The first thing I asked myself was whether I could share my Postman collection with the tests with all my colleagues, and the solution turned out to be much simpler than I expected.

 

I discovered that we could connect Postman to a repository that contained one or several collections of APIs. At the same time, Postman even included a Git client to update the collections, make commits, and perform other operations from Postman itself without having to switch to the terminal or anything. It might be something that everyone knew, but I had never noticed xD.

 

Buckle up! Now, I will explain how to connect Postman to a repository with an API collection..

 

For the example, I have created a repository on GitHub. I have also tried to make one on Bitbucket. It is possible too in case you prefer to work with that service. So, here is the link to my repo::

https://github.com/daniel-aguilar-garcia/postman-collection-test

 

You can fork it if you wish. The collection contains some simple tests that point to a Docker container in a local instance (localhost) of IrisApiTester.

 

First of all, connect Postman to your repository.

 

Open Postman, click Apis, and create API:

 

Then choose a name for the collection and click the GitHub icon (Or Bitbucket...)

 

It may ask you for authorization. If it does, give it permission to connect to your GitHub user:

 

Once the request is accepted, select your GitHub user, the repository where you are going to store the APIs, and the repository branch:

 

Once connected (unless it is a new repository), the API collections that you have in the repository will show up:

 

All the collections within the API will also appear in the menu:

 

If we make any changes to the collection, they will be reflected in the Git section immediately. It will allow us to perform such operations as commit, pull, push, etc.

 

If you have a Postman’s paid license, the only thing you should do to connect with the rest of the development team is to create a common Workspace, and that would be it. However, if you use a free account, you must repeat all the steps mentioned above on every development team's computer..

 

With the abovementioned steps, we have just completed the first point, sharing our collection with our team members and keeping it updated. The only drawback here would be if you use a free account, you can only generate 3 APIs. So, if this is the case, just put all the collections in the same repository to avoid problems.

 

Point 2 - Unit tests:

 

The next issue to solve was related to how to use the tool not only for API tests but also to execute unit tests. At that point, I asked myself: "What would be the fastest way to generate tests without creating new endpoints for each one of them?" So, this is what I came up with:

 

I created a webApp on the /run path:

 

I also made a class for the API. I built the following route (in the repository, it is the TestRoutes.cls class from the Example package):

 

With this WebApp and the route, we can establish a so-called “auto-publish” method for any class. We only need to pass the class and the method names to the API to achieve that. Check out the example below:

localhost:52773/run/IrisNewman.Example.TestMethods/TestOK

 

In this case, we have indicated the following:

/run -> WebApp path

/IrisNewman.Example.TestMethods -> a class where the method that should be executed is located

/TestOK -> the method to execute

 

In the TestOK method, I performed a simple check operation for the unit test:

ClassMethod TestOK() As %Status
{
    Set testNumber = 1
    Set a = 1
    Set b = 2
    Set res = ..SumNumbers(a,b)

    Do ..assert(res,3,$G(%methodname),testNumber)

    Quit $$$OK
}

 

A peculiarity on this class it’s that I defined my own assert method. My method assures that the values passed in parameters 1 and 2 are equal. Parameter 3 is the actual name of the method, and 4 is the number of assertions within the method. These last 2 parameters are only used to return a more detailed message in case an error in the assertion occurs. If the values don’t match when compared, it will throw an exception with a General Throw, sending the response code 500 to the request’s header. Then the test will be marked as an error in Newman's report.

 

With this approach, the only things left would be the following:

  • Include a call to our method to the Postman collection.
  • Commit the changes. 

 

In this way, everyone will have the collection updated in the repository.

 

Point 3 - Integration Test:

 

In the same way, as in the previous step, we can reuse the WebApp utilized (or not) for the integration test. An example of the test could be adding a person to our database:

localhost:52773/run/IrisNewman.Example.TestMethods/InsertPerson

 

In this case, we have indicated the following:

/run -> WebApp path

/IrisNewman.Example.TestMethods -> a class where the method to be executed is located

/InsertPerson -> a method to execute

 

In the InsertPerson method, I performed all the operations within a transaction and checked with an assertion that the desired values had been stored. Finally, I completed a rollback to undo the changes:

ClassMethod InsertPerson()
{

    Set testNumber = 1
    Set method=$G(%methodname)

    TSTART
    Set person=##class(IrisNewman.Example.Entity.Person).%New()
    Set person.IDCard="11111111H"
    Set person.Name="Incognito Guy"
    Set person.Address="False Street, 123"
    Set person.City="Springfield"
    Set res = person.%Save()

    Do ..assert(res,1)

    Set personReaded = ##class(IrisNewman.Example.Entity.Person).%OpenId(person.IDCard)

    Do ..assert(personReaded.Name,"Incognito Guy",method,testNumber)

    TROLLBACK
    Quit $$$OK
}

 

In the same way, we could test the Update, Delete, or any other operation, and as a result, we could execute any integration test we need.

 

Point 4 - Adding CI/CD:

 

You might be considering the following question: "Ok, this is good, but I want something more automated. How can I launch the tests of my collections automatically?"

 

So, for this case, I created a new endpoint in the App (It must be launched in a browser, not in Postman):

http://localhost:52773/pull_and_run_tests

 

This endpoint downloads the latest version of the collection from our Git or Bitbucket repository. It also runs the tests on it and shows the report (from Newman) with the results of those tests on screen:

 

To run the pull_and_run_test endpoint, we must configure the access data to the repository where we store our collection of tests in the file repository.cfg:

 

At this point, I had an idea dwelling in my mind that It would be nice to add a Workflow to the repository which would run all the tests automatically every time I make a commit

 

It came to my mind to create a new endpoint for this:

http://localhost:52773/pull_run_and_send_google

 

It does the following: downloads the ApiTesting docker image, then downloads the collection from the repository, later executes the tests, and sends a message with the URL of the resulting HTML file to Google Chat.

 

For this to work, in the file repository.cfg we must configure the URL of the webhook of our Google Chat channel where we want to receive the message:

 

In the following picture, you can see an example of the workflow execution after every commit in the repository:

 

Below there is the code from the GitHub Workflow that I used as an example:

name: Launch Tests
on:
  push:
    branches:
      - main
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout source code
      uses: actions/checkout@v2
    - name: Clone the irisapitester repository
      run: git clone https://github.com/daniel-aguilar-garcia/irisapitester.git
    - name: Raise Docker Compose
      run: docker-compose up -d
      working-directory: ./irisapitester
    - name: Wait for Docker
      run: sleep 30
    - name: Send report to Google Chat
      id: send_report_google
      run: |

        $(curl -s http://localhost:52773/pull_run_and_send_google)

 

Now, take a look at the example of the message received:

(In my example, I simply send the URL. However, we could program it to be sent only when it fails or make it arrive with an executed Ok / KO + the URL to the report).

 

Note: If you plan to use the function of sending messages, you should map some network storage to save the HTML of the test results. Since the Docker instance is generated and destroyed during the Workflow, if we store it there, it will disappear. To solve this issue, add a network volume with the path to the Docker file and modify the test storage path in the executionsTestPath parameter of the IrisNewman/Api.cls class.

 

 

With all the abovementioned, we have already covered a large part of all the tests we wish to automate. Since I used the Workflow as an example of instruction, I have added it to my test repository. However, you can also store it in the repository of your software. Another option would be to place the source code of your software and the collection to be executed directly in the same repository. In this case, with each commit, the tests of the Postman collection that we have updated would be executed, and we would be notified (in this case by Google Chat) of the result of the operation automatically.

 

I hope you found my article interesting and will use this application/way of working in your daily life, or, at least, it has given you some ideas of a similar thing that can come in handy for you.

 

I encourage you to drop your questions and any uncertainties in the comments section. Your questions are highly appreciated.

 

Thanks for reading!!


 

Top comments (0)