![](https://onwardsource.com/wp-content/uploads/2024/10/bugs_with_dollar_signs-300x300.jpg)
API testing is a fundamental component of software quality assurance, ensuring the reliability and functionality of an application’s API (Application Programming Interface). APIs typically serve as the communication bridge between the user facing front-end of a mobile app or website and a data source like a database, facilitating the seamless exchange and processing of data. APIs can also be used to exchange data with other APIs, systems, and applications without a user interface. The primary goal of API testing is to validate that the API functions as intended, adheres to specifications, enforces business rules, and interacts seamlessly with other software components. The testing approach encompasses various types of testing, including contract testing, integration testing, functional testing, performance and load testing, and security testing. API testing poses challenges stemming from the unique characteristics of APIs and the complexity of modern software systems. The absence of a user interface requires testers to rely on documentation and specialized tools, complicating the visual inspection of system behavior. Handling diverse data formats, such as JSON and XML, adds complexity, as does the reliance on external services and third-party integrations.
There are many guides available for API testing on the internet but many of them only cover theory and high level concepts with precious little context or practical application. This series on API Testing will explore each aspect of API testing in detail, provide real world examples, and discuss special points of interest that only comes with decades of API testing practice. Further, this guide stands as a specification for how Onward Source approaches API testing for the clients we work with.
APIs can be intimidating. They can seem like they are a nebulous entity that receives requests and magically returns data. In actuality they are like any other computer program just like a desktop application or mobile app. With an API, the interface is data instead of a UI. And just like any other application an API takes in input, process it, and provides output. In this case the input and output is data. API applications typically run on a server and can be written in any one of a myriad of programming languages like Java, Python, Ruby, PHP, or increasingly more common, Javascript. APIs are packaged into an executable file like any other computer program and require system resources like CPU, RAM memory (APIs written in Java are notorious memory hogs), and storage memory, the same as any other application. These resources are exhaustible as the API application runs and should be monitored during testing and investigated whenever an especially perplexing bug is isolated. As we discuss the different aspects of API testing in this series we will make a point to discuss the touch-points each has with the API application itself.
A simple API system diagram. In this example the API application is installed on a server with an in-memory cache and database and also integrates with a third party API. Each component in this system diagram is a point of integration that requires testing. More on this when we discuss integration testing.
OK, but what are microservices and how do they change the approach to API testing?
Microservice architecture is a design pattern whereby the different functions of the API are broken up into separate applications. Consider the two API design diagrams below.
The traditional API application design pattern combines all the API’s methods into a single application, making one single monolithic API application. This monolithic API architecture would then be installed on as many servers as needed to serve the amount of traffic needed. Any change to any one method in the monolithic API would necessitate a regression test of all APIs in the application, possibly requiring considerable time and slowing the release cadence.
The right-hand diagram shows an example of the microservice API architecture. With the microservice API architecture an individual API application serves only a handful of methods. This API design allows for much more flexible server deployments where only the most utilized API application needs to be scaled to multiple servers and the least used can use a separate scaling schema. This architecture also lends itself to faster releases as only the API application and its respective methods that were changed need to be tested.
API testing tools can be as simple or as complex as needed for the context of the API that is being tested. Some tools offer a simple UI interface while others are code based. In some cases and specialized applications may be required to test an API that is coded from the ground up in a traditional programming language like Java or Python. Here are some of the tools typically used for API testing:
Let’s get a brief description of the different types of testing that are executed during API testing. The rest of this API testing series of blog posts will dive deeper into each of these. It is important to understand that each of these types do not live in isolation and there can be some overlap in the testing and the kind of tests you actually use for each. For instance you may run a functional test to verify an integration is working. These types of tests define the objective, not necessarily the process.
Before beginning more in-depth types of testing it is best to verify that all the different sub-systems and components involved in the API are communicating with each other. This can include verifying that the API is communicating with a database and other subsytems. Some of these subsystems can include:
During integration testing each integrated support service that works on behalf of the API will be tested in isolation to verify it is operating as the API needs it to. Without first testing these sub-systems we cannot assume that any other part of the API will function correctly.
Contract testing includes testing how a client will communicate with the API and how the API will send data back to the client. Within the context of an API think of a “contract” as just a definition of how requests will be sent to the API and how responses will sent to the client.
Consider the contract for a webpage. The contract for a browser sending a URL to a server in a request for a webpage defines that the request will be sent with the ‘http’ protocol, include a domain name, and a path/filename. The contract further defines that the response will be a HTML document with tags for ‘html’ encapsulating ‘head’, ‘title’, and ‘body’ tags.
API Request contracts will define the following properties
API Response contracts will define the following properties
The objective of contract testing is to verify that each method of the API conforms to the contract so that clients can reliably communicate with the API. This testing lays the foundation for all testing that is to come and is the most basic form of functional testing. Many QA organizations may stop their functional testing here and may not continue into more exhaustive testing of data testing, business rule processing, or permutation testing.
Functional testing will constitute the bulk of the testing performed during API testing. Functional testing includes testing each major function of the API including the create, read, update, and delete functions, commonly referred to as CRUD functions. These functions will also be tested against the data caching policies that are employed to be certain the cache hit, cache miss, and data change cases are correctly handled.
During functional testing it can be useful to approach the API under test as if it were a UI application. With a UI application, each interface control will be tested along with each control value. Think of a UI dropdown control having 5 different options that the user can select from, and that selecting each option results in a different operation being initiated on the UI application. This can be synonymous with a API parameter having an enumerated list of 5 options, each of which initiates the processing of different business rules that are reflected in the API response. Just as with the UI application, we must test each of the 5 parameter options during our API test.
Some of the functional API testing activities include:
These are just a few of the functional testing activities than can be performed. We will explore each of these in more depth, as well as some others, in a future blog post.
Load testing involves executing multiple simultaneous API requests to simulate usage by multiple users of a client application that is using the API. The objective of this testing is to discover if the API can serve multiple simultaneous requests and still remain performant and not suffer any functional degradation. This testing is also used to test any automated scaling policies put in place on the server to increase the number of API application instances when traffic increases during peak usage.
To execute this testing, a test script is created in an application called JMeter that simulates multiple simultaneous users. JMeter is an open source application maintained by the Apache Software Foundation and can be run on Windows, Mac, and Linux. It includes a front-end UI application for the creating of the load test script which is then typically run by command line from a host system for the load test.
The product owners and development team will need to be engaged to determine what load will be generated during the load test. The process for setting a target load is as follows:
Another way of determining the target load is to investigate server logs from past API usage in a production environment to determine the number of requests per second that were generated and then set up JMeter to reproduce that load.
The load test will run continuously for some length of time during which the server logs and resources will be monitored. API response times, any errors, change in API application health, or server resources are noted and reported in the load test report. The client application may also be intermittently, manually, tested while the API load test is in progress to assess the user experience under load.
API security testing is a crucial aspect of ensuring the integrity and protection of data and services exposed through APIs. API security testing involves evaluating the security measures implemented in an API to identify vulnerabilities and weaknesses. Some of the security testing methods include:
In our next blog post in this series we will discuss Integration Testing in more detail including the methods for testing and some of the tools used.
Created by Water’s Edge Web Design