January 12, 2026

#3 - API Testing with requests

api-testingpythonpytestrequests

Python requests module

requests is a high-level HTTP client for Python that lets you talk to APIs using simple, readable code instead of low-level networking.

What really happens when you call requests.get()

Below is a GET call with params — requests.get() is a wrapper to make an HTTP GET call:

response = requests.get(url="https://gorest.co.in/public/v2/users", params={"page": 2})

Here's what happens behind the scenes for that call:

Diagram showing requests.get() call flow

Internally this calls requests.api.request()

requests.api.get(url)

requests.api.request("GET", url, **kwargs)

A temporary session is created

  • A new Session object is created
  • It exists only for this single request
  • It is managed using a context manager
  • It is automatically closed after the request completes
with sessions.Session() as session:
    ...

A Request object is built

req = Request(
         method="GET",
         url="https://gorest.co.in/public/v2/users",
         params={"page": 2}
)

The request is prepared

  • Query params are URL-encoded
  • ?page=2 is appended to the URL
  • Headers are merged and normalized
  • Default headers like User-Agent are added
  • Body (if any) is serialized
prepared_req = session.prepare_request(req)

The prepared request is sent

  • DNS lookup happens
  • TCP connection is opened
  • TLS handshake occurs (for HTTPS)
  • HTTP request bytes are sent
  • Server response is received
response = session.send(prepared_req)

A Response object is created

Once the server replies, requests builds a Response object containing the status code, response headers, raw response body, timing information, and helper methods like .json().

The session is closed automatically

with Session() as session:
    ...

Once the response is returned, the session is closed and connections are released.

API testing using requests and pytest

In this section we use the requests module to make API requests, process the response, add assertions, and execute everything using pytest.

Setup variables

BASE_URL = "https://gorest.co.in/public/v2"
USERS_ENDPOINT = f"{BASE_URL}/users"
USER_ENDPOINT = f"{USERS_ENDPOINT}/{{user_id}}"
TOKEN = os.environ.get("API_TOKEN")
 
headers = {"Authorization": f"Bearer {TOKEN}"}

Create user flow

  • Using Faker to create unique user data, to support repeated execution.
  • The created user payload is a Python dictionary — but the API doesn't understand Python dictionaries.
  • The requests module converts the Python dictionary to a JSON string via json.dumps(create_user_payload) before sending the request, and appends the header Content-Type: application/jsonserialization.
  • To process the response body we convert response bytes back to a Python dictionary — deserialization — using response_body = response.json(), which internally calls json.loads(decoded_response_text).
def test_create_user():
    # Create unique data for multiple execution
    fake = Faker()
    username = fake.name_male()
    user_email = fake.email()
    user_gender = "male"
    user_status = "inactive"
 
    # create user payload as python dict
    create_user_payload = {
        "name": username,
        "email": user_email,
        "gender": user_gender,
        "status": user_status
    }
 
    # send POST request
    response = requests.post(url=USERS_ENDPOINT, headers=headers, json=create_user_payload)
    response_body = response.json()
 
    print(f"Status Code: {response.status_code}")
    print(f"Response Body: {response_body}")
 
    # Assertion
    assert response.status_code == 201
    assert response_body["name"] == username
    assert response_body["email"] == user_email
    assert response_body["gender"] == user_gender
    assert response_body["status"] == user_status

Execute the test using pytest and uv:

uv run pytest -s tests/test_gorest_crud.py::test_create_user

Test execution results screenshot

Test execution using pytest and uv

The rest of the test can be found in the gorest-api-test repository.

# Check uv is installed
uv --version
 
# Clone the repo
git clone https://github.com/sksingh329/gorest-api-test.git
 
# Switch to directory and branch
cd gorest-api-test
git switch basics/gorest-crud
 
# Install required packages
uv sync
 
# Export token
export API_TOKEN=<replace with your token>
 
# Run a specific test
uv run pytest -s tests/test_gorest_crud.py::test_create_user
 
# Run all tests
uv run pytest

Using requests to make API calls and pytest to execute tests provides foundational capability, but building scalable test suites requires additional infrastructure — shared utilities, pytest fixtures via conftest.py, and structured HTML reporting — which the next parts of this series cover.

Originally published on Hashnode.