← Назад к вопросам

Как вычисляется Coverage?

2.0 Middle🔥 151 комментариев
#Python Core#Тестирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как вычисляется Coverage?

Code Coverage (покрытие кода) — это метрика, показывающая, какая часть исходного кода была выполнена при запуске тестов. Это критичный показатель качества тестирования.

Основная формула

Coverage (%) = (Количество выполненных строк / Общее количество строк) × 100%

Например, если из 100 строк кода выполнено 85 строк при запуске тестов, то coverage = 85%.

Типы Coverage

1. Line Coverage (Покрытие строк)

Самый распространённый тип — отслеживает, какие строки кода были выполнены:

def calculate_discount(amount, is_vip):
    if amount < 100:  # Строка 2 — проверяется
        discount = 0  # Строка 3 — выполняется если amount < 100
    else:
        discount = 0.1  # Строка 5 — выполняется если amount >= 100
    
    if is_vip:  # Строка 7 — проверяется
        discount += 0.05  # Строка 8 — выполняется если is_vip=True
    
    return amount * (1 - discount)  # Строка 10 — всегда выполняется

Если тесты проверяют только calculate_discount(150, False), то:

  • Выполнены строки: 2, 5, 7, 10 = 4 строки
  • Общее количество: 10 строк
  • Coverage = 40%

2. Branch Coverage (Покрытие ветвей)

Проверяет, выполнены ли все ветви условных операторов:

def authenticate(username, password):
    if not username:  # Ветвь 1: если username пусто
        return False  # Ветвь не покрыта?
    
    if not password:  # Ветвь 2: если password пусто
        return False  # Ветвь не покрыта?
    
    if verify_credentials(username, password):  # Ветвь 3
        return True  # Ветвь не покрыта?
    else:
        return False  # Ветвь не покрыта?

Для 100% Branch Coverage нужны тесты со всеми комбинациями:

  • authenticate("", "pass") — ветвь 1
  • authenticate("user", "") — ветвь 2
  • authenticate("user", "correct_pass") — ветвь 3 (True)
  • authenticate("user", "wrong_pass") — ветвь 3 (False)

3. Function Coverage (Покрытие функций)

Проверяет, была ли вызвана каждая функция:

def get_user(user_id):
    return {"id": user_id}

def delete_user(user_id):
    pass  # Если эта функция никогда не вызывается в тестах

# Если есть тест только для get_user(), то Function Coverage = 50%

Как измерить Coverage в Python

Использование pytest-cov

# Установка
pip install pytest-cov

# Запуск с отчётом о покрытии
pytest --cov=src --cov-report=html

# Вывод в консоль
pytest --cov=src --cov-report=term-missing

Пример вывода

Name                    Stmts   Miss  Cover   Missing
─────────────────────────────────────────────────────
src/utils.py               20      3    85%    15-17, 25
src/models.py              45      5    89%    10, 22-24, 40
─────────────────────────────────────────────────────
TOTAL                      65      8    88%

Практический пример

# calculate.py
def add(a, b):
    return a + b

def multiply(a, b):
    return a * b

def divide(a, b):
    if b == 0:
        raise ValueError("Division by zero")
    return a / b

# test_calculate.py
import pytest
from calculate import add, multiply, divide

def test_add():
    assert add(2, 3) == 5

def test_multiply():
    assert multiply(2, 3) == 6

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

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

Запуск:

pytest --cov=. --cov-report=term-missing

Результат:

  • Line Coverage = 100% (все строки выполнены)
  • Branch Coverage = 100% (обе ветви divide проверены)
  • Function Coverage = 100% (все функции вызваны)

Целевой Coverage

  • 80%+ — хороший результат для production-кода
  • 90%+ — высокий стандарт (как в этом проекте)
  • 100% — идеально, но не всегда реалистично

Основное правило: покрывайте критичную бизнес-логику на 100%, остальное 80-90%.

Как вычисляется Coverage? | PrepBro