Skip to main content

Command Palette

Search for a command to run...

#3 - API Testing with requests

What Really Happens When You Call requests.get() API Testing using requests and pytest

Published
3 min read
S

• Possess over 14 years of experience in Quality Engineering, specializing in building test frameworks for complex systems including web applications, REST APIs, and core cloud infrastructure on platforms like Akamai's Linode and Azure.

• Skilled in the development and improvement of automation frameworks for various Web applications, service APIs displaying proficiency in TestNG, PyTest, Selenium, Rest Assured, Jenkins pipeline.

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 get call with params - requests.get() is wrapper to make HTTP GET call

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

Below is behind the scene calls for above get() call

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 build a Response object.

  • Status code

  • Response headers

  • Raw response body

  • Timing information

Helper methods like .json()

The Session Is Closed Automatically

with Session() as session:

Once the response is returned:

  • The session is closed

  • Connections are released


API Testing using requests and pytest

In this section will use requests module to make API requests, process response, add assertion and execute 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 support for multiple execution

  • Created user payload using Python dictionary but API doesn’t understand Python dictionary

  • Requests module convert python dictionary to JSON string using json.dumps(create_user_payload) before sending request and also append header as Content-Type: application/json→ Serialization

  • To process the response body we need to convert response bytes to 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 using pytest and uv

Rest of test can be found here → https://github.com/sksingh329/gorest-api-test/blob/basics/gorest-crud/tests/test_gorest_crud.py

# 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 package 
uv sync

# Export token 
export API_TOKEN=<replace with your token>

# Run specific test 
uv run pytest -s tests/test_gorest_crud.py::test_create_user

# Run all tests 
uv run pytest

In this section, we used requests to make API calls and pytest to execute tests. This approach works well for basic testing, but it doesn’t scale. To build a maintainable and scalable test suite, we need shared utilities—such as requests.Session, pytest fixtures via conftest.py, and structured HTML reporting—which will be covered in upcoming articles.

API Testing | Pytest & requests

Part 3 of 5

A practical series on building a scalable, production-ready API testing framework using Python, requests and Pytest. Covers modern project setup, clean architecture, real-world API scenarios, and CI integration.

Up next

#4 - Pytest concept

pytest is one of the most widely adopted testing frameworks in the Python ecosystem. It provides a clean, expressive, and highly extensible way to write tests—ranging from simple unit tests to large-scale API and integration test suites. Tests are wr...