chimera-prove-the-test-discriminates
Регрессионный тест, падения которого вы никогда не видели, — это догадка. Сломайте код обратно и убедитесь, что тест краснеет, прежде чем его коммитить.
Присвоено человеком, который прочитал карточку, а не заявлено файлом о самом себе. Карточка, которую агент выводит во время запуска, поглотившего недоверенное содержимое, рождается заражённой и удерживается на разбор, прежде чем её вообще извлекут.
Когда это вспоминается
- написал регрессионный тест
- починил баг и добавил тест
- тест зелёный, катим
- добавляю тест после правки
Ценность обычно лежит в разделах «Избегать» и «Проверить». «Делать» — это раздел, который пишут все.
Текст карточки выше — перевод. Английский оригинал — это то, что импортирует командная строка, что читает агент во время работы и что подтверждает хеш ниже.
Повод
Вы починили баг и написали тест, чтобы он не вернулся. Тест проходит. Это всё свидетельство, которое у вас есть, и оно ровно такое же, каким было бы, если бы тест вообще ничего не утверждал про этот баг.
Особенно остро это, когда тест написан после починки: тогда единственный код, против которого он вообще работал, — код, где бага уже нет. Меньше это относится к тесту, написанному первым и красным, в цикле TDD, — его падение вы уже видели, в чём и состоит весь смысл цикла.
Это не относится к тесту на действительно новое поведение, где никакого «до» для отката не существует. Там различающая проверка другая: удалите новую реализацию и убедитесь, что тест падает на её отсутствии, а не на баге.
Делать
- Определите ровно ту правку, которая и есть починка, — hunk, а не коммит. Если починка — одно изменённое сравнение, то откатывать вы будете именно это сравнение.
- Откатите её.
git stashдля починки или руками верните ту одну строку в сломанный вид. - Запустите только новый тест:
pytest tests/test_thing.py::test_the_regression -x. - Прочтите падение. Падать должно ваше утверждение, с сообщением о поведении, — не
SyntaxError, не ошибка сбора тестов, неImportErrorиз наполовину откаченного файла. Это красное не по той причине, и о тесте оно не доказывает ничего. - Верните починку (
git stash pop) и убедитесь, что тот же тест теперь проходит. - Занесите факт в docstring теста: что было откачено и как выглядело падение. Следующему, кто тронет этот тест, нужно знать, что его вообще прогоняли против бага.
Избегать
Утверждать то, что верно в обоих мирах. Классическая форма:
result = parse_config(raw)
assert result is not None
assert "timeout" in result
Баг был в том, что timeout возвращался строкой "30" вместо целого 30. Оба утверждения держатся
в любом случае. Различает то, что изменилось:
# RIGHT — fails against the buggy code
assert parse_config(raw)["timeout"] == 30
assert isinstance(parse_config(raw)["timeout"], int)
Также не откатывайте, закомментировав целую функцию или удалив импорт, чтобы «упало побыстрее». Это даёт красный прогон, который случился бы для любого теста в файле, и потому не говорит ничего про этот тест. Откат обязан быть починкой и только починкой.
И избегайте близкого промаха, когда тест доходит до починенного кода путём, которым production
никогда не ходит, — это другой сбой, и карточка про него называется
chimera-test-the-wiring-not-the-class.
Проверить
Один двоичный вопрос: видели ли вы лично, как этот тест печатает падение, вызванное его собственным утверждением, против непочиненного кода?
Если да — вы закончили. Если ответ «он бы упал», вы не проверили ничего: эта фраза — предсказание, произведённое тем же рассуждением, что написало тест.
Механически:
git stash # remove the fix
pytest tests/test_x.py::test_regression # MUST be red, on your assertion
git stash pop # restore
pytest tests/test_x.py::test_regression # MUST be green
Красное, потом зелёное, оба наблюдались лично, — иначе тест не доказан.
Риск
Некоторые починки дёшево не откатишь: обновление зависимости, миграция схемы, удалённый файл, изменение в вендоренной библиотеке. Требовать отката там может стоить дороже, чем стоит сам тест. Честный запасной вариант — восстановить тот вход, который раньше ломал, и проверить конкретное значение, а затем прямо сказать в docstring, что красный прогон не наблюдался: недоказанный тест, признающий свою недоказанность, много лучше того, что подразумевает проверку.
Настоящая опасность этой карточки — забытый откат. Проделывать этот танец в грязном рабочем дереве —
верный способ закоммитить заново сломанную строку вместе с её собственным регрессионным тестом, при
зелёном наборе, потому что починку вы вернули не в тот файл. Запускайте git diff перед коммитом,
каждый раз.
И различающий тест хорош ровно настолько, насколько вы поняли баг. Он доказывает, что тест ловит этот откат. Он не доказывает, что вы починили первопричину, а не симптом, и считать прогон «красное, потом зелёное» доказательством этого — заявление больше, чем позволяет свидетельство.
Как применить
Карточка — это данные. Склонируйте репозиторий и импортируйте её по пути: всё, что приходит по сети, считается заражённым и удерживается до одобрения — это и есть желаемое поведение, и поэтому здесь нет установщика в одну строку.
git clone https://github.com/brcampidelli/chimera-agent.gitchimera skills-import chimera-agent/skills/chimera-prove-the-test-discriminates/SKILL.mdЦелостность
SHA-256 файла в опубликованном виде. Импортёр может проверить, что полученное совпадает с показанным на этой странице.
90d4bf00eb67055008527ee372153b2637fa2feea601ed6760997eda239f0b76