Что представляет собой ‘unit’ в юнит-тестировании?

Ответ

В контексте юнит-тестирования (unit testing), 'unit' (модуль) — это наименьшая логически обособленная и изолированная часть программного кода, которую можно протестировать.

Цель юнит-теста — проверить, что этот конкретный 'unit' работает корректно в изоляции от остальной системы. Внешние зависимости (например, обращения к базе данных, файловой системе или API) обычно заменяются заглушками (mocks, stubs).

В роли 'юнита' чаще всего выступают:

  • Функция или метод
  • Класс
  • Иногда — небольшой модуль

Пример:

Допустим, у нас есть функция-юнит для расчета скидки:

# a_unit_of_code.py
def calculate_discount(price, discount_percent):
    if not 0 <= discount_percent <= 100:
        raise ValueError("Скидка должна быть в диапазоне от 0 до 100")
    return price * (discount_percent / 100)

Юнит-тест для этой функции будет проверять её логику с разными входными данными:

# test_unit.py
import pytest
from a_unit_of_code import calculate_discount

def test_calculate_discount_positive():
    """Проверяет корректный расчет скидки."""
    assert calculate_discount(100, 10) == 10.0
    assert calculate_discount(200, 25) == 50.0

def test_calculate_discount_with_invalid_percent():
    """Проверяет вызов исключения при некорректном проценте."""
    with pytest.raises(ValueError):
        calculate_discount(100, 101)

Основные принципы:

  1. Изоляция: Тест не должен зависеть от внешних систем или других юнитов.
  2. Скорость: Юнит-тесты должны выполняться очень быстро, так как их запускают часто.
  3. Автоматизация: Запуск и проверка результатов должны быть полностью автоматическими.

Такой подход позволяет быстро находить и исправлять ошибки на ранних стадиях разработки.

Ответ 18+ 🔞

А, ну это ж про юнит-тесты, блядь! Слушай, сейчас разжую, как для полного чайника, только с перчинкой.

Вот смотри, представь себе, что ты пишешь прогу. И там у тебя куча функций, методов, классов — всякой хуйни. Так вот, 'unit' — это как раз та самая мельчайшая, блядь, логическая частица, которую можно выдрать из всего этого бардака и протестировать отдельно, в стерильных условиях, ёпта!

Смысл в чём? Чтобы проверить, что этот конкретный кусок кода работает ровно так, как ты задумал, и не ссыт в сторону. А все его дружки-приятели — типа база данных, файловая система или какой-нибудь внешний сервис — нахуй не нужны. Их заменяют муляжами, заглушками, чтобы они не мешали и не косячили.

Что обычно выступает в роли этого самого 'юнита', этой святой единицы тестирования?

  • Функция или метод — чаще всего, блядь.
  • Класс — тоже пойдёт.
  • Ну или маленький, блядь, самостоятельный модульчик.

Вот тебе живой пример, чтобы не быть голословным:

Допустим, есть у нас функция, которая считает скидку. Проще некуда, но и тут можно накосячить, если не проверить.

# a_unit_of_code.py
def calculate_discount(price, discount_percent):
    if not 0 <= discount_percent <= 100:
        raise ValueError("Скидка должна быть в диапазоне от 0 до 100")
    return price * (discount_percent / 100)

И вот для этой, с позволения сказать, единицы, мы пишем отдельный тест. Словно сажаем её в аквариум и смотрим, как она там плавает.

# test_unit.py
import pytest
from a_unit_of_code import calculate_discount

def test_calculate_discount_positive():
    """Проверяет корректный расчет скидки."""
    assert calculate_discount(100, 10) == 10.0
    assert calculate_discount(200, 25) == 50.0

def test_calculate_discount_with_invalid_percent():
    """Проверяет вызов исключения при некорректном проценте."""
    with pytest.raises(ValueError):
        calculate_discount(100, 101)

Видишь? Мы её тыкаем палочкой с разными данными: и нормальными, и заведомо кривыми. Смотрим, не сломается ли. Если сломается там, где не должна — сразу ясно, где искать косяк. Удобно же, ёпта!

А теперь три кита, на которых всё это держится, блядь:

  1. Изоляция, ёб твою мать! Тест должен проверять только свой кусок. Никаких посторонних связей, иначе это уже не юнит-тест, а какая-то ебучка интеграционная.
  2. Скорость — пиздец какая! Эти тесты должны бегать как угорелые, потому что их запускают постоянно. Если тест выполняется дольше, чем я успеваю сходить за кофе — это уже плохой тест.
  3. Полный автомат, блядь! Нажал кнопку — получил результат. Никакого ручного вмешательства, никаких "ой, а тут база лежала". Всё само.

Вот такой подход и позволяет ловить баги на самом раннем этапе, пока они ещё мелкие и несмелые. Потому что если запустить эту хуйню в продакшн без проверки, потом охуеешь искать, что сломалось и где.