Calmcode - fastapi: testing two

Adding more elaborate unit tests to FastAPI.

1 2 3 4 5 6 7 8 9

Let's also add some tests that check if the pydantic data types are handled correctly. Again, before running pytest you want to confirm it is installed.

pip install pytest

The files we use in this video are displayed below.

app.py

import time
import asyncio

from pydantic import BaseModel, validator
from fastapi import FastAPI

app = FastAPI()


class Item(BaseModel):
    name: str
    price: float

    @validator("price")
    def price_must_be_positive(cls, value):
        if value <= 0:
            raise ValueError(f"we expect price >= 0, we received {value}")
        return value


@app.get("/")
def root():
    return {"message": "hello world again"}


@app.get("/users/{user_id}")
def read_user(user_id: str):
    return {"user_id": user_id}


@app.post("/items/")
def create_item(item: Item):
    return item


@app.get("/sleep_slow")
def sleep_slow():
    r = time.sleep(1)
    return {"status": "done"}


@app.get("/sleep_fast")
async def sleep_fast():
    r = await asyncio.sleep(1)
    return {"status": "done"}

tests.py

from starlette.testclient import TestClient

from app import app

client = TestClient(app)

def test_root_endpoint():
    resp = client.get("/")
    assert resp.status_code == 200
    assert resp.json() == {"message": "hello world again"}

def test_users_endpoint():
    resp = client.get("/users/1")
    assert resp.status_code == 200
    assert resp.json() == {"user_id": "1"}

def test_correct_item():
    json_blob = {"name": "shampoo", "price": 1.5}
    resp = client.post("/items/", json=json_blob)
    assert resp.status_code == 200

def test_wrong_item():
    json_blob = {"name": "shampoo", "price": -1.5}
    resp = client.post("/items/", json=json_blob)
    assert resp.status_code != 200