Skip to content

๐Ÿ” ๐Ÿ’ฏ

๐Ÿ‘† โœ”๏ธ โช ๐Ÿ‘€ โ” ๐Ÿ’ฏ ๐Ÿ‘† FastAPI ๐Ÿˆธ โš™๏ธ ๐Ÿšš TestClient. ๐Ÿ†™ ๐Ÿ”œ, ๐Ÿ‘† โœ”๏ธ ๐Ÿ•ด ๐Ÿ‘€ โ” โœ ๐Ÿ” ๐Ÿ’ฏ, ๐Ÿต โš™๏ธ async ๐Ÿ”ข.

โž– ๐Ÿ’ช โš™๏ธ ๐Ÿ” ๐Ÿ”ข ๐Ÿ‘† ๐Ÿ’ฏ ๐Ÿ’ช โš , ๐Ÿ–ผ, ๐Ÿ•โ” ๐Ÿ‘† ๐Ÿ”ฌ ๐Ÿ‘† ๐Ÿ’ฝ ๐Ÿ”. ๐ŸŒˆ ๐Ÿ‘† ๐Ÿ’š ๐Ÿ’ฏ ๐Ÿ“จ ๐Ÿ“จ ๐Ÿ‘† FastAPI ๐Ÿˆธ & โคด๏ธ โœ” ๐Ÿ‘ˆ ๐Ÿ‘† ๐Ÿ‘ฉโ€๐Ÿ’ป โช โœ โ˜‘ ๐Ÿ’ฝ ๐Ÿ’ฝ, โช โš™๏ธ ๐Ÿ” ๐Ÿ’ฝ ๐Ÿ—ƒ.

โžก๏ธ ๐Ÿ‘€ โ” ๐Ÿ‘ฅ ๐Ÿ’ช โš’ ๐Ÿ‘ˆ ๐Ÿ‘ท.

pytest.mark.anyio

๐Ÿšฅ ๐Ÿ‘ฅ ๐Ÿ’š ๐Ÿค™ ๐Ÿ” ๐Ÿ”ข ๐Ÿ‘† ๐Ÿ’ฏ, ๐Ÿ‘† ๐Ÿ’ฏ ๐Ÿ”ข โœ”๏ธ ๐Ÿ”. AnyIO ๐Ÿšš ๐Ÿ‘Œ ๐Ÿ“ ๐Ÿ‘‰, ๐Ÿ‘ˆ โœ” ๐Ÿ‘ฅ โœ” ๐Ÿ‘ˆ ๐Ÿ’ฏ ๐Ÿ”ข ๐Ÿค™ ๐Ÿ”.

๐Ÿ‡ธ๐Ÿ‡ฒ

๐Ÿšฅ ๐Ÿ‘† FastAPI ๐Ÿˆธ โš™๏ธ ๐Ÿ˜ def ๐Ÿ”ข โ†ฉ๏ธ async def, โšซ๏ธ async ๐Ÿˆธ ๐Ÿ”˜.

TestClient ๐Ÿ”จ ๐ŸŽฑ ๐Ÿ”˜ ๐Ÿค™ ๐Ÿ” FastAPI ๐Ÿˆธ ๐Ÿ‘† ๐Ÿ˜ def ๐Ÿ’ฏ ๐Ÿ”ข, โš™๏ธ ๐Ÿฉ โœณ. โœ‹๏ธ ๐Ÿ‘ˆ ๐ŸŽฑ ๐Ÿšซ ๐Ÿ‘ท ๐Ÿšซ๐Ÿ”œ ๐Ÿ•โ” ๐Ÿ‘ฅ โš™๏ธ โšซ๏ธ ๐Ÿ”˜ ๐Ÿ” ๐Ÿ”ข. ๐Ÿƒ ๐Ÿ‘† ๐Ÿ’ฏ ๐Ÿ”, ๐Ÿ‘ฅ ๐Ÿ’ช ๐Ÿ™…โ€โ™‚ ๐Ÿ“ โš™๏ธ TestClient ๐Ÿ”˜ ๐Ÿ‘† ๐Ÿ’ฏ ๐Ÿ”ข.

TestClient โš“๏ธ ๐Ÿ”› ๐Ÿ‡ธ๐Ÿ‡ฒ, & โ†ฉ๏ธ, ๐Ÿ‘ฅ ๐Ÿ’ช โš™๏ธ โšซ๏ธ ๐Ÿ”— ๐Ÿ’ฏ ๐Ÿ› ๏ธ.

๐Ÿ–ผ

๐Ÿ™… ๐Ÿ–ผ, โžก๏ธ ๐Ÿค” ๐Ÿ“ ๐Ÿ“Š ๐ŸŽ 1๏ธโƒฃ ๐Ÿ”ฌ ๐Ÿฆ ๐Ÿˆธ & ๐Ÿ”ฌ:

.
โ”œโ”€โ”€ app
โ”‚ย ย  โ”œโ”€โ”€ __init__.py
โ”‚ย ย  โ”œโ”€โ”€ main.py
โ”‚ย ย  โ””โ”€โ”€ test_main.py

๐Ÿ“ main.py ๐Ÿ”œ โœ”๏ธ:

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def root():
    return {"message": "Tomato"}

๐Ÿ“ test_main.py ๐Ÿ”œ โœ”๏ธ ๐Ÿ’ฏ main.py, โšซ๏ธ ๐Ÿ’ช ๐Ÿ‘€ ๐Ÿ’– ๐Ÿ‘‰ ๐Ÿ”œ:

import pytest
from httpx import AsyncClient

from .main import app


@pytest.mark.anyio
async def test_root():
    async with AsyncClient(app=app, base_url="http://test") as ac:
        response = await ac.get("/")
    assert response.status_code == 200
    assert response.json() == {"message": "Tomato"}

๐Ÿƒ โšซ๏ธ

๐Ÿ‘† ๐Ÿ’ช ๐Ÿƒ ๐Ÿ‘† ๐Ÿ’ฏ ๐ŸŒ ๐Ÿ“จ:

$ pytest

---> 100%

โ„น

๐Ÿ“‘ @pytest.mark.anyio ๐Ÿ’ฌ โœณ ๐Ÿ‘ˆ ๐Ÿ‘‰ ๐Ÿ’ฏ ๐Ÿ”ข ๐Ÿ”œ ๐Ÿค™ ๐Ÿ”:

import pytest
from httpx import AsyncClient

from .main import app


@pytest.mark.anyio
async def test_root():
    async with AsyncClient(app=app, base_url="http://test") as ac:
        response = await ac.get("/")
    assert response.status_code == 200
    assert response.json() == {"message": "Tomato"}

Tip

๐Ÿ—’ ๐Ÿ‘ˆ ๐Ÿ’ฏ ๐Ÿ”ข ๐Ÿ”œ async def โ†ฉ๏ธ def โญ ๐Ÿ•โ” โš™๏ธ TestClient.

โคด๏ธ ๐Ÿ‘ฅ ๐Ÿ’ช โœ AsyncClient โฎ๏ธ ๐Ÿ“ฑ, & ๐Ÿ“จ ๐Ÿ” ๐Ÿ“จ โšซ๏ธ, โš™๏ธ await.

import pytest
from httpx import AsyncClient

from .main import app


@pytest.mark.anyio
async def test_root():
    async with AsyncClient(app=app, base_url="http://test") as ac:
        response = await ac.get("/")
    assert response.status_code == 200
    assert response.json() == {"message": "Tomato"}

๐Ÿ‘‰ ๐ŸŒ“:

response = client.get('/')

...๐Ÿ‘ˆ ๐Ÿ‘ฅ โš™๏ธ โš’ ๐Ÿ‘† ๐Ÿ“จ โฎ๏ธ TestClient.

Tip

๐Ÿ—’ ๐Ÿ‘ˆ ๐Ÿ‘ฅ โš™๏ธ ๐Ÿ”/โŒ› โฎ๏ธ ๐Ÿ†• AsyncClient - ๐Ÿ“จ ๐Ÿ”.

๐ŸŽ ๐Ÿ” ๐Ÿ”ข ๐Ÿค™

๐Ÿ”ฌ ๐Ÿ”ข ๐Ÿ”œ ๐Ÿ”, ๐Ÿ‘† ๐Ÿ’ช ๐Ÿ”œ ๐Ÿค™ (& await) ๐ŸŽ async ๐Ÿ”ข โ†–๏ธ โšช๏ธโžก๏ธ ๐Ÿ“จ ๐Ÿ“จ ๐Ÿ‘† FastAPI ๐Ÿˆธ ๐Ÿ‘† ๐Ÿ’ฏ, โšซ๏ธโ” ๐Ÿ‘† ๐Ÿ”œ ๐Ÿค™ ๐Ÿ‘ซ ๐Ÿ™† ๐Ÿ™† ๐Ÿ‘† ๐Ÿ“Ÿ.

Tip

๐Ÿšฅ ๐Ÿ‘† โš” RuntimeError: Task attached to a different loop ๐Ÿ•โ” ๐Ÿ› ๏ธ ๐Ÿ” ๐Ÿ”ข ๐Ÿค™ ๐Ÿ‘† ๐Ÿ’ฏ (โœ… ๐Ÿ•โ” โš™๏ธ โœณ MotorClient) ๐Ÿ’ญ ๐Ÿ”— ๐ŸŽš ๐Ÿ‘ˆ ๐Ÿ’ช ๐ŸŽ‰ โžฐ ๐Ÿ•ด ๐Ÿž ๐Ÿ” ๐Ÿ”ข, โœ… '@app.on_event("startup") โฒ.