15. Creating API Tests in Python

15.1. Introduction

Testing APIs requires more complex test data objects and communications protocols. Vitaq’s Test Activity diagram approach is very flexible, providing the user with the ability to abstract their testing needs to focus on the APIs exposed objects or actions. By developing Test Activities that access the components in API services, Vitaq can provide huge variability in auto-generated tests that is ideal for modern API testing.

When testing APIs that are related to software frameworks, you will need to access several API’s often nested within each other. The ability to deeply nest your Test Activity next allowable action will provide the scope for this complex form of testing. Using the ability to dynamically enable and disable your test actions (see Disabling Test Actions) you can develop Test Activities that respond to flow of control from generic frameworks.

15.2. Remote APIs

To test a remote API, you can either develop a Test Interface File that handles communication to the remote resources of the API or have each test Action send a test via the defined protocol into the API.

15.3. Web APIs

For example if your API is defined as a set of HTTP requests along with defined structure of response messages using XML or JSON, then much of the ‘heavy lifting’ is already taken care of in readily available Python open-source libraries.

Whether you are testing SOAP or REST style APIs, Vitaq can be used to create Test Activities with Test Action Scripts that auto-generate tests into multiple APIs for new application mashups.

A useful API target testing resource is provided online at http://jsonplaceholder.typicode.com with a number of JSON object based applications developed around a typical Web API.

15.4. Handling JSON objects

To handle JSON objects in Vitaq we can use the json python library. How to use new python libraries is described in the section Importing Python libraries into Vitaq

First we need to ‘pip’ the package

C:\Python27\scripts> pip install json

then include this line in the imports Test Action Script

import json

15.5. Requests library

To show how you can apply Vitaq to API testing, we will develop a typical example using the requests python library. http://docs.python-requests.org/en/master/ Requests is one of the most downloaded Python packages of all time, claiming over 400,000 downloads each day.

How to use new python libraries is described in the section Importing Python libraries into Vitaq

First we need to ‘pip’ the package

C:\Python27\scripts> pip install requests

then include this line in the imports Test Action Script

import requests

15.6. Web API Test Activity

We will now develop a Test Activity to auto-generate tests into the http://jsonplaceholder.typicode.com todo application. We will need to make HTTP requests, pass parameters in URLs and read the content of the server’s response and for this example we will be handling JSON data. So let’s create an Exhaustive Test Activity that contains GET, POST, PUT, PATCH and DELETE requests abstracted into Vitaq Test Actions. If you need, you can refer to sections Creating Test Actions and Creating a Test Activity

_images/21_Web_API_Test_Activity.png

Notice that we have used the ‘exhaustive’ feature of a Test Action Exhaustive Test Actions The :ref:’Exhaustive_API_Tests’ Test Action will exhaustively call (randomly) all of the Test Actions beneath it until they ‘hit’ their Call Limits Setting Call Limits on test actions .

To auto-generate complex JSON data objects we first create ‘atomic’ Activity variables that we can use in the Test Actions Scripts. These will form the base of more complex data structures, enabling the auto-generation of complex test data with intelligent variability that Vitaq provides.

_images/22_Web_API_Activity_Variables.png

The first Test Action Script we will write is for a GET request to access the current ToDo list from our target test API http://jsonplaceholder.typicode.com/todos Creating-API-Tests

GET_todos

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# ToDo List test
self.variables.ToDo_ID.gen()
print ('The ToDO_ID selected is:', self.variables.ToDo_ID.get_value())
ToDoResponse = requests.get('http://jsonplaceholder.typicode.com/todos')

#ToDoResponse_decoded = ToDoResponse.decode("windows-1252")
print ('The status code attribute of this todo JSON object is', ToDoResponse.status_code)
all_ToDos = json.loads(ToDoResponse.text)
print (all_ToDos[self.variables.ToDo_ID.get_value()])

# User List test
self.variables.User_ID.gen()
print ('The USER_ID selected is:', self.variables.User_ID.get_value())
UserResponse = requests.get('http://jsonplaceholder.typicode.com/users')

#UserResponse = unidecode(UserResponse)
print ('The status code attribute of this user JSON object is', UserResponse.status_code)

# print ('Result of GET:', response.text)
all_users = json.loads(UserResponse.text)
print (all_users[self.variables.User_ID.get_value()])
 

We first use the Vitaq gen gen library method to auto generate a value for the Activity Variables ToDo_ID and User_ID. There are 200 ToDos and 9 users, so we use a Range constraints in the Activity Variables to make sure we get valid data each time w run the Test Activity. .. note:: You can define ranges outside the valid numbers to create negative tests.

Then we use requests to get the todo JSON objects and decode them using json.loads and print the response of the GET

POST_New_todo

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# Use Vitaq libraries to generate new ToDo data 
self.variables.User_ID.gen()
self.variables.NewToDo_ID.gen()
self.variables.Titles.gen()
self.variables.ToDoStatus.gen()

# Use the requests library to send the new todo item to the API
response = requests.post('http://jsonplaceholder.typicode.com/todos')
NewToDo = {"userId": self.variables.User_ID.get_value(),
           "id": self.variables.NewToDo_ID.get_value(),
           "title": self.variables.Titles.get_value(),
           "completed": self.variables.ToDoStatus.get_value()}
ToDoResponse = requests.post('http://jsonplaceholder.typicode.com/todos', json=NewToDo)

# Check API response for errors
if ToDoResponse.status_code != 201:
    raise ApiError('POST /todos/ {}'.format(ToDOResponse.status_code))
print('Created New ToDo. ID: {}'.format(ToDoResponse.json()["id"]))
 

Now we auto-generate values for our ‘atomic’ Activity Variables to feed into a JSON object that we have created a NewToDo

Then we can post that JSON object using requests and check the API response for errors

PUT_update_todo

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Use Vitaq libraries to generate an updated ToDo item
self.variables.ToDo_ID.gen()
self.variables.User_ID.gen()
self.variables.Titles.gen()
self.variables.ToDoStatus.gen()

# Use the requests library to 'update' a todo item through the API
requests.put('http://jsonplaceholder.typicode.com/todos/{:d}/'.format(self.variables.ToDo_ID.get_value()),
             json={'userId': self.variables.User_ID.get_value(),
                   'title': self.variables.Titles.get_value(),
                   'completed': self.variables.ToDoStatus.get_value()
                  }
            )
 

Using the requests python library we send a put request with a auto-generated JSON object a update ‘todo’ through the API