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

Тесты — прочитать и запустить

что означает красный вывод и чему он на самом деле верит

Что это

Как просить тесты — статья 3.9. Эта статья о том, что делать с полученными: как читать вывод pytest, что считать настоящей проверкой и почему зелёные тесты не означают, что всё хорошо.

Писать тесты самому не придётся. Читать их придётся обязательно — иначе ты доверяешь проверке, которую не проверял.

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

Функция режет длинное сообщение на куски. Тесты написаны по списку случаев из статьи 3.9.

pytest -q
измерено
...F                                                                     [100%]
=================================== FAILURES ===================================
_______________________ test_paragraph_longer_than_limit _______________________

    def test_paragraph_longer_than_limit():
        text = "y" * 300
        parts = split_message(text, limit=100)
>       assert all(len(p) <= 100 for p in parts)
E       assert False

test_split.py:21: AssertionError
=========================== short test summary item ============================
FAILED test_split.py::test_paragraph_longer_than_limit - assert False
1 failed, 3 passed in 0.02s

Как это читать

Первая строка — карта. ...F значит: три теста прошли, четвёртый упал. Точка — успех, F — провал, E — ошибка в самом тесте, s — пропущен.

> отмечает строку, на которой упало. Здесь — assert.

E — что именно не сошлось. assert False значит, что условие оказалось ложным.

Последняя строка — итог. 1 failed, 3 passed — самое важное, с неё можно и начинать.

Что показал упавший тест

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

Это ровно тот случай, который в статье 3.9 был помечен как «тот, о котором обычно забывают». Тест его поймал — в этом и смысл.

Полезные ключи

pytest -q                       # коротко
pytest -x                       # остановиться на первом падении
pytest -k "split"               # только тесты с «split» в имени
pytest test_split.py::test_empty  # ровно один тест
pytest -q --tb=short            # короткий трейсбек

Второй и четвёртый — рабочие лошадки при починке: не надо каждый раз ждать весь набор.

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

Запрос
Вот вывод pytest. Что именно не сошлось и почему?
Код пока не чини.

<вывод>

Когда тест упал после твоей правки:

Запрос
Этот тест проходил до моей правки и упал после.
Я менял только функцию X. Что в ней могло на это повлиять?

И проверка качества самих тестов:

Запрос
Эти тесты точно проверяют поведение, а не то, что код
равен самому себе? Есть ли среди них такие, которые
пройдут при любой реализации?

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

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

assert result is not None там, где None невозможен. Выглядит проверкой, не проверяет ничего.

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

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

Все случаи удачные. Нет ни одного теста с пустыми данными, None или мусором на входе — набор неполон, и как раз там живут баги.

Зелёные тесты вместо чтения кода. Тесты проверяют то, что в них написано, и ничего больше. Они дополняют чтение диффа, а не заменяют его.

Шпаргалка

  • ...F — карта прогона: точка успех, F провал.

  • > — строка падения, E — что не сошлось, последняя строка — итог.

  • Упавший тест — хорошая новость; опасны зелёные и пустые.

  • Проверка теста: сломай код, тест обязан покраснеть.

  • pytest -x и pytest -k экономят время при починке.

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