API testing plays a crucial role in software quality assurance. Whether you work for a company that delivers robust software solutions or are preparing for a software testing interview, you may encounter a situation where you need to make cases for an API. This article will discuss various test cases that can be used while working with an API. These test cases will be presented in a structured manner, moving from a broad view to a more granular view for easy comprehension.
The image below illustrates the various aspects of API testing using which we will make our test cases. It provides an overview of the high-level scenarios for testing an API.
We will divide our API testing into three parts –
Let’s discuss each of the above one by one.
Functional Testing
Functional testing is a form of software testing that concentrates on validating whether a software application or system performs accurately as per the predetermined requirements and design. The major objective of functional testing is to guarantee that the software executes its intended functions.
In order to confirm that an API is functioning properly, it is necessary to examine and analyze both the request and response thoroughly. This entails scrutinizing all the input parameters of the request and confirming that the response is accurate, valid, and in the expected format.
So, let’s dive into the various parts of the Request and Response.
Request
We will examine how the API behaves when different types of data are sent along with the request. This will cover both positive and negative test scenarios. To simplify the process, we can divide the data into subcategories and generate a complete list of test cases for each category.
Request payload test cases
Request Payload, or we can say Request Body, is one of the most important parts of an API. Depending on the payload, we can expect different kinds of responses from the API. So, it becomes important that we test our API thoroughly by sending different types of payloads.
- Valid Request Payload – Hit the API request with a valid Request Payload to ensure the API returns the expected response. This is to ensure that the API works as expected when we provide valid values to it.
- Missing a mandatory key – If a mandatory key is missing, the API should return a 400 Bad Request error.
- Missing an Optional key – The API should not return a Bad Request error but rather respond according to the defined logic.
- Changing the value’s data type – We should test an API’s response to different data types by sending a value that is not specified in the API contract. For instance, one can send an integer or boolean value instead of a string and verify the API’s response. Upon receiving such a value, the API should return an appropriate error status code, such as 400 Bad Request.
- Empty Payload – Check how the API behaves when we send an empty payload.
- Empty values – If a field accepts a String, then we can send an empty string to check the behavior of the API.
- Special characters – Send special characters to see that API correctly handles these characters and returns a proper output.
- Boundary values – We can test the API on boundary values, such as the minimum and maximum value of a number field, and observe the API’s response.
- Injection Attacks – It is important to thoroughly test the API by including payloads that attempt to inject SQL or cross-site scripting (XSS) attacks.
- Concurrent Requests – Send multiple concurrent requests with different request payloads to test the API’s concurrency and thread safety. Check the API’s response for any unexpected behavior or race conditions.
Request headers test cases
Request headers are responsible for authorizing and authenticating API requests. It’s crucial to prevent unauthenticated users from accessing API data.
- Valid Request Headers – Provide valid and correct Request headers and verify that the API returns the expected Response and the status code.
- Missing Request Headers – Simply remove one or more headers from the request and verify the response from the API. If, for instance, an invalid token is passed, the API response should indicate that the user is not authenticated to make the specific API request.
- Authorization Header – Verify that the Authorization is working as expected with below scenarios
- Valid authorization token
- Expired authorization token
- Missing authorization token
- Invalid authorization token
- Content-Type Header – Send different types of Content-Type headers and see how the API behaves accordingly. Verify that API correctly parses and processes the request body based on the specified Content-Type header.
- Accept Header – Send requests with different Accept headers to specify the expected response format. The API should return the response in the expected response format, or it should throw an error if the format is not supported.
Request methods test cases
- Valid Request Methods – Use a valid request method to see if the API returns the expected response or not. For example, if the API supports a GET request, we should execute a GET request to verify if the response is as expected.
- Invalid Request Methods – When we try to use a request method that is not supported by an API, we should get an error. For instance, if an API only supports GET requests, and we try to execute a POST request, we will receive a “405 Method Not Allowed” response. This error message is usually returned by APIs when we attempt to use an invalid request method.
- Idempotency Testing – Request Methods like PUT are idempotent. So, hitting the same PUT request multiple times should yield the same result.
Request url test cases
- Valid URL – Test the API with the valid URL to see if it gives the expected results.
- Invalid URL – Verify how the API behaves when using an invalid URL, such as a malformed or nonsensical URL.
- Special characters – Ensure that unsupported special characters in the URL produce the expected error.
- Query and Path Parameters – Validate the API on valid/invalid query and Path parameters. Normally, API throws a “404 Not Found” error if it’s unable to find the path parameters.
- Send additional query Parameters – Send some additional query parameters to see how the API behaves.
- URL case sensitivity – When testing the API, it is recommended to verify different cases, such as variations in path parameters. For instance, if the original request has “/resource” in its path, we should also test “/Resource” to verify its functionality.
- Paginated URLs – If your API supports Pagination, then verify whether the API returns the expected result for each page and provides pagination-related information.
Response
Giving out a proper response along with the necessary errors is important for anyone consuming the API. So, let’s discuss the test cases one can use to test out the
Response codes and messages
Response codes are critical as many API-consuming services first check the response codes before processing the response body. Therefore, if the response code does not match the expected values, it could result in system failure.
- Valid response codes – Verify whether the API returns the expected response code and message for the valid request. For example, API usually returns the 200 OK code for a successfully processed request.
- Validate various response codes – The response codes should follow the standards. For instance, if we create a new resource, the response code should be “201 created”. This indicates a resource is created at the backend.
- Forbidden and Unauthorized requests – When a request contains invalid credentials or the credentials are correct but lack permission, the API should return “401 Unauthorized” and “403 Forbidden” errors, respectively.
- Too many requests – It is important to test the rate-limiting feature of an API to ensure that only a specific number of requests are allowed. This is important to prevent malicious attacks from bots and DDoS attacks. If the number of API requests exceeds the specified limit, then the API should return a “429 Too Many Requests” error code.
- 5xx series errors – Test the API on various server errors like 503, 504, etc.
We can test the API on different response codes depending on the API requirements.
Response body test cases
- Valid Response Body – Send a request and verify that the API returns a valid response body with the expected data or resource.
- Response Data Format – Verify that the API correctly formats the response data according to the requested format or the default format.
- Response Body Structure – Verify that the Response Body structure matches the expected response structure.
- Response Data Type – Verify the data type of the fields in the Response Body. For example, verify that numeric fields are numbers, strings are strings, and dates are in the expected date format.
- Pagination in Response – Verify that API returns the expected number of entries and that the pagination information is properly handled.
- Response Body Errors – Execute API with an erroneous request to ensure that the API handles those errors and then displays the correct error information in the response.
Response headers test cases
Response headers contain additional information about the response. It is necessary to test if it is correctly passed.
- Content-Type Header – Verify that the Content-Type header in the response header matches the expected media type like application/json.
- Cache-Control Header – The cache-control header specifies browser caching policies. It is necessary to verify that correct cache policies are passed in the response headers.
- Allow Header – Verify that the allow header lists the list of allowed HTTP methods.
- Rate Limiting headers – If your API has implemented rate limiting, it’s important to verify the “X-Rate-Limit-Limit,” “X-Rate-Limit-Remaining,” and “X-Rate-Limit-Reset” headers. These response headers are crucial for other services that consume the API as they rely on them to execute the API and stay within the rate limit to avoid the 429 error.
- Security Headers – Verify various security-related headers ( “X-Content-Type-Options,” “X-Frame-Options,” and “X-XSS-Protection”) if applicable.
- Retry-After header – The Retry-After header provides information on the duration that the user agent should wait before sending another request. This header is useful after receiving a 429 error, which indicates that the server has received too many requests. In such cases, the user agent should wait for the duration specified in the Retry-After header before sending any further requests.
Response time
- Baseline Response time – Establish a baseline response time under normal conditions and verify that the API response time would always fall in the acceptable range.
- Response Time Under Load – Verify the API’s response time under load.
- Response Time for large or complex payloads – Verify whether the API responds within the acceptable range for large or complex payloads.
- Response Time with and Without Caching – Verify whether the response time is being reduced if data is being picked from the cache.
- Response Time Across Geographic Regions – Verify the API’s response time from different geographic regions or with requests originating from various locations.
Non-Functional Testing
It is crucial to perform non-functional testing on an API to ensure that it can handle heavy loads and peak system performance. Sometimes, daily testing often overlooks this important aspect, which can result in issues arising in the future.
We are going to cover some of the important aspects of non-functional testing, but it is a whole other topic that we will discuss in another post.
Let’s look at them one by one.
Performance Testing
- Load Testing – Gradually increase the number of concurrent users or requests to assess the API’s performance under varying loads. Verify how the API is behaving under varying loads.
- Spike Testing – Test the API’s behavior to a sudden spike in the load.
- Endurance testing – Test that API can handle the expected load over a long period of time.
- Scalability testing – Verify the API effectiveness in “scaling up” to support an increase in user load. It helps plan capacity addition to your software system.
There are many other types of performance testing that one can use to measure the performance of the API.
Reliability Testing
- Basic Functionality Testing – Test the API continuously over a long duration to ensure that core features remain operational without disruptions.
- Failover testing – Verify that the API gracefully handles the scenarios where one or more components associated with the API fail or give errors.
- Data Recovery and Backup – Verify that data recovery and backup mechanisms work effectively.
- Auto-Scaling – Verify the auto-scaling mechanisms, if applicable. It’s the ability of the system to adjust resource allocation based on load.
Security Testing
- Denial of Service (DoS) Testing – Verify that the system can detect and mitigate DoS attacks effectively.
- Security Logging and Monitoring – Suppose you are testing a payments API that involves credit card numbers, CVV, etc. In this scenario, we should only print the masked credit card number in the logs. There are many such scenarios where it is important to verify that no sensitive information should be printed in the application logs.
- There are a few other security-related tests that we already covered when we talked about authorization, SQL injection, security-related headers, etc.
We hope you enjoyed reading the article. If you feel that we missed mentioning some important cases, please feel free to let us know in the comments section or you can also email us at admin@codekru.com. We will try our best to include as many cases as possible in one place to provide a comprehensive list to our readers.