Automated API testing using Pytest library or Playwright? Part 1.

Valentin Lutchanka
7 min readNov 30, 2023

--

1. Intro

In the ever-evolving landscape of software development, the need for robust and efficient testing practices has become more pronounced than ever. Automated testing plays a pivotal role in ensuring that software applications meet their functional requirements, adhere to specifications, and remain resilient to changes.

As APIs become increasingly integral to application architectures, the importance of systematic testing cannot be overstated.

I will try to highlight why automated API testing is becoming a crucial part of Software development nowadays, but please don’t estimate the approaches covered in the article as a criticism or the only right way to perform API testing.

  1. Rapid Development Cycles:

Automated testing expedites the development process by quickly validating the functionality of APIs. As developers iterate through code changes, automated tests provide instant feedback, enabling the early detection of regressions.

2. Ensuring Functional Integrity:

REST APIs often serve as the glue between various software components. Automated testing guarantees that APIs consistently deliver the expected outcomes, preserving the functional integrity of the entire application.

3. Error Detection and Isolation:

By automating the testing process, developers can promptly identify and isolate errors in API implementations. This accelerates the debugging process and minimizes the chances of defects reaching production environments.

4. Continuous Integration and Continuous Delivery (CI/CD):

Automated testing seamlessly integrates with CI/CD pipelines, allowing for the continuous validation of APIs at every stage of development. This integration ensures that only thoroughly tested and validated code is deployed, enhancing the overall software quality.

Well…

We have a huge variability of tools for automating the REST API test. It becomes a matter of personal/company commitment to the particular one. And I always welcome the constructive and positive advice. Feel free to write you personal opinion un the comments.

But now I would like to showcase the API testing approach using the Pytest Python library and briefly compare it with the Playwright (JS).

Lets compare…

Why Pytest for API Testing?

While various testing frameworks exist, Pytest stands out as a versatile and powerful tool for API testing. Here are key benefits of leveraging Pytest in the context of REST APIs:

  1. Simplicity and Readability:
  • Pytest embraces a straightforward syntax, making it accessible to both beginners and seasoned developers. Its concise and expressive code allows for the creation of clear and readable API test scripts.

2. Fixture Support:

  • Pytest’s fixture mechanism simplifies the setup and teardown of test environments. This is particularly advantageous in API testing, where establishing a consistent testing environment is crucial for reliable results.

3. Parametrization for Varied Scenarios:

  • Pytest’s parametrization feature enables the execution of the same test logic with different inputs. This is invaluable in API testing, where various scenarios, endpoints, and data combinations need to be validated.

4. Rich Ecosystem of Plugins:

  • Pytest boasts a rich ecosystem of plugins that extend its functionality. For API testing, this means access to plugins that facilitate tasks such as generating detailed test reports and integrating seamlessly with other testing tools.

What about the Playwright???

1. Full-Stack Testing:

  • Playwright enables testing of both frontend and backend components in a unified manner. This is particularly beneficial for projects where end-to-end testing involves interactions with both the UI and API.

2. Unified Testing Framework:

  • Playwright provides a unified testing framework for different aspects of web applications, including browser automation and API testing. This can lead to a more cohesive testing strategy.

3. Network Intercept and Modification:

  • Playwright allows interception and modification of network requests, which is crucial for API testing. Developers can inspect and manipulate API calls initiated from the front end, providing a comprehensive testing approach.

But in the end, while Playwright offers advantages for API testing, it’s important to note that traditional API testing frameworks like Postman or Pytest may be more tailored for API-specific scenarios. The choice between Playwright and dedicated API testing tools depends on the specific requirements of the project and the desired level of granularity in API testing.

I have some experience with both of them, and I can assume that each tool is appropriate for its own purpose and it depends on a particular project.

In this first part I will showcase the automated API testing using the Pytest.

Our application under the test will be an Airport Gapa RESTful API to help you improve your API automation testing skills. It provides access to a database of airports, calculates distances between airports, and allows you to save your favorite airports. You can check out the documentation

Let’s see the testing scenario:

I will cover a Positive testing of a user path for (GET, POST, PUT/PATCH, DELETE):

  • retrieving the list of the airports,
  • retrieving the particular airport,
  • getting the distance between the airports,
  • checking the user token
  • getting the user favorites
  • creating the favorite airport
  • modifying the created airport
  • deleting the favorited airport

For this tutorial, we will focus on three types of tests:

- Contract: If the API is able to validate the query parameters that are sent

- Status: If the status codes are correct

  • Authentication: We will check the validity of the token and its obligation

Tech setup:

You will need the Python installed on your machine. The rest is quite simple…

Check out the test demo repository with the codebase used in this tutorial.

If you clone the repository and follow the Readme file to setup it is sufficient to run the tests. You only need to create a config.ini file with the desired constants (including the token )

I am using an AAA (Arrange — Act — Assert) approach for the automated testing.

The project structure is:

  1. project_root/: This is the root directory of your project.

2. tests/: This directory contains all your test modules. You can further organize tests into subdirectories based on functionality or endpoints.

  • test_airport.py: Contains tests related to the /airports endpoint.

3. config.ini: This file holds configuration settings, including API endpoints, authentication tokens, or any other configuration required for tests. DO NOT COMMIT IT :)

4. pytest.ini: This file can include configuration settings for Pytest. For example, you can set options like test discovery patterns or plugins. We can specify the test name pattern, flags to be passed to the CLI command, reporter to use, etc…

5. requirements.txt: Lists the dependencies required for your project. Include libraries like Pytest, requests, and any other dependencies needed for testing.

this is how we set the requirements and initialize the variables in the test_airport.py file:

The main test script follows:

I use Test Classes to organize the tests structure

Pros:

  1. Organization: Test classes provide a natural way to group related test methods.
  2. Sharing Setup Code: You can use setup and teardown methods within a class to share setup and teardown code among test methods.
  3. Test Lifecycle Management: Test classes offer more control over test lifecycle management.

Cons:

  1. Increased Complexity: For small and simple test suites, using classes might introduce unnecessary complexity.
  2. Learning Curve: Some developers might find the class-based approach less intuitive, especially if they are more familiar with function-based tests.

Each testing function in the Test Class follows the AAA approach, and tests are parametrized, which gives us:

  1. Diverse Test Cases: Parametrization allows you to run the same test logic with different input values. This is particularly useful when testing functions or methods that should behave consistently across various inputs.
  2. Reduced Code Duplication: Instead of writing multiple test functions that follow a similar structure, you can use parametrization to define a test once and run it with different inputs. This helps in maintaining cleaner and more concise test code.
  3. Improved Test Coverage: By providing a range of inputs, you can increase your test coverage, ensuring that your code is robust and handles different scenarios effectively.
  4. Easier Maintenance: When changes are made to the test logic, having parameterized tests means you only need to update the test in one place. This reduces the chances of introducing errors during maintenance.
  5. Clearer Test Output: When a parametrized test fails, testing frameworks often provide detailed information about which set of parameters caused the failure. This makes it easier to identify and fix the issue.
  6. Data-Driven Testing: Parametrization allows you to perform data-driven testing, where you can separate the test logic from the test data. This makes it easy to add or modify test cases without changing the test code.

Lets run the tests:

Well, the test covers the testing scenario in just 4.36s. (SPOILER: in the Part 2 we will try the same scenario with the Playwright :) ). It is impressively fast 😍.

The test results, apart from stdout, can be seen in the reports folder — there will be generated an HTML report.

I hope this showcase can be useful in getting insights on how we can leverage the Pytest for API testing.

I am quite happy if you read this line 😄.

In Part 2 of this article, I will showcase the same API testing scenario using the Playwright with JavaScript, so we can compare the two approaches and see the pros and cons of each one.

I appreciate any ideas, suggestions or improvements, feel free to comment… and happy coding!!! 😄.

If you like the story feel free to buy me a coffee 😍

--

--