Recently I wrote a blog post on API testing in Python, but I only talked about GET requests there. In this tutorial we are going to look at POST and PUT requests and how to provide data for it.

Most of the API’s require you to provide access token which normally goes in header and in case of POST and PUT we would need some data that goes in message body.

For this learning exercise we going to use python requests library, we also going to look at Postman for better understanding.

Let’s assume that we have classroom project where user can provide credentials and in response get the token. Once the token received user can signup for the class he would like to take. And then he can mark the class as complete once it is finished. Here is how our api will look like

POST: base_url/user/token
POST: base_url/classes/signup
PUT: base_url/user/classes/{class}

First thing first lets look at the token request. Bellow is the screenshot of how it looks like in Postman

Now lets try make the same call in Python.

def get_token():
    base_url = api_base_url
    data = {
        'email': 'email_address@example.com',
        'password': 'some_password'
    }

    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Accept': 'application/json'
    }

    response = requests.post(f'{base_url}/users/token', headers=headers, data=data)
    assert response.status_code is 200

    response_body = response.json()
    return response_body['accessToken']

Here is what’s happening in get_tocken() function that we created. First we need base_url for our call. Then similar how we provide message body in Postman we create Python dictionary with data that we need. Then we add dictionary for the headers (it can vary depend on your project). Now all is left is make a POST request with all the info in it and store the response. Here is how our response look like in JSON:

{
"accesToken": "our_token_here"
}

Then we made a simple status code assertion and returning accessToken. Now since we can get our token lets actually run the test and signup for the class.

def test_post_class_signup():
    base_url = api_base_url
    token = self.get_token()
    headers = {'X-User-Token': token}
    data = {'class': 'CS50'}
    response = requests.post(f'{base_url}/classes/signup', headers=headers, data=data)
    assert response.status_code is 201

Let’s look at what we do here. First we call get_token function, then we supply the token in the header of the request and setting up the data for message body. Then we make POST request and asserting status_code.

Ok we signed up for class, now lets try to update with status.

def test_update_class_status():
    base_url = api_base_url
    token = self.get_token()
    headers = {'X-User-Token': token}
    params = {'success': True }
    class = 'CS50'

    response = requests.put(f'{base_url}/user/classes/{class}', headers=headers, params=params)
    assert response.status_code is 201

The update_class_status() function similar to test_post_class_signup(), except there is few key differences. We are using PUT to update the object and we extending our url using params dictionary. Basically this make our url look like this:

PUT: base_url/classes/{class_id}?success=true

And that is pretty much it, we have successfully created few tests with POST and PUT requests in python. I use pytest as test runner and assertion library, but you can use whatever unit testing library you prefer.

Hope this blog post helps and as always feel free to post your comments in the section below.