Tutorial Material

Unit testing

Share to
Python unit testing

Unit testing — bu dastur kodining alohida qismlarini (funksiya, metod yoki class) test qilish usuli. Maqsad: ularning to'g'ri ishlayotganini tekshirish.

"Lekin hozir kodim ishlayapti-ku!" Bugun ishlashi mumkin, lekin 6 oy o'tib bitta qatorni o'zgartirasiz va boshqa funksiyalar buzilib ketadi. Unit test'lar — sizning "xavfsizlik to'ri"ngiz.

Python'da ikkita asosiy test freymvorki (framework) bor: unittest (o'rnatilgan/built-in) va pytest (uchinchi tomon/third-party, lekin juda ommabop).

1. unittest (o'rnatilgan/built-in) bilan

unittest JUnit (Java) dan ilhomlangan. U sinfga asoslangan (class-based) yondashuvdan foydalanadi.

Masalan, quyidagi oddiy funksiyalar bo'lsin:

# calc.py fayli
def add(x, y):
    return x + y

def divide(x, y):
    if y == 0:
        raise ValueError("Cannot divide by zero")
    return x / y

Test faylni yaratamiz:

# non-runnable: requires external environment/setup
# test_calc.py fayli
import unittest
from calc import add, divide

class TestCalc(unittest.TestCase):

    def test_add(self):
        self.assertEqual(add(3, 4), 7)
        self.assertEqual(add(-1, 1), 0)

    def test_divide(self):
        self.assertEqual(divide(10, 2), 5)

        # Exception tekshirish
        with self.assertRaises(ValueError):
            divide(10, 0)

if __name__ == '__main__':
    unittest.main()

Ishga tushirish: python test_calc.py

2. pytest (zamonaviy tavsiya)

pytest ixchamroq, kuchliroq va ko'proq "Pythonic". U class'lar o'rniga oddiy funksiyalar va standart assert dan foydalanadi.

O'rnatish:

python -m pip install pytest

Pytest bilan test yozish:

# non-runnable: requires external environment/setup
# test_calc_pytest.py fayli
import pytest
from calc import add, divide

def test_add():
    assert add(3, 4) == 7
    assert add(-1, 1) == 0

def test_divide():
    assert divide(10, 2) == 5

def test_divide_zero():
    with pytest.raises(ValueError):
        divide(10, 0)

Terminal'da pytest deb yozing. Pytest test_ bilan boshlanadigan fayllarni avtomatik topadi.

3. Mocking tushunchasi

Mocking - test qilinayotgan tizimning ayrim qismlarini mock obyektlar bilan almashtirish texnikasi. Bu kod API, database yoki file system kabi tashqi tizimlarga bog'liq bo'lganda foydali.

Misol: biz API so'rov yuboradigan funksiyani test qilmoqchimiz, lekin haqiqiy so'rov yubormoqchi emasmiz (sekin va internet talab qiladi).

unittest.mock bilan:

# non-runnable: requires requests
from unittest.mock import Mock, patch
import requests

# Test qilinadigan funksiya
def get_user_data(url):
    resp = requests.get(url)
    if resp.status_code == 200:
        return resp.json()
    return None

# Mock bilan test
@patch('requests.get')
def test_get_user_data(mock_get):
    # Mock'ni sozlash
    mock_response = Mock()
    mock_response.status_code = 200
    mock_response.json.return_value = {"id": 1, "name": "Bob"}

    # Mock javobni mock_get'ga berish
    mock_get.return_value = mock_response

    # Funksiyani ishga tushirish
    result = get_user_data("http://fakeurl.com")

    # Tekshirish
    assert result["name"] == "Bob"
    # requests.get to'g'ri URL bilan chaqirilganini tekshirish
    mock_get.assert_called_with("http://fakeurl.com")

4. Kod qamrovi (code coverage)

Kodingizning qanchasi test bilan qamrab olingan? Qamrov (coverage) vositalari qaysi qatorlar testdan o'tmaganini ko'rsatadi.

O'rnatish:

python -m pip install pytest-cov

Ishga tushirish:

pytest --cov=my_project

Xulosa