Практика: отладка, тестирование и мини-проекты на Python
Зачем нужен этот урок
К этому моменту вы уже умеете писать программы на Python: используете типы данных, условия и циклы, разбиваете код на функции и модули, работаете с файлами и коллекциями. Следующий шаг, который отличает просто написанный код от работающей программы, — это практика трёх навыков:
Отладка: находить причину ошибки и исправлять её системно
Тестирование: проверять, что код работает не только “на одном примере”, а стабильно
Мини-проекты: собирать знания вместе и оформлять их в завершённые программыПосле этой статьи вы сможете:
читать traceback (стек вызовов) и быстро понимать, где случилась ошибка
использовать несколько подходов к отладке: print, отладчик, pdb
писать простые автоматические тесты через unittest
проектировать небольшие программы из функций и модулей так, чтобы их было легче проверять!Блок-схема показывает типовой цикл отладки и закрепления исправления тестом
Отладка: как думать, когда код “не работает”
Отладка — это не магия, а последовательность действий:
воспроизвести проблему
собрать информацию (ошибка, входные данные, шаги)
сформулировать гипотезу, почему так происходит
проверить гипотезу (минимальным экспериментом)
исправить и убедиться, что исправление не ломает другоеГлавное правило: не пытайтесь “чинить наугад”. Лучше потратить минуту на понимание, чем час на хаотичные правки.
Как читать сообщения об ошибках
Когда Python падает с ошибкой, вы обычно видите traceback — список вызовов, который заканчивается строкой с типом ошибки.
Официальная справка про встроенные исключения:
Built-in ExceptionsАнатомия traceback
Traceback почти всегда читают снизу вверх:
последняя строка — тип ошибки и сообщение
строки выше — где именно это произошло (файл, номер строки, фрагмент кода)
если ошибок несколько “по цепочке”, traceback показывает путь: какая функция вызвала какуюПример:
Ожидаемая ошибка:
ValueError: строка не выглядит как целое числоЧастые ошибки новичка и что они означают
| Ошибка | Типичная причина | Как быстро проверить |
|---|---|---|
| SyntaxError | опечатка в синтаксисе (скобки, двоеточие, кавычки) | посмотрите на строку и символ, который подсвечен |
| IndentationError | неверные отступы, смешали табы и пробелы | выровняйте отступы, используйте 4 пробела |
| NameError | переменная/функция не определена или опечатка в имени | проверьте, где объявлено имя |
| TypeError | операция над несовместимыми типами | распечатайте type(...) у значений |
| ValueError | тип подходит, но значение “не то” (например, int("abc")) | распечатайте исходную строку, проверьте ввод |
| KeyError | нет ключа в словаре | используйте get() или проверку in |
| IndexError | индекс вне границ списка | проверьте len(list) и индекс |
| FileNotFoundError | неверный путь к файлу | распечатайте путь, проверьте рабочую папку |
Минимальный воспроизводимый пример
Если программа большая, полезно “сжать” проблему до минимума:
оставьте только тот код, который приводит к ошибке
подставьте конкретные входные данные вместо input()
временно отключите всё лишнееЗачем это нужно:
проще понять, что именно ломается
быстрее проверять гипотезы
легче попросить помощи (можно показать маленький кусок кода)Приёмы отладки без специальных инструментов
Отладка через print()
Это самый простой и часто достаточный метод.
Что полезно печатать:
значения переменных в ключевых местах
типы данных: type(x)
размеры коллекций: len(items)Пример: ищем, почему не считается сумма чисел из файла.
repr(line) полезен тем, что показывает скрытые символы (например, \n).
Минус подхода: если print становится слишком много, отладка превращается в “шум”. Тогда стоит перейти к отладчику или логированию.
Отладка через assert
assert — это проверка, которая должна быть истинной. Если нет — программа падает с AssertionError.
Пример:
Когда полезно:
вы хотите быстро зафиксировать “ожидаемое условие” прямо в коде
вы отлавливаете неправильные данные как можно раньшеВажно понимать:
assert — это не замена обработке ошибок для пользователя
assert чаще применяют как внутренние проверки при разработкеОфициальная справка (инструкция assert):
The assert statementОтладчики: когда нужно пошагово
pdb: встроенный отладчик Python
pdb позволяет остановить программу и пошагово смотреть, что происходит.
Документация:
pdb — The Python DebuggerМини-пример:
Когда выполнение остановится, вы сможете вводить команды. Самые полезные:
n — следующая строка (step over)
s — зайти внутрь функции (step into)
p имя — распечатать значение, например p a
c — продолжить выполнение (continue)
q — выйтиОтладка в VS Code
Если вы запускаете код в Visual Studio Code, удобно ставить breakpoint (точку остановки) кликом слева от строки и запускать отладку.
Официальная документация VS Code:
Debugging in Visual Studio CodeПлюсы для новичка:
вы видите переменные в боковой панели
можно выполнять код по шагам без команд в консоли
легче понять, как меняются значения в циклеТестирование: как убедиться, что код работает
Тестирование — это запуск кода в автоматическом режиме и сравнение результата с ожидаемым.
Идея простая:
вы пишете функцию
задаёте входные данные
проверяете, что выход совпадает с ожиданиемКакие тесты бывают на базовом уровне
| Вид проверки | Что проверяем | Как обычно делают на старте |
|---|---|---|
| ручная проверка | “я сам ввёл данные и посмотрел результат” | запускают программу и пробуют разные варианты |
| проверки через assert | простые условия внутри кода | assert something == expected |
| модульные тесты | отдельные функции по отдельности | unittest |
Для новичка самый правильный следующий шаг — модульные тесты, потому что они учат писать функции, которые легко проверять.
unittest: встроенная библиотека для тестов
unittest — модуль стандартной библиотеки Python.
Документация:
unittest — Unit testing frameworkМинимальный пример
Представим, что у вас есть файл calc.py:
Создадим тесты в test_calc.py:
Запуск:
Если всё хорошо, вы увидите, что тесты прошли.
Что важно в структуре теста
тесты должны быть быстрыми
тесты должны быть независимыми друг от друга
имя теста должно объяснять, что именно проверяетсяЧто именно тестировать
Хорошая привычка: проверять не только “обычный случай”, но и крайние случаи:
пустые данные
нулевые значения
отрицательные значения (если они возможны)
неверный ввод (если вы ожидаете, что так бывает)Пример: тесты для функции “скидка” из прошлого урока про return.
Тесты:
Как писать код так, чтобы его было легко отлаживать и тестировать
Ниже несколько практичных принципов, которые напрямую опираются на темы прошлых уроков (функции, модули, файлы, коллекции).
Разделяйте “логику” и “ввод/вывод”
Старайтесь, чтобы функции:
получали данные аргументами
возвращали результат через return
не делали input() внутри и не печатали “всё подряд”Тогда функцию легко протестировать.
Плохая тестируемость:
Хорошая тестируемость:
Делайте маленькие функции
Функция на 10–20 строк почти всегда проще:
понять
отладить
покрыть тестамиДержите данные в коллекциях, а не в десятках переменных
Если у вас “много однотипных значений”, используйте list или dict. Это уменьшает количество ошибок вида “не ту переменную обновили”.
Мини-проекты: собрать всё вместе
Ниже три примера мини-проектов. Они специально построены из тем курса: условия и циклы, функции и модули, файлы, коллекции, плюс отладка и тестирование.
Мини-проект: консольный список дел с сохранением в файл
Идея:
хранить задачи в списке list
сохранять задачи в текстовый файл
поддержать команды: добавить, показать, удалить, выйтиВариант структуры проекта:
todo_storage.py — загрузка/сохранение
todo_app.py — логика командtodo_storage.py:
todo_app.py:
Как применяются навыки отладки и тестирования:
при падении на удалении по индексу вы сразу увидите IndexError и поймёте, что нужен диапазон 0 <= idx < len(tasks)
функцию print_tasks и логику преобразования номера задачи можно вынести и протестировать отдельноМини-проект: анализ текста — частота слов и отчёт
Идея:
прочитать файл
посчитать частоту слов в dict
вывести топ-N словКлючевой приём: сделать “чистую” функцию, которая не читает файлы, а работает со строкой.
Такую функцию легко покрыть тестами: подать короткую строку и сравнить словарь.
Мини-проект: игра “угадай число” с режимом отладки
Идея:
компьютер загадывает число
пользователь угадывает
программа подсказывает “больше/меньше”Хитрый момент обучения: добавить “режим отладки”, чтобы видеть загаданное число при необходимости.
Эта программа тренирует:
циклы while и continue
условия if/elif/else
работу со строками и проверкой ввода
практическую отладку через “debug-флаг”Практичный рабочий процесс
Полезная последовательность, которая экономит время:
запускайте программу маленькими шагами
при ошибке сначала читайте последнюю строку traceback, затем ищите вашу строку кода
фиксируйте исправления тестом, если ошибка может повториться
выносите логику в функции, а ввод/вывод оставляйте в main()Итоги
Вы научились практическим навыкам, которые делают программирование “взрослым”:
читать и понимать traceback
отлаживать код через print, assert, pdb и отладчик в VS Code
писать базовые модульные тесты через unittest
проектировать мини-программы из функций и модулей так, чтобы их было легко отлаживать и проверятьЭти умения напрямую усиливают всё, что вы прошли ранее: типы данных, условия, циклы, функции, модули, файлы и коллекции. С этого момента ваши программы будут не только “получаться”, но и становиться надёжнее и понятнее.