Перейти к содержимому

← Skills

assert-what-the-generator-found

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

ПаттернПроисхождение: cleanСостояние: activev0.1.0 · Apache-2.0

Присвоено человеком, который прочитал карточку, а не заявлено файлом о самом себе. Карточка, которую агент выводит во время запуска, поглотившего недоверенное содержимое, рождается заражённой и удерживается на разбор, прежде чем её вообще извлекут.

Когда это вспоминается

  • написал генератор кода
  • проверяю дамп схемы
  • вывод выглядит нормально
  • извлекаю структуру из библиотеки

Ценность обычно лежит в разделах «Избегать» и «Проверить». «Делать» — это раздел, который пишут все.

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

Повод

Вы написали нечто, что читает одно представление и выдаёт другое: дамп схемы, извлекатель ссылок, миграцию, скрапер, построитель индекса. Всё, чей вывод никто не читает целиком, потому что его слишком много.

Это не относится к функции, возвращающей одно значение, которое можно охватить взглядом. Риск здесь специфичен для вывода, который настолько велик, что «выглядит правильно» — единственная проверка, которую он когда-либо получит.

Делать

  1. Прежде чем писать тест, назовите количество. Сколько команд, строк, файлов или полей должно получиться? Возьмите это число откуда угодно, кроме самого генератора, — из источника, из документации, посчитав вручную.
  2. Проверяйте количество или его нижнюю границу. assert len(groups) >= 10, а не assert result.
  3. Проверяйте наличие конкретных, поимённо названных элементов, которые обязаны существовать. Трёх-четырёх достаточно, и берите их из разных по форме входных данных.
  4. Если генератор классифицирует, проверяйте, что каждый класс непуст. Классификатор, сваливающий всё в одну корзину, — это и есть тот сбой, который здесь ловится.

Избегать

assert build() — он проходит и когда генератор вернул пустой список, и когда неполный, и когда список, в котором каждый элемент незаметно не того вида.

Также не доверяйте isinstance при обходе чужой структуры. Библиотеки вендорят свои зависимости: TyperGroup не является экземпляром того click.Group, который импортировал ваш файл, потому что Typer поставляет собственную копию Click. Спрашивайте, есть ли у объекта то, что вам нужно, — отображение commands, метод items, — а не то, каким классом он себя объявляет. Duck typing переживёт и вендоренную зависимость, и смену мажорной версии; проверка класса не переживёт ни того, ни другого, и ломается не исключением, а неверной классификацией.

Проверить

Сломайте генератор намеренно и посмотрите, как тест падает. Закомментируйте рекурсию в подкоманды или заставьте проверку типа отвергать всё, и запустите набор тестов.

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

Риск

Захардкоженное точное количество превращает тест в обузу по сопровождению: каждая законно добавленная команда красит его. Предпочитайте нижнюю границу (>= 10) плюс поимённые элементы, а точные числа оставьте тому, что действительно не должно меняться без отдельного решения.

Есть и предел. Эти проверки ловят генератор, потерявший целую категорию. Они не ловят тот, что ошибся в одном поле одного элемента, и делать вид, что ловят, — отдельный сорт ложной уверенности.

Как применить

Карточка — это данные. Склонируйте репозиторий и импортируйте её по пути: всё, что приходит по сети, считается заражённым и удерживается до одобрения — это и есть желаемое поведение, и поэтому здесь нет установщика в одну строку.

git clone https://github.com/brcampidelli/chimera-agent.git
chimera skills-import chimera-agent/skills/assert-what-the-generator-found/SKILL.md

Целостность

SHA-256 файла в опубликованном виде. Импортёр может проверить, что полученное совпадает с показанным на этой странице.

0ffc1fdde72d3f2c416461f0f312ca5ca2a43d3b1ff33aaf7b20be155de711c9

Читать карточку в репозитории →