Automating REST API CRUD Operations with Python and pytest

Automating REST API CRUD Operations with Python and pytest

Step 1: Set Up the Project Start by creating a new directory for your project and navigate to it in your terminal. Then, initialize a new Python virtual environment and activate it:

$ mkdir rest_api_tests
$ cd rest_api_tests
$ python3 -m venv venv
$ source venv/bin/activate

Step 2: Install Dependencies Next, install the required dependencies: pytest for writing and executing tests, and requests for making HTTP requests to the API:

(venv) $ pip install pytest requests

Step 3: Create Test Files Inside your project directory, create a new directory called tests and navigate to it. Create a new Python file, such as test_crud.py, to hold your CRUD tests:

(venv) $ mkdir tests
(venv) $ cd tests
(venv) $ touch test_crud.py

Step 4: Write CRUD Tests Open test_crud.py in a text editor and import the necessary modules:

import pytest
import requests

Next, define your test functions. Here's an example that demonstrates CRUD operations for a hypothetical "users" endpoint:

@pytest.fixture
def base_url():
    return 'https://api.example.com/users'

def test_create_user(base_url):
    data = {
        'name': 'John Doe',
        'email': 'johndoe@example.com'
    }
    response = requests.post(base_url, json=data)
    assert response.status_code == 201
    assert 'id' in response.json()

def test_get_user(base_url):
    response = requests.get(base_url + '/1')
    assert response.status_code == 200
    assert response.json()['name'] == 'John Doe'

def test_update_user(base_url):
    data = {
        'name': 'Jane Smith'
    }
    response = requests.put(base_url + '/1', json=data)
    assert response.status_code == 200
    assert response.json()['name'] == 'Jane Smith'

def test_delete_user(base_url):
    response = requests.delete(base_url + '/1')
    assert response.status_code == 204

def test_get_nonexistent_user(base_url):
    response = requests.get(base_url + '/1')
    assert response.status_code == 404

In this example, we're using the base_url fixture to set the base URL of the API. Each test function performs a specific CRUD operation and asserts the expected HTTP status code and response data.

Step 5: Run the Tests To execute the tests, go back to the project's root directory and run pytest:

(venv) $ cd ..
(venv) $ pytest

You should see the test execution output, including the number of tests run and their status.

Now, let's discuss the pytest fixture and the behavior of the requests module:

  1. Pytest Fixture:

    • In the code, we have added a pytest fixture called base_url. Fixtures in pytest are used to provide reusable setup and teardown code for tests.

    • The base_url fixture returns the base URL of the API. By using a fixture, we can define the base URL once and reuse it across multiple tests.

    • Fixtures provide a convenient way to manage and share common test data or resources, making the test code more modular and maintainable.

  2. Requests Module:

    • The requests module is a popular HTTP library in Python used for making HTTP requests to APIs.

    • In our test functions, we import the requests module to interact with the API endpoints.

    • The requests module is not a singleton. Each time you call a function from the requests module, it creates a new instance of the Session class to handle the HTTP request.

    • This behavior allows you to make separate HTTP requests independently, manage cookies or sessions, and configure different options for each request.

By using pytest fixtures, we can set up common test data or resources once and reuse them across multiple tests. The requests module, on the other hand, allows us to make HTTP requests and handle the responses conveniently within our test functions.

That's it! You've created a test suite for your REST API using Python and pytest. You can expand on this example by adding more tests or modifying it to fit your specific API endpoints and data models.