Учебник Юнит-тестирование на Python для начинающих
Практический курс по юнит-тестированию на Python. Вы научитесь писать тесты на встроенном модуле unittest, проверять ожидания assert-методами, изолировать код от базы данных, сети и времени с помощью unittest.mock, а затем познакомитесь с фреймворком pytest, покрытием кода и подходом TDD. Большинство примеров на unittest и unittest.mock — это стандартная библиотека, поэтому их можно запускать прямо в браузере и видеть реальный результат.
Курс «Юнит-тестирование на Python» состоит из 6 разделов и 23 уроков: Введение в юнит-тестирование, Assert-методы и организация тестов, Тестирование на практике, Тест-дублёры и mock, pytest: обзор и сравнение и Качество и практика тестирования. Уроки идут по порядку — от основ к более сложным темам, в каждом есть объяснение с примерами, а в конце — вопросы для самопроверки. К урокам привязаны задачи с автоматической проверкой: прочитали тему — сразу закрепили её кодом.
Программа курса
1 Введение в юнит-тестирование
- Зачем нужны юнит-тесты
Что такое юнит-тест, какие проблемы он решает и чем отличается от ручной проверки и других видов тестов в пирамиде тестирования.
- Модуль unittest: первый TestCase
Что такое unittest, как устроен класс TestCase, зачем нужны методы test_* и assertEqual и как написать и запустить первый тест.
- Структура теста: паттерн AAA
Паттерн Arrange-Act-Assert: как организовать тело теста, чтобы он читался легко, проверял одно поведение и имел понятное имя.
- Как запускать тесты
Запуск тестов через python -m unittest, автообнаружение test-файлов и программный запуск через unittest.main и TextTestRunner.
- Зачем нужны юнит-тесты
2 Assert-методы и организация тестов
- Ключевые assert-методы
Главные методы TestCase: assertEqual, assertTrue, assertIn, assertIsNone, assertAlmostEqual для float и сравнение коллекций без порядка.
- Фикстуры: setUp и tearDown
Как фикстуры setUp и tearDown убирают дублирование подготовки, обеспечивают изоляцию тестов и освобождают ресурсы даже при падении.
- Фикстуры класса: setUpClass
Фикстуры setUpClass и tearDownClass для дорогой подготовки один раз на весь класс и почему в них кладут только данные для чтения.
- Пропуск тестов и группировка
Пропуск тестов через skip, skipIf и skipUnless, пометка известных багов через expectedFailure и ручная сборка наборов TestSuite.
- Ключевые assert-методы
3 Тестирование на практике
- Тестируем функции и границы
Как тестировать чистые функции: типичные, граничные и пустые входы, проверка порогов и фиксация договорённостей о поведении.
- Тестируем классы
Тестирование классов на Python: состояние объекта, методы, инварианты и проверка поведения через публичный интерфейс, а не детали.
- Тестирование исключений
Как проверять исключения: assertRaises как контекст, assertRaisesRegex для текста ошибки и доступ к объекту через ctx.exception.
- Параметризация через subTest
Прогон одной проверки на множестве входов через subTest, таблицы вход-ожидание и принципы того, что вообще покрывать тестами.
- Тестируем функции и границы
4 Тест-дублёры и mock
- Зачем нужны тест-дублёры
Зачем мокать: изоляция кода от БД, сети, файлов, времени и случайности, виды тест-дублёров и когда мок только вредит.
- Mock и MagicMock
Объекты Mock и MagicMock из unittest.mock: return_value, магические методы, атрибуты вызовов и зачем нужен spec для строгости.
- patch: декоратор и контекст
Подмена зависимостей через patch как декоратор и контекстный менеджер, главное правило патчинга по месту использования.
- Проверка вызовов и side_effect
Проверка взаимодействий: assert_called_with, call_count и call_args_list, side_effect для последовательностей и мок времени.
- Зачем нужны тест-дублёры
5 pytest: обзор и сравнение
- Чем удобен pytest
Обзор pytest: простой assert вместо assert-методов, тесты-функции без классов, умная диагностика и совместимость с unittest.
- Фикстуры и параметризация pytest
Фикстуры pytest через аргументы и yield, conftest.py и scope, параметризация @pytest.mark.parametrize и контекст pytest.raises.
- unittest против pytest
Сводное сравнение unittest и pytest, когда что выбирать, миграция между ними и обзор экосистемы плагинов pytest и coverage.
- Чем удобен pytest
6 Качество и практика тестирования
- Покрытие кода тестами
Что измеряет coverage.py, чем покрытие ветвей строже покрытия строк и почему 100% покрытия не равно отсутствию багов.
- Хорошие тесты: принципы FIRST
Принципы FIRST: быстрые, независимые, детерминированные и самопроверяемые тесты, борьба с flaky и значение понятных имён.
- TDD: red-green-refactor
Разработка через тесты на живом примере: падающий тест red, минимальный код green и безопасный рефакторинг под защитой тестов.
- Легаси-код и CI
Характеризующие тесты для легаси-кода, внедрение зависимостей ради тестируемости, запуск тестов в CI и финальный чек-лист.
- Покрытие кода тестами