Skip to main content

Utility for generating tests for FastAPI routers and endpoints

Project description

FATestGenerator

FATestGenerator is a utility for automatically generating tests for APIs built with FastAPI. The library allows you to quickly create tests for your routes and neatly organize their structure.

Особенности

  • Test generation for all FastAPI routes.
  • Support for the asynchronous client httpx.
  • Automatic test organization by routers.
  • Generation of auxiliary files:
    • conftest.py for fixtures and environment setup.
    • pytest.ini for pytest configuration.
    • test.env file for the test environment.

Installation

Add FATestGenerator to your project:

pip install fa-test-generator
poetry add fa-test-generator

Usage

Initialization

from fastapi import FastAPI
from fa_test_generator import FATestGenerator

# Initialize your FastAPI app
app = FastAPI()

# Initialize the generator and start generating tests
generator = FATestGenerator(app, tests_dir="./tests/")
generator.generate()

Constructor Parameters

  • app (FastAPI): Your FastAPI app.
  • tests_dir (str, optional): The folder to store the tests. Default is ./tests/.

What is Generated?

  1. Test Files: For each router file, a separate test file is created in tests/api/.

    For example, for the router located in user_router.py:

     # app/api/routers/user_router.py
    
     from fa_test_generator import FATestGenerator
     from fastapi import APIRouter, FastAPI, status
     from pydantic import BaseModel
    
     from models.user import User
     from services.user_service import UserService
    
     user_router = APIRouter()
    
    
     @user_router.get(
         path="/users/",
         status_code=status.HTTP_200_OK,
         response_model=list[User],
     )
     async def get_users():
         users = UserService.get_users()
         return users
    
    
     class UserCreateScheme(BaseModel):
         name: str = Field(
             title="Username",
             default="Unknown"
         )
    
    
     @user_router.post(
         path="/users/",
         status_code=status.HTTP_201_CREATED,
         response_model=User,
     )
     async def create_user(
         user_scheme: UserCreateScheme,
     ):
         user = UserService.create_user(user_scheme)
         return user
    
     # app/main.py
    
     from fastapi import FastAPI
    
     app = FastAPI()
    
     app.include_router(user_router)
    
     if __name__ == "__main__":
         FATestGenerator(app, tests_dir="./tests/").generate()
    

    A file tests/api/test_user_router.py is created with the following structure:

    # tests/api/test_user_router.py
    
    from httpx import AsyncClient
    import jsony
    
    class TestUsers:
        async def test_get_users(self, client: AsyncClient):
            resp = await client.get("/users")
            assert resp.status_code == 200
    
         async def test_create_user(self, client: AsyncClient):
             data = {
                 "name": "annotation: str, title: Username, default: Unknown"
             }
            resp = await client.post("/users", json=jsony.normalize(data))
            assert resp.status_code == 2001
    
  2. conftest.py: This file sets up fixtures and checks the test environment.

    # app/tests/conftest.py
    
    import os
    from dotenv import load_dotenv
    import pytest
    from asgi_lifespan import LifespanManager
    from httpx import AsyncClient, ASGITransport
    from main import app
    
    load_dotenv(dotenv_path="./tests/test.env")
    
    @pytest.fixture(scope="session", autouse=True)
    def check_mode():
        mode = os.getenv("MODE")
        if mode != "TEST":
            raise PermissionError(f"Environment variable MODE must be TEST. Current MODE = {mode}")
    
    @pytest.fixture()
    async def client():
        async with LifespanManager(app):
            async with AsyncClient(transport=ASGITransport(app=app), base_url="http://localhost") as ac:
                yield ac
    
  3. pytest.ini: Configuration file for pytest:

     # app/test/pytest.ini
    
    [pytest]
    pythonpath = . .
    env_files = ./tests/test.env
    asyncio_mode = auto
    
  4. test.env: Environment file for tests:

    # app/test/test.env
    
    MODE=TEST
    

How Does Test Generation Work?

  • Test classes are organized by routers. The class names are generated automatically based on the module name.
  • A test method is created for each route with a template to check the response status.
  • If the route requires a request body, it will be automatically generated based on the FastAPI model.

Example of a generated test method:

async def test_create_user(self, client: AsyncClient):
    data = {
        "name": "John Doe",
        "age": 30
    }
    resp = await client.post("/users", json=data)
    assert resp.status_code == 201

License

This project is licensed under the MIT License. For more information, see the LICENSE file.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fa_test_generator-0.1.3.tar.gz (4.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fa_test_generator-0.1.3-py3-none-any.whl (5.2 kB view details)

Uploaded Python 3

File details

Details for the file fa_test_generator-0.1.3.tar.gz.

File metadata

  • Download URL: fa_test_generator-0.1.3.tar.gz
  • Upload date:
  • Size: 4.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.0.1 CPython/3.12.3 Linux/5.15.0-1071-intel-iotg

File hashes

Hashes for fa_test_generator-0.1.3.tar.gz
Algorithm Hash digest
SHA256 9fd64783c57757321ba8d34b7b8c69f8122e80088c651eae909981310b26b8f4
MD5 343253ad3c25170558ef9619ece75202
BLAKE2b-256 cf4f1dec3560b6219966bb479b3fbdf5a775444cbaa6ffd2e6cc8ca432b06ddd

See more details on using hashes here.

File details

Details for the file fa_test_generator-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: fa_test_generator-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 5.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.0.1 CPython/3.12.3 Linux/5.15.0-1071-intel-iotg

File hashes

Hashes for fa_test_generator-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 3876851a74b1cc5bb62bda0e6ec9c85941b31aecfa499efae1d1645d1b3b370e
MD5 74ec2a8454bcaee8a06c1b724e5aebf9
BLAKE2b-256 29ed15ba1152ca2ec1316df93028f3afed75ed82678648ff67ba6422ed942012

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page