A little bit about API testing automation

Testing of network applications is divided into several interrelated stages and significantly depends on the correctness of the API. It is not uncommon for an API to publish a large number of methods that manipulate datastore objects, some of which are protected by authorization mechanisms. Tests include a sequence of operations for creating-modifying-deleting objects and may consist of a large number of requests, which are preferably checked without the participation of a tester. In this article, we’ll discuss different approaches to automating API tests using Postman, Rest Assured, and Karate DSL.
Let’s start with the most famous tool for interacting with the API – Postman. It is typically used to manually make requests to the API. When creating a query, variables and the environment (defined for a collection or a single query) can be used. But it is also now possible to define scripted tests using a built-in interpreter that can work with a pre-configured pm object to extract the value of variables and execute queries.
Let’s create a new workspace (File -> New -> Workspace) and a collection (File -> New -> Collection). Note that when creating a collection, the Tests tab is available, which defines a script that will be executed after each request in the collection.

To execute requests, the pm.sendRequest(url, function(err, response) { … }); method is used, where an object with information about the server response or an error description object is passed to the function. You can use the function to check if the condition is met. pm.test("message", function () { выражение })
which may contain pm.expect()
to test the condition inside the test. The expression is written as a phrase <объект>.to.<условие>.<ожидаемое значение>
for example, response.to.have.status(200)
or except(response.text()).to.eql('OK')
. The content of the response can be extracted from response.text() or response.json() and inspected via pm.test
/ pm.expect
. There is also access to environment variables (pm.environment), collection variables (pm.collectionVariables
), local variables (pm.variables
). Otherwise, the script code can use all JavaScript features (functions, conditional statements, loops, …), including outputting messages to the console (it is available in Postman through the menu View -> Show postman console
).
When defining a query, all tests are run after the query is executed. In this case, the query script can store intermediate values in pm.environment
and pass them to the next request from the collection or group. Query results are available in pm.response
.
To run tests in the context menu of the collection, select Run collection, specify the number of iterations and the interval between them. The result of the execution will be information about the results of the execution of requests in iterations and a report on the success of the passage.
To test, let’s create a simple test for the Date Nager API (returns information about holidays in many countries around the world). To get a JSON response, we turn to the address https://date.nager.at/api/v3/publicholidays/2017/EN and check for the presence of the holiday “New Year” in the response. Create a GET request to the address and add the following code in the Tests tab:
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
pm.test("Response time is less than 400ms", function () {
pm.expect(pm.response.responseTime).to.be.below(400);
});
pm.test("Response have new year", function() {
const responseJson = pm.response.json();
pm.expect(responseJson[0].localName).to.eql("Новый год");
});
After running the query (or the entire collection), we get the result of the execution:

To access methods protected by an authorization token, you can use the usual Postman handling of request headers.
Now let’s move on to more specialized tools and talk about Rest Assured. The code for Rest Assured is created in Java, each test is a separate function with the @Test annotation, which consists of two parts:
when() – a chain of calls that creates the necessary context, for example, get(“url”)
then() – a chain of checks (statusCode checks the response code, body(“path”, equalTo(“value”) checks the value of a json object or XML structure field).
For example, our Rest Assured test would look like this:
@Test
public void testNewYear() {
when().get("https://date.nager.at/api/v3/publicholidays/2017/RU").
then().statusCode(200).body("[0].localName", equalTo("Новый год"))
}
The main advantage of RestAssured is that it is a full-fledged java library and allows you to perform complex processing of the received data, as well as to integrate into existing Java-Kotlin applications (directly into the task of running automated tests, for example, via JUnit).
The last library we will look at today is Karate DSL. Its capabilities are extensive and go far beyond scripted API testing, but for now we will only discuss the possibilities for creating API tests. The script for Karate DSL is created as a text document that defines the test specification from the expression Given (variable definition), When (query definition), Then (test conditions). In our case, the description might look like this:
Scenario: Test Date Nager API
Given url 'https://date.nager.at/api/v3/publicholidays/2017/RU'
When method get
Then status 200
And match response[0].localName == 'Новый год'
Test can be integrated into JUnit and also executed via standalone jar file or through extension Visual Studio Code. To run the test, just pass the name of the feature file (java -jar karate.jar datetest.feature
). The test result report will be displayed in the console, and the return code will also be set to 0 (on success) or an error code, allowing Karate DSL to be used when automatically running tests in CI/CD.
How to write a bug report so that colleagues thank you? My colleagues from OTUS will tell about this and not only at a free lesson, which will be held on August 10th. Registration for the class is available via this link..