Mastering API Automation: Testing POST and DELETE Requests with Python
In our previous discussions about API testing, we focused heavily on retrieving data using GET requests. While verifying data structure is crucial, real-world applications don't just read data—they create, update, and delete it.
To ensure the full lifecycle of your application's data is functioning correctly, your API testing framework must cover data mutation. In this article, we'll explore how to automate testing for POST (create) and DELETE (remove) endpoints using Python and Pytest.
Why Test Mutations Differently?
Testing a GET endpoint is usually straightforward: you ask for data and check if it's there. Testing mutations involves state changes:
- POST (Create): You must verify not only that the server accepted your payload (usually returning a
201 Createdstatus), but also that the response contains the assigned unique ID and matches the data you sent. - DELETE (Remove): You must ensure the resource is properly removed (often returning a
200 OKor204 No Contentstatus) without affecting other data.
Real-World Scenario: A Blog API
Let's imagine we are testing a Blog platform's API. We need to verify that our system allows users to publish new posts and delete existing ones. We will use the public mock API jsonplaceholder.typicode.com.
Step 1: The Setup
Ensure you have your environment ready:
pip install pytest requests
Step 2: Writing the Tests
Create a file named test_posts_api.py. We will write two tests: one to create a post and one to delete it.
import requests
import pytest
BASE_URL = "https://jsonplaceholder.typicode.com"
def test_create_new_post():
"""
Test that sending a valid POST request creates a new resource.
"""
# 1. Define the payload (the data we are sending)
payload = {
"title": "Automating API Tests",
"body": "This is a great tutorial on testing.",
"userId": 1
}
# 2. Make the POST request
response = requests.post(f"{BASE_URL}/posts", json=payload)
# 3. Assert Status Code for creation (201 Created)
assert response.status_code == 201, f"Expected 201, but got {response.status_code}"
# 4. Assert Response Content matches our payload
response_data = response.json()
assert response_data["title"] == payload["title"]
assert response_data["body"] == payload["body"]
assert response_data["userId"] == payload["userId"]
# 5. Ensure the server assigned a unique ID
assert "id" in response_data
def test_delete_post():
"""
Test that sending a DELETE request properly removes a resource.
"""
post_id = 1
# 1. Make the DELETE request
response = requests.delete(f"{BASE_URL}/posts/{post_id}")
# 2. Assert Status Code
# JSONPlaceholder returns 200 OK for successful deletes.
# Real APIs might return 204 No Content.
assert response.status_code == 200, f"Expected 200, but got {response.status_code}"
# 3. Verify the response is empty
assert response.json() == {}
Step 3: Execution
Run your tests using the pytest command:
pytest test_posts_api.py -v
Output:
============================= test session starts ==============================
test_posts_api.py::test_create_new_post PASSED [ 50%]
test_posts_api.py::test_delete_post PASSED [100%]
============================== 2 passed in 0.85s ===============================
Best Practices for Mutation Testing
When building these tests in a production environment, keep these tips in mind:
- Test Isolation: A
DELETEtest shouldn't break aGETtest. Ensure your tests create their own temporary data to work with (e.g., using Pytest fixtures to setup and teardown data). - Edge Cases: What happens if you try to
POSTa post with a missing title? What if you try toDELETEa post that doesn't exist? Your framework should assert that the API returns the correct400 Bad Requestor404 Not Founderrors in these scenarios. - Headers and Auth: Most
POSTandDELETErequests require authentication. Always pass the correctAuthorizationheaders.
Conclusion
By incorporating POST and DELETE testing into your framework, you ensure that your API isn't just a static database, but a fully functioning, reliable service. Happy automating!
Top comments (0)