2-bo‘lim
Muhitni sozlash va birinchi test
Virtual muhit yaratish, pytest o'rnatish, birinchi testni yozish va ishga tushirish, pytest chiqishini qatorma-qator o'qish.
Ushbu bo‘lim mundarijasi
Bu bo'limda bitta test yozamiz va uni ishga tushiramiz. Keyin uni ataylab buzamiz - chunki testning eng foydali chiqishi u yiqilgan paytdagi chiqishi.
Kerakli narsalar #
Sizda Python 3.9 yoki undan yangisi bo'lsa yetarli. Tekshirib olamiz:
python3 --version
Python 3.13.12
Windows da odatda python3 emas, python yoziladi:
python --version
Keyingi buyruqlarda ham shunday: python3 o'rniga python, .venv/bin
o'rniga .venv\Scripts. Qolgan hammasi bir xil.
Loyiha papkasi va virtual muhit #
Yangi papka yaratib, uning ichida virtual muhit ochamiz. Virtual muhit - shu loyiha uchun alohida ajratilgan Python: unga o'rnatilgan kutubxonalar kompyuterdagi boshqa loyihalarga tegmaydi.
mkdir loyiha
cd loyiha
python3 -m venv .venv
Endi uni faollashtiramiz:
source .venv/bin/activate
Buyruq qatorining boshida (.venv) yozuvi paydo bo'ladi - demak muhit
faol. Windows da faollashtirish buyrug'i: .venv\Scripts\activate.
pytest ni o'rnatish #
pip install pytest
Collecting pytest
Downloading pytest-9.1.1-py3-none-any.whl.metadata (7.6 kB)
Collecting iniconfig>=1.0.1 (from pytest)
Downloading iniconfig-2.3.0-py3-none-any.whl.metadata (2.5 kB)
Collecting packaging>=22 (from pytest)
Downloading packaging-26.3-py3-none-any.whl.metadata (3.5 kB)
Collecting pluggy<2,>=1.5 (from pytest)
Downloading pluggy-1.6.0-py3-none-any.whl.metadata (4.8 kB)
Collecting pygments>=2.7.2 (from pytest)
Downloading pygments-2.21.0-py3-none-any.whl.metadata (2.5 kB)
Downloading pytest-9.1.1-py3-none-any.whl (386 kB)
Downloading pluggy-1.6.0-py3-none-any.whl (20 kB)
Downloading iniconfig-2.3.0-py3-none-any.whl (7.5 kB)
Downloading packaging-26.3-py3-none-any.whl (129 kB)
Downloading pygments-2.21.0-py3-none-any.whl (1.3 MB)
Installing collected packages: pygments, pluggy, packaging, iniconfig, pytest
Successfully installed iniconfig-2.3.0 packaging-26.3 pluggy-1.6.0 pygments-2.21.0 pytest-9.1.1
Beshta paket o'rnatildi: pytest va uning to'rtta yordamchisi. Versiyani
tekshiramiz:
pytest --version
pytest 9.1.1
Tekshiriladigan kod #
Talabalarning o'rtacha bahosini hisoblaydigan kichkina funksiya yozamiz:
def ortacha(baholar):
return sum(baholar) / len(baholar)
Birinchi test #
Test ham oddiy Python fayli. Uni test_ bilan boshlanadigan nom bilan
saqlash kerak - pytest fayllarni shu belgi bo'yicha topadi:
from hisob import ortacha
def test_uchta_baho():
assert ortacha([70, 80, 90]) == 80
def test_bitta_baho():
assert ortacha([65]) == 65
Bu yerda uchta qoida bor va ularning hammasi nomlar bilan bog'liq:
| Nima | Qoida | Misol |
|---|---|---|
| Fayl nomi | test_ bilan boshlanadi yoki _test.py bilan tugaydi | test_hisob.py |
| Funksiya nomi | test_ bilan boshlanadi | def test_uchta_baho() |
| Sinf nomi | Test bilan boshlanadi | class TestHisob: |
Qolgan hamma narsa - oddiy Python. assert - tilning o'z kalit so'zi,
pytest uni o'zgartirmaydi.
Ishga tushirish #
pytest
========================= test session starts ==========================
platform linux -- Python 3.13.12, pytest-9.1.1, pluggy-1.6.0
rootdir: /home/dasturchi/loyiha
collected 2 items
test_hisob.py .. [100%]
========================== 2 passed in 0.01s ===========================
Chiqishni qismlarga ajratib o'qiymiz:
Diqqat: biz pytest ga hech qanday fayl nomini bermadik. U o'zi qidirdi:
joriy papkadan boshlab test_*.py fayllarini topdi, ularning ichidan
test_ bilan boshlanadigan funksiyalarni yig'di va hammasini ishga tushirdi.
Test yiqilganda #
Endi eng muhim qismga o'tamiz. Kodga xato kiritamiz - o'rtachani hisoblash o'rniga faqat yig'indini qaytaramiz:
def ortacha(baholar):
return sum(baholar)
pytest
========================= test session starts ==========================
platform linux -- Python 3.13.12, pytest-9.1.1, pluggy-1.6.0
rootdir: /home/dasturchi/loyiha
collected 2 items
test_hisob.py F. [100%]
=============================== FAILURES ===============================
___________________________ test_uchta_baho ____________________________
def test_uchta_baho():
> assert ortacha([70, 80, 90]) == 80
E assert 240 == 80
E + where 240 = ortacha([70, 80, 90])
test_hisob.py:5: AssertionError
======================= short test summary info ========================
FAILED test_hisob.py::test_uchta_baho - assert 240 == 80
===================== 1 failed, 1 passed in 0.01s ======================
Endi . o'rniga F harfi chiqdi - failed. Lekin eng muhimi hisobotning
o'rtasida:
>belgisi - yiqilgan aynan shu qator;Ebilan boshlangan qatorlar - xato haqidagi tushuntirish.
Shu ikki qatorga diqqat qiling:
| Qator | Nimani aytadi |
|---|---|
assert 240 == 80 | Solishtirish natijasi: chap tomon 240, o'ng tomon 80 |
where 240 = ortacha([70, 80, 90]) | 240 qayerdan kelgani - qaysi chaqiruvdan |
Ya'ni pytest assert ichidagi ifodani qismlarga ajratdi va har birining
haqiqiy qiymatini ko'rsatdi. Kodni ochib qarash shart emas - xato
hisobotining o'zi yetarli.
Eng pastdagi short test summary info bo'limi ayniqsa foydali: yuzlab
test ichidan yiqilganlari bitta ro'yxatda jamlanadi.
Odatiy Python da assert x == y yiqilsa, siz faqat AssertionError
degan quruq xabarni olasiz - qiymatlar ko'rinmaydi.
pytest test fayllarini yuklashdan oldin ularni qayta yozadi
(assertion rewriting) va har bir assert ga qiymatlarni chop etadigan
kod qo'shadi. Shuning uchun assertEquals, assertTrue kabi o'nlab
maxsus metodlarni o'rganish shart emas - oddiy assert yetadi.
Bu boshqa vositalardan asosiy farqi. JUnit da assertEquals(80, natija)
yozish kerak; pytest da assert natija == 80 yetarli.
Kodni tuzatamiz:
def ortacha(baholar):
return sum(baholar) / len(baholar)
pytest -q
.. [100%]
2 passed in 0.12s
-q (quiet) - qisqartirilgan chiqish. Sarlavha va versiyalar
ko'rsatilmaydi. Kundalik ishda ko'pincha shu ishlatiladi.
Eng kerakli bayroqlar #
| Bayroq | Nima qiladi |
|---|---|
-q | Qisqa chiqish |
-v | Har testning nomini alohida qator qilib ko'rsatadi |
-x | Birinchi yiqilishda to'xtaydi |
-k "nom" | Faqat nomida nom bo'lgan testlarni ishga tushiradi |
--tb=short | Xato izini qisqartiradi |
--tb=no | Xato izini umuman ko'rsatmaydi |
test_hisob.py::test_bitta_baho | Faqat bitta testni ishga tushiradi |
-v ni ko'rib chiqamiz - u katta loyihada qaysi test nima qilayotganini
ko'rsatadi:
pytest -v
========================= test session starts ==========================
platform linux -- Python 3.13.12, pytest-9.1.1, pluggy-1.6.0 -- /home/dasturchi/loyiha/.venv/bin/python3
cachedir: .pytest_cache
rootdir: /home/dasturchi/loyiha
collecting ... collected 2 items
test_hisob.py::test_uchta_baho PASSED [ 50%]
test_hisob.py::test_bitta_baho PASSED [100%]
========================== 2 passed in 0.01s ===========================
Nomlar shu yerda ko'rinadi - shuning uchun test nomlari gap bo'lishi kerak. Bu haqda 5-bo'limda batafsil gaplashamiz.
Bitta testni nomi bo'yicha tanlash:
pytest -k "bitta" -v
========================= test session starts ==========================
platform linux -- Python 3.13.12, pytest-9.1.1, pluggy-1.6.0 -- /home/dasturchi/loyiha/.venv/bin/python3
cachedir: .pytest_cache
rootdir: /home/dasturchi/loyiha
collecting ... collected 2 items / 1 deselected / 1 selected
test_hisob.py::test_bitta_baho PASSED [100%]
=================== 1 passed, 1 deselected in 0.00s ====================
Qolgan testlar "deselected" - tanlanmagan - deb belgilandi.
pip install pytest ni virtual muhitsiz ishlatmangVirtual muhitsiz o'rnatilgan paketlar butun tizimga tushadi. Bir loyiha pytest 7 ni, ikkinchisi pytest 9 ni talab qilsa - ular to'qnashadi.
Ba'zi tizimlarda (Debian, Ubuntu, Kali) Python buni oldindan taqiqlaydi
va externally-managed-environment xatosini beradi. Bu - xato emas,
himoya: virtual muhit yarating va davom eting.
- Yangi papka oching, virtual muhit yarating va pytest o'rnating.
hisob.pyvatest_hisob.pyfayllarini yozib,pytestni ishga tushiring.- Chiqishdagi har bir qatorni yuqoridagi rasm bilan solishtirib chiqing.
- Testga uchinchi holat qo'shing: to'rtta bahoning o'rtachasi.
- Funksiyani ataylab buzing (masalan
/ 2qo'shing) va xato hisobotini o'qing. assertqatorida qaysi qiymat ko'rsatilganini toping va uni tushuntiring.pytest -vni ishga tushirib, chiqishning qanday o'zgarganini yozing.pytest -kbilan faqat bitta testni ishga tushiring.- Test funksiyasining nomini
test_siz yozib ko'ring - pytest uni topadimi? - Fayl nomini
hisob_test.pyga o'zgartirib ko'ring - pytest uni topadimi?
Xulosa #
- Virtual muhit (
python3 -m venv .venv) - loyihaga alohida ajratilgan Python; kutubxonalar boshqa loyihalarga tegmaydi. pip install pytestbeshta paket o'rnatadi: pytest va uning to'rtta yordamchisi.- Test - oddiy Python fayli; sirli tuzilish yoki sinf talab qilinmaydi.
- pytest testlarni nom bo'yicha topadi:
test_*.pyfayllar,test_bilan boshlanadigan funksiyalar,Testbilan boshlanadigan sinflar. pytestbuyrug'iga hech narsa berilmasa, u joriy papkadan boshlab o'zi qidiradi.- Chiqishdagi har bir nuqta - o'tgan test, F harfi - yiqilgan test.
- Yiqilgan testda pytest
assertichidagi ifodani qismlarga ajratib, haqiqiy qiymatlarni ko'rsatadi. - Bu xususiyat assertion rewriting deb ataladi - shuning uchun
assertEqualskabi maxsus metodlar kerak emas. - Eng kerakli bayroqlar:
-qqisqa,-vbatafsil,-xbirinchi xatoda to'xtash,-knom bo'yicha tanlash. - Bitta testni
fayl.py::test_nomiko'rinishida to'g'ridan-to'g'ri chaqirish mumkin. - Yakuniy qatordagi vaqt har ishga tushirishda biroz farq qiladi - bu normal.
- Virtual muhitsiz o'rnatish tizimdagi boshqa loyihalar bilan to'qnashuvga olib keladi.
Keyingi bo'limda assert ning o'zini chuqurroq ko'ramiz: sonlar, obyektlar,
istisnolar va xato xabarini qanday foydali qilish.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.