REST API Testing Using Python
REST or RESTful API using JSON format has been very popular now because of its simplicity I believe. In this article, I am going to show you how to use Python to create a REST automation test suite using requests and flask modules.

Postman
First, I recommend you install and play with Postman. It allows you to create manual test scripts easily and also some level of automation (semi-automation) using variables and response assertion (Javascript only). The most important thing here is it can convert the manual scripts to sample codes in almost any languages including Python, so it is a good start point if you are new to API automation.
It is just 4 steps to create a Postman API request test:
- Select a request method
- Provide the API URL
- Add customized headers
- Add body
Then just click the Send button to send the request and check the response data.
And you can click the ‘Code’ button to convert the same request to a code snippet of your choice, e.g. Python in this case as shown below. Save the code into a python file, e.g. postman_code_snippet.py, and run it, and you will get the same response as you run the manual test in Postman.

Build First Python REST API Test
To build a Python REST API test suite, you will need to install Python3 first, and below modules (using pytest test framework in this example).
pip install -U requests Flask pytest pytest-html
or install with pip3 if you have both Python2 and Python3 installed:
pip3 install -U requests Flask pytest pytest-html
Now let’s re-write the above code snippet in a simpler way and convert it to a pytest test as below.
As you can see, the Python script also just follows the steps as simple as Postman.
- Provide API URL
- Add customized headers
Standard headers like Content-Length are taken care of by requests module. - Add body
Just create a dictionary variable for your request body, and convert it to json string format using json.dumps() function. - Select a request method
Use requests.post function for post request, and likewise requests.get for get request, etc.
Then we can simply validate the response by checking the response object resp. For example, resp.status_code
for response status code, and resp.json()
for response body content. Below is the response body print for this post request test, and to validate a field in the response body, e.g. “url”, we can just call assert resp.json()["url"] == "https://httpbin.org/post"
.
{
"args": {},
"data": "{\n \"key1\": 1,\n \"key2\": \"value2\"\n}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "39",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "Python Requests"
},
"json": {
"key1": 1,
"key2": "value2"
},
"origin": "103.115.210.48, 103.115.210.48",
"url": "https://httpbin.org/post"
}
Writing tests in Python is so easy and it gives the power of a programming language to support any flexibility needs, e.g. generate unique transaction id, read test data from a file, looping, or call another dependent API dynamically for an authentication token, etc.
Run with pytest
To run the test with pytest test framework, we need to define the function with test_ prefix and save the file with test_ prefix in the filename, e.g. test_post_headers_body_json.py. Then to run the test, just open a command prompt and type pytest
in the script folder, and you will get a test result as follows.
pytest
================ test session starts =======================
platform win32 -- Python 3.7.3, pytest-4.4.1, py-1.8.0, pluggy-0.9.0
rootdir: D:\REST_API_Test_Framework_Python\Scripts\code_snippets
plugins: metadata-1.8.0, html-1.21.1
collected 1 itemtest_post_headers_body_json.py . [100%]================= 1 passed in 1.61 seconds ====================
To get more details and generate a html report, run with below parameters. Check pytest --help
for option details.
pytest -sv --html report.html
Logging
When something goes wrong, it is nice to a full snapshot of every request sent and response received, like the Postman console feature. So we add two pretty print functions as below to print every header, body and status code for request and response. And you can call them by pretty_print_request(resp.request)
and pretty_print_response(resp)
.
Of course you can write the logging to a file as well, e.g. using the standard logging module, as shown in the repository at the end.
Mocking with Flask
We use Python requests module to send requests, and can use Flask module to mock server endpoints. So you can perform TDD test development or validate your test code.
For example, below is the code to mock a service endpoint http://127.0.0.1:5000/json and return json format response
{“code”: 1, “message”: “Hello, World!” }.
Just save the code as a file, e.g. flask_mock_simple_service.py, and run it by python flask_mock_simple_service.py
.
Then you can access this service by typing http://127.0.0.1:5000/json in a browser.

Or you can write a Python request test code as below.
Put It All Together
To put it together, you can download the full Python REST API test framework example below, which includes everything mentioned above and more.
Appendix: Python vs JSON Format
Python dictionary looks very like JSON format, but there are still some differences, so you cannot simply put a quote around a dictionary to convert it to JSON string format, though it works most of the time, e.g. ‘{“key1”: “value1”}’ is a valid JSON string format.
Below is data mapping between Python and JSON format. Also note that JSON format always uses double quotes for strings.

Thanks for reading. Please help click “clap” if you like it.
[Update: See also part 2 - Scale-up REST API functional tests to performance tests in Python]