As APIs and microservices become more prevalent in modern applications and development processes, testing and monitoring these APIs becomes ever more critical to ensure the functionality and performance of these applications.

In this article, we’ll cover the seven basic steps for writing API tests. These can prove useful for engineers looking to introduce API testing into their applications and for teams looking to formalize API testing processes as part of their software development lifecycle.

How to Write API Tests

  1. Understand the Scope of the API
  2. Understand the User Flows
  3. Write API Tests
  4. Write Negative Tests and Edge Case Tests
  5. Execute Tests against Dev and Stage environments
  6. Connect Tests to CI/CD Pipeline
  7. Run Tests to Monitor Production Environments

1. Understand the Scope of the API

Before attempting to test an API, it is critical to understand what the API does and what its responsibilities are. This step should start with getting access to the API documentation. You should manually make some calls to the API endpoints to get a solid understanding of how they work and what data they return.

In essence, you should have answers to some of the following questions:

  1. What is the purpose of this API?
  2. What kind of data does this API handle, and what are the data models used for?
  3. What are the entry points to this API (endpoints/queries/tasks it accepts)? What is their structure?
💡 TIP: This step also helps uncover inaccuracies and unclear aspects of the API documentation, as sometimes it’s being read for the first time. This could be a great opportunity to perfect the API docs.

2. Understand the User Flows

In this step, you should venture beyond the individual API and look at the application(s) consuming it. Try and understand how users use these applications and what API calls are being triggered by their usage.

This will help you understand the real-life scenarios the APIs are used in and enable you to develop tests that test and validate the API in the ways it is being used in real life.

For instance, if the API is called directly from a web application, you can use the browser developer tools to record all the requests made to an API and inspect the request and response payloads. This can help develop an understanding of how the API is consumed.

3. Write API Tests

Armed with an understanding of the API and its use cases, you should be all set to start creating API tests. We like to think of this as an inside-out process: start by testing individual endpoints for their expected behavior (for instance, GET /product/214 should return JSON describing the product with ID 214). Then, expand to creating more intricate tests that chain multiple requests and validate the functional flow (create a product, get it, modify the product, get it again and make sure the modifications were saved).

Ideally, useful tests written in this step should have several traits:

  1. Atomic: Each test should be self-contained and shouldn’t rely on other tests to run before/after it on or other data to exist.
  2. Portable: Any data, configurations, and especially URLs should be passed as parameters to ensure portability between environments.
  3. Repeatable: You should be able to re-run tests frequently without any process in-between runs (like manual data cleanup).

4. Write Negative Tests and Edge Case Tests

The previous step centered around the API’s expected behavior and validating it worked as expected under “normal” usage. However, in this step, we try to test that the API behaves correctly under edge cases and negative cases. For instance:

  1. Does trying to get a non-existent entity to return the correct error code (404 response)?
  2. Does the API fail if supplied with an argument of the wrong data type (400 response)?
  3. What happens if we try to access an entity we do not have permissions for (401 response)?

One trick for this step is to look at the list of HTTP error codes (especially the 4xx range – user errors) and try to create scenarios to produce each of these codes.

💡 TIP: Developers using an API expect the correct errors to be returned. It is critical to ensure the API behaves well when experiencing errors.

5. Execute Tests against Dev and Stage environments

Once your tests are written, you should be able to start utilizing them in your non-production environments and see them passing. Ideally, if you wrote your tests correctly, you should be able to execute your tests against different environments by passing different variables to them. This can help you start validating your API’s development versions.

6. Connect Tests to CI/CD Pipeline

Once you can see all your tests running against development/stage environments, you can connect them to your CI/CD pipeline to start automating the testing process when you push new code. This can be done through your source code management tool, like GitHub or GitLab, or a build tool like Jenkins or CircleCI. This helps keep the testing running and “forces” you to keep tests up to date as you couldn’t push code with failing tests.

7. Run Tests to Monitor Production Environments

One of the benefits of API tests is that you can easily run them in multiple environments. Specifically, you can run your tests periodically on your production environment to ensure it functions as expected. This can also help you collect performance data about your API to see degradations or changes in performance in real-time.