Программирование с ИИ
ENRU
3.9

Шаблон — напиши тесты

писать не обязательно, читать обязательно

Что это

Тест — это код, который проверяет другой код. Писать тесты самому не придётся, их охотно пишет ИИ. А вот читать их придётся, и это окупается: хороший набор тестов — это список того, что твоя программа обещает делать.

Для того, кто работает с ИИ, у тестов есть второе применение, которое важнее первого: они не дают сломать то, что уже работало. Попросил правку, прогнал тесты — сразу видно, задел ли ИИ соседнее.

Как выглядит в коде

Сначала список случаев, потом код

Главный приём: не проси сразу тесты. Попроси перечислить, что проверять.

Лучше
Вот функция split_message. Перечисли списком, какие случаи
стоит проверить тестами. Пока без кода — только список.
Отметь, какие случаи считаешь важными, а какие — на всякий случай.

Список читается за полминуты, и в нём сразу видно, одинаково ли вы поняли задачу:

Ответ ИИ
Важные:
1. Текст короче лимита — возвращается одним куском
2. Текст длиннее лимита — режется по границам абзацев
3. Склейка кусков равна исходному тексту
4. Слово не разрывается посередине

На всякий случай:
5. Пустая строка
6. Текст ровно по лимиту, символ в символ
7. Абзац длиннее лимита целиком

Случай 7 — тот самый, о котором обычно забывают. Увидев список, ты решаешь, что нужно, а что лишнее, и только потом просишь код.

Запрос
Напиши тесты на pytest для случаев 1–4 и 7. Остальные пропусти.

Шаблон

Запрос
Код: <что тестируем>
Чем: <pytest / unittest / что в проекте уже есть>
Случаи: <список, согласованный заранее>
Без: <моков, если можно обойтись; внешней сети; файлов на диске>

Как сказать ИИ

Тест проверяет поведение, а не устройство

Плохой тест ломается при любом рефакторинге, даже если программа работает правильно. Так бывает, когда тест заглядывает внутрь: проверяет приватные поля, порядок вызовов, промежуточные переменные.

Запрос
Тесты должны проверять только то, что функция возвращает,
и её видимые эффекты. Во внутреннее устройство не заглядывай:
после рефакторинга тесты должны продолжать проходить.

Проси тесты, которые сначала падают

Способ убедиться, что тест вообще что-то проверяет:

Запрос
Перед тем как чинить баг, напиши тест, который его
воспроизводит. Он должен падать на текущем коде.

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

Запускать обязательно

Сгенерированные тесты надо прогнать. Звучит очевидно, но пропускают это постоянно — тесты выглядят убедительно и создают ложное чувство покрытия.

pytest -q

На что смотреть

Тест, который проходит всегда. assert result is not None там, где функция не может вернуть None. Выглядит как проверка, не проверяет ничего.

Моки вместо проверки. ИИ подменяет заглушкой половину системы, и тест проверяет, что заглушка вернула то, что в неё положили. Формально зелёный, по сути пустой.

Тесты повторяют реализацию. Если в тесте построчно воспроизведён алгоритм функции, он не проверяет правильность — он проверяет, что код равен самому себе.

Проверены только удачные случаи. Пустые данные, None, обрыв сети, слишком длинный вход — туда баги и прячутся. Если в наборе нет ни одного неудачного случая, набор неполон.

Шпаргалка

  • Сначала список случаев, потом код тестов.

  • Тест проверяет поведение, а не внутреннее устройство.

  • Тест на баг должен падать до починки.

  • Тест, который никогда не падал, ничего не гарантирует.

  • Сгенерированные тесты обязательно прогнать.

  • Нет ни одного неудачного случая — набор неполон.