Тест бичих (pytest)
Код бичих нь зөвхөн ажиллуулж харахад хангалтгүй — шинэ өөрчлөлт хийхэд өмнөх зүйл эвдрэхгүй гэдгийг хэрхэн баталгаажуулах вэ? Автомат тест нь үүний хариулт. pytest нь Python-д хамгийн алдартай тест framework бөгөөд суралцахад хялбар, хүчирхэг.
pytest суулгах ба анхны тест
pip install pytest
Тест файлын нэр test_ угтвараар эхэлнэ, тест функц ч мөн адил:
# test_тооцоолол.py
def нэмэх(а, б):
return а + б
def хасах(а, б):
return а - б
def test_нэмэх_эерэг():
assert нэмэх(3, 5) == 8
def test_нэмэх_сөрөг():
assert нэмэх(-2, -3) == -5
def test_хасах():
assert хасах(10, 4) == 6
def test_нэмэх_тэг():
assert нэмэх(0, 0) == 0
# Бүх тест ажиллуулах
pytest
# Дэлгэрэнгүй гаралттай
pytest -v
assert нь нөхцөлийг шалгана — худал бол тест унана, pytest алдааг тайлбарлана. Ажиллуулахад иймэрхүү харагдана:
test_тооцоолол.py .... [100%]
4 passed in 0.02s
Алдаа гарахыг тест хийх
Зарим тохиолдолд функц алдаа өгөх ёстой — үүнийг ч тест хийж болно:
# test_хуваах.py
import pytest
def хуваах(а, б):
if б == 0:
raise ValueError("Тэгд хуваах боломжгүй")
return а / б
def test_хуваах_энгийн():
assert хуваах(10, 2) == 5.0
def test_хуваах_тэгд():
with pytest.raises(ValueError, match="Тэгд хуваах боломжгүй"):
хуваах(10, 0)
def test_хуваах_бутархай():
assert хуваах(7, 2) == pytest.approx(3.5)
pytest.raises() нь тухайн алдаа гарахыг баталгааждаг. pytest.approx() нь бутархай тоог ойролцоогоор шалгана — 0.1 + 0.2 == 0.3 Python-д False байдаг тул энэ чухал.
FastAPI endpoint тест хийх
httpx пакеж ашиглан FastAPI endpoint-ийг бодит server ажиллуулалгүй шууд тест хийнэ:
pip install httpx
# test_api.py
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_эхлэл_хуудас():
хариу = client.get("/")
assert хариу.status_code == 200
assert "мэндчилгээ" in хариу.json()
def test_сурагч_үүсгэх():
хариу = client.post("/сурагч", json={
"нэр": "Болд",
"и_мэйл": "bold@example.mn"
})
assert хариу.status_code == 201
өгөгдөл = хариу.json()
assert өгөгдөл["нэр"] == "Болд"
assert "id" in өгөгдөл
def test_байхгүй_сурагч():
хариу = client.get("/сурагч/99999")
assert хариу.status_code == 404
TestClient нь бодит HTTP хүсэлт илгээдэггүй — санах ойд шууд ажилладаг тул маш хурдан.
fixture — ашиглагдах өгөгдөл бэлтгэх
Олон тестэд нэг ижил өгөгдөл хэрэгтэй үед @pytest.fixture ашиглана:
import pytest
from fastapi.testclient import TestClient
from main import app
@pytest.fixture
def client():
return TestClient(app)
@pytest.fixture
def бүртгэлтэй_сурагч(client):
хариу = client.post("/сурагч", json={
"нэр": "Тест сурагч",
"и_мэйл": "test@example.mn"
})
return хариу.json()
def test_сурагч_авах(client, бүртгэлтэй_сурагч):
id = бүртгэлтэй_сурагч["id"]
хариу = client.get(f"/сурагч/{id}")
assert хариу.status_code == 200
assert хариу.json()["нэр"] == "Тест сурагч"
def test_xp_нэмэх(client, бүртгэлтэй_сурагч):
id = бүртгэлтэй_сурагч["id"]
хариу = client.patch(f"/сурагч/{id}/xp")
assert хариу.status_code == 200
Fixture нь тест бүрт дахин ажиллана — тестүүд бие биеэс хамаарахгүй, тусдаа байна. Тест бичих дадал эхэндээ хэцүү санагдаж болох боловч кодын чанарыг эрс сайжруулдаг — мэргэжлийн хөгжүүлэгч бүр ашигладаг арга.
Дараагийн хичээлд:
Async Python үндэс — async/await хэрхэн ажилладаг, яагаад FastAPI async-д суурилдаг, олон ажлыг зэрэгцүүлэн гүйцэтгэх аргыг сурна.