Starter Code for Creating a Fully Fledged API Tester in Python

In today’s development environment, APIs are crucial for facilitating communication between various systems. When building code, I aim to eliminate potential problem areas by using variations of the code below to test APIs. This is my starter template.

This article will guide you through the starter code used in creating a fully-fledged API tester in Python, leveraging libraries like requests for making HTTP requests and unittest for structuring tests.


Prerequisites

Before we begin, ensure you have Python installed on your system. You can install the necessary libraries using pip:

pip install requests
pip install jsonschema
pip install unittest

Step 1: Setting Up the Project Structure

Create a project directory with the following structure:

api_tester/

├── tests/
│   ├── __init__.py
│   └── test_api.py

├── api_tester.py
└── config.py

Step 2: Configuration File

In config.py, define the configurations for your API, such as the base URL and endpoints:

# config.py
BASE_URL = "https://api.example.com"
ENDPOINTS = {
    "login": "/auth/login",
    "user": "/user",
    "posts": "/posts"
}
HEADERS = {
    "Content-Type": "application/json"
}

Step 3: Creating the API Tester

The core of your API tester will be in api_tester.py. This script will handle making requests and validating responses.

# api_tester.py
import requests
from config import BASE_URL, ENDPOINTS, HEADERS

class APITester:
    def __init__(self, base_url=BASE_URL):
        self.base_url = base_url

    def get(self, endpoint, params=None, headers=HEADERS):
        url = f"{self.base_url}{endpoint}"
        response = requests.get(url, params=params, headers=headers)
        return response

    def post(self, endpoint, data=None, headers=HEADERS):
        url = f"{self.base_url}{endpoint}"
        response = requests.post(url, json=data, headers=headers)
        return response

    def put(self, endpoint, data=None, headers=HEADERS):
        url = f"{self.base_url}{endpoint}"
        response = requests.put(url, json=data, headers=headers)
        return response

    def delete(self, endpoint, headers=HEADERS):
        url = f"{self.base_url}{endpoint}"
        response = requests.delete(url, headers=headers)
        return response

Step 4: Writing Tests

Create test cases in tests/test_api.py using the unittest framework. This will allow you to automate your API tests and validate responses.

# tests/test_api.py
import unittest
from api_tester import APITester
from config import ENDPOINTS

class TestAPI(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.api_tester = APITester()

    def test_get_user(self):
        response = cls.api_tester.get(ENDPOINTS['user'])
        self.assertEqual(response.status_code, 200)
        self.assertIn('application/json', response.headers['Content-Type'])
        data = response.json()
        self.assertIn('id', data)
        self.assertIn('name', data)

    def test_login(self):
        payload = {"username": "testuser", "password": "testpass"}
        response = cls.api_tester.post(ENDPOINTS['login'], data=payload)
        self.assertEqual(response.status_code, 200)
        self.assertIn('application/json', response.headers['Content-Type'])
        data = response.json()
        self.assertIn('token', data)

    def test_create_post(self):
        payload = {"title": "New Post", "body": "This is a new post."}
        response = cls.api_tester.post(ENDPOINTS['posts'], data=payload)
        self.assertEqual(response.status_code, 201)
        self.assertIn('application/json', response.headers['Content-Type'])
        data = response.json()
        self.assertIn('id', data)
        self.assertEqual(data['title'], "New Post")

    def test_update_post(self):
        payload = {"title": "Updated Post"}
        response = cls.api_tester.put(f"{ENDPOINTS['posts']}/1", data=payload)
        self.assertEqual(response.status_code, 200)
        self.assertIn('application/json', response.headers['Content-Type'])
        data = response.json()
        self.assertEqual(data['title'], "Updated Post")

    def test_delete_post(self):
        response = cls.api_tester.delete(f"{ENDPOINTS['posts']}/1")
        self.assertEqual(response.status_code, 204)

if __name__ == "__main__":
    unittest.main()

Step 5: Running the Tests

To run your tests, simply execute the test_api.py script:

python -m unittest discover tests

This command will discover and run all the tests in the tests directory.

Enhancing the API Tester

To make your API tester more robust, consider adding the following features:

  • Authentication Handling: Automate login and token management to test authenticated endpoints.
  • Schema Validation: Use libraries like jsonschema to validate the structure of API responses.
  • Logging and Reporting: Implement logging to record test results and generate reports.

Thank you for following along with this utility. We hope you found it helpful and informative. If you have any questions, or if you would like to suggest new Python code examples or topics for future tutorials/articles, please feel free to join and comment. Your feedback and suggestions are always welcome!

You can find the same tutorial on Medium.com

Leave a Reply