Глава 23 · Часть V · Проверяем и автоматизируем

Пишем первые автоматические тесты

Тесты SafeSort работают только во временном каталоге pytest — ни один из них не трогает настоящие пользовательские файлы.

SafeSort · Часть 5 из 6
Git и GitHubПланированиеПроектРеализацияТесты и CIРелиз

Представим: кто-то случайно сломал классификатор — расширение .PDF в верхнем регистре перестало определяться как документ. Как об этом узнать, не проверяя вручную каждый раз?

~/safesort $ pytest tests/test_classifier.py -q
........F.
=================================== FAILURES ===================================
______________________ test_classify_is_case_insensitive _______________________
 
assert classify(".PDF", DEFAULT_EXTENSIONS) == "documents"
E AssertionError: assert 'other' == 'documents'
 
1 failed, 9 passed in 0.04s
RED — тест обнаружил поломку раньше человека.

Возвращаем нормализацию регистра на место — и тот же тест подтверждает исправление:

~/safesort $ pytest tests/test_classifier.py -q
..........
10 passed in 0.02s
GREEN — поведение снова соответствует ожиданию.

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

Терминал (окружение активировано)
pip install -e ".[dev]"
pytest tests/ -v
Тесты файловой системы никогда не используют настоящие пользовательские каталоги
Тест, который вызывает apply прямо на ~/Downloads, при первом же неудачном запуске способен испортить реальные файлы. Все тесты SafeSort работают внутри временного каталога, который pytest создаёт и удаляет сам, через встроенную функцию tmp_path — она передаётся тестовой функции как обычный параметр:
Только читают
ВРЕМЕННЫЙ КАТАЛОГ /tmp/pytest-.../ — создаём, перемещаем, удаляем — удаляется автоматически
Меняют файлы
РЕАЛЬНЫЕ ФАЙЛЫ ПОЛЬЗОВАТЕЛЯ ~/Downloads — здесь тесты не выполняются никогда
tests/test_classifier.py
from safesort.classifier import classify
from safesort.config import DEFAULT_EXTENSIONS

def test_classify_known_extension():
    # Arrange: расширение и правило классификации уже готовы, ничего создавать не нужно
    # Act
    rezultat = classify(".pdf", DEFAULT_EXTENSIONS)
    # Assert
    assert rezultat == "documents"

Три части — Arrange (подготовить), Act (вызвать), Assert (проверить) — повторяются почти в каждом тесте SafeSort. Функция classify() — хороший первый тест не случайно: она чистая, не трогает файловую систему и не зависит ни от чего внешнего. Следующая страница берётся за более сложные тесты — те, что действительно создают файлы во временном каталоге.

Коротко

  • Тест — код, который проверяет код: запускает функцию и сравнивает результат с ожидаемым.
  • tmp_path — временный каталог, который pytest создаёт и удаляет для каждого теста сам.
  • Ни один тест SafeSort не обращается к настоящему пользовательскому каталогу вроде ~/Downloads.