API Testing with Playwright: Handbook for beginners
Table of Contents
When it comes to testing APIs, having efficient tools and frameworks is crucial. Playwright, a powerful automation library, not only excels in browser automation but also provides seamless API testing capabilities. In this article, we'll delve into how Playwright can be leveraged for API testing in Python.
Installation
To begin with, let's set up our testing environment. We'll need Python installed on our system along with the Playwright library. Playwright can be installed via pip, ensuring compatibility with various operating systems.
pip install pytest-playwright
Once Playwright is installed, we'll also need Pytest, a popular testing framework for Python.
pip install pytest
Understanding the Test Suite
Now that our environment is set up, let's take a closer look at the test suite we'll be writing. Our suite consists of test functions targeting different HTTP methods: GET
, POST
, PUT
, and DELETE
. These functions utilize the capabilities of the Playwright library to send requests and validate responses.
import os from typing import Generator import pytest from playwright.sync_api import Playwright, APIRequestContext __BASE_URL__ = "https://httpbin.dmuth.org/" @pytest.fixture(scope="session") def api_request( playwright: Playwright, ) -> Generator[APIRequestContext, None, None]: headers = { "Accept": "application/json", "User-Agent": "articles.eminmuhammadi.com", } request_context = playwright.request.new_context( base_url=__BASE_URL__, extra_http_headers=headers ) yield request_context request_context.dispose()
The api_request
fixture is responsible for creating a new API request context using Playwright. It sets the base URL for all requests and can include additional headers if needed. After yielding the request context to tests, it ensures proper disposal afterward.
def test_get(api_request: APIRequestContext) -> None: response = api_request.get("/get/args/?foo=bar") assert response.status == 200 assert response.ok assert response.json()["foo"] == "bar"
This code block defines a test function named test_get
that verifies the functionality of a GET request to a specific endpoint. The function takes an APIRequestContext
object named api_request
as a parameter, indicating that it's part of a test suite using pytest. Inside the function, a GET request is sent to the "/get" endpoint using the api_request
object, which encapsulates the context for making HTTP requests.
def test_post(api_request: APIRequestContext) -> None: data = { "foo": "bar", } response = api_request.post("/post", data=data) assert response.status == 200 assert response.ok assert response.json()["data"]["foo"] == "bar"
This code block defines a test function named test_post
responsible for testing the functionality of a POST request to a specific endpoint. Within the function, a Python dictionary named data
is defined, representing the payload to be sent along with the POST request. This payload typically contains key-value pairs of data that the API endpoint expects to receive. The api_request
object, which encapsulates the context for making HTTP requests, is then used to send a POST request to the "/post" endpoint, including the defined data
.
def test_put(api_request: APIRequestContext) -> None: data = { "foo": "bar", } response = api_request.put("/put", data=data) assert response.status == 200 assert response.ok assert response.json()["data"]["foo"] == "bar"
This code block defines a test function named test_put
, specifically designed to assess the functionality of a PUT request to a designated endpoint. Within this function, a Python dictionary named data
is created, serving as the payload to be included in the PUT request. This payload typically contains the data to be updated or modified on the server side. The api_request
object is then employed to dispatch a PUT request to the "/put" endpoint, incorporating the specified data
.
def test_delete(api_request: APIRequestContext) -> None: response = api_request.delete("/delete") assert response.status == 200 assert response.ok
This code block defines a test function named test_delete
responsible for evaluating the behavior of a DELETE request to a specific endpoint. Within this function, the api_request
object, which encapsulates the context for making HTTP requests, is utilized to dispatch a DELETE request to the "/delete" endpoint. This action is intended to remove or delete a resource from the server.
After the request is sent, two assertions are utilized to check the response: initially, it validates that the response's HTTP status code is 200, signifying a successful request, while subsequently ensuring that the response object meets the criteria of being "OK," typically denoted by a status code within the 200-299 range. These assertion procedures are pivotal in verifying the proper handling of GET, POST, PUT, DELETE requests by the API endpoint, thereby safeguarding the integrity and effectiveness of the API's deletion functionalities.
Results
To view test results using pytest-html
, you can follow these steps
pip install pytest-html
Once installed, you can run pytest with the --html
option followed by the desired filename for the HTML report
pytest --html=report.html
The HTML report provides a comprehensive overview of the test results, including the number of tests passed, failed, and skipped, along with any errors or failures encountered during testing. You can navigate through the report to view details of each test case, including the test name, status, duration, and any captured output or exceptions.
By following these steps, you can generate and view an HTML report of your test results using pytest-html
, providing a more structured and visually appealing way to analyze the outcomes of your test suite.
Conclusion
In conclusion, testing APIs is essential in ensuring the reliability and functionality of web applications. With Playwright, developers have access to a versatile automation library that not only excels in browser automation but also provides seamless capabilities for API testing in Python.
By utilizing pytest-html, developers can generate comprehensive HTML reports of their test results. These reports offer detailed insights into the test outcomes, including the number of tests passed, failed, or skipped, along with any encountered errors or failures. This structured presentation facilitates easy analysis and debugging, ultimately contributing to the overall quality and reliability of the tested APIs.
In conclusion, leveraging Playwright for API testing in Python, coupled with pytest and pytest-html, provides developers with robust tools and frameworks to streamline the testing process, leading to more resilient and dependable web applications.