All streams
Search
Write a publication
Pull to refresh
21
0

User

Send message
Но по факту сам код функции и является полной спецификацией задачи.

А вот и нет. Например, вы можете очень легко проверить, что функция проверки электронной подписи возвращает True для реальных подписей и False для рандомных данных, но попробуйте такую функцию написать.

Какую конкретно задачу? Вы можете ее сформулировать?

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

Написать исчерпывающий набор тестов только на основе свойств — часто та еще задача. Поэтому идеальный вариант — комбинировать.

Опять же — какая была популярность у скалы в 2007? :) Я не отрицаю, что подход не новый, но ощущение, что активная популяризация началась примерно года два назад, когда стали появляться статьи про питоновский Hypothesis. Питон простой, на нем пишет дофига людей, он не требует понимания таких "страшных" вещей, как монады и гомоморфизмы — и видимо это стало своеобразным толчком. Но опять же — я могу очень сильно ошибаться.


Поэтому в тех языках, где система типов помощнее, это сначала и появляется.

Кстати, я как-то попытался написать hypothesis-подобный фреймворк на чистой сишечке. И даже стало получаться, но потом резко пропало свободное время примерно на годик. Как думаете — стОит продолжать, или смысла нет?

Вот, это кстати не совсем хорошо, т.к. создает иллюзию, что, раз у вас тест на сотне сгенеренных примеров отработал — то это даст больше гарантий. На самом деле нет.

Тут на самом деле можно провести аналогию — баги это враги, традиционные тесты — выискивание врагов в бинокль и отстрел из винтовки, тесты на основе свойств — закидывание осколочными гранатами. Можно всех отстрелять по одному из винтовки — но это долго и дорого, плюс всегда есть шанс, что снайпер все равно кого-то упустит. Можно закидать гранатами — всего несколько таких "бросков" может положить просто уйму багов, даже хорошо спрятавшихся, хотя и тут некоторым все равно может повезти. Но тот же процент "зачистки" будет достигнут гораздо меньшими затратами. В целом мое мнение: тесты на основе свойств — не замена традиционным, а очень мощное дополнение. Лучше всего совмещать оба подхода.


Проблема же почти всегда в граничных случаях, а их в общем наборе обычно крайне мало и маловероятно, что автогенерация на какой-то из них случайно попадет.

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

Генерация тестовых данных — может быть полезна, но это, как верно подмечено, больше про fuzzy, или это прямо обязательный атрибут тестирования на основе свойств?

Видимо я сделал недостаточный акцент на этом в статье, но генерация тестовых данных — это как раз один из основных атрибутов тестов на основе свойств. А fuzzing — это просто очень частный случай, когда тестируемым свойством является "не падать".


Ну и непонятно насколько тут нужны фреймворки, насколько они повышают удобство написания таких тестов?

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


  • не надо в явном виде писать циклы по прогону одного и того же теста
  • удобный инструментарий для быстрого написания генераторов
  • возможность делать повторяемые тесты (например за счет вывода в консоль сида, с которым сгенерился фейлящийсе тест, и который можно подставить в качестве параметра в test runner, чтобы гарантированно получить тот же результат)
  • минификация данных (вы же не хотите дебажить почему ваша функция упала на обработке массива из 1000 элементов?)

Кстати, в статье есть целый абзац, посвященный этому.


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

Да, про quickcheck в хаскеле наслышан, просто до относительно недавнего времени эта тема была совсем далека от мейнстрима.

Обычные тесты проверяют какие-то конкретные единичные примеры. Тесты на основе свойств выделяют определенные зависимости и проверяют их на сотнях примеров, и считается, что это даёт достаточно хорошую гарантию, что свойство будет выполняться для любых данных (ну, в рамках заданных предусловием).

Эмм, ну вот у вас есть интерфейс какого-то хранилища с ключами-строками. Вы пишете один тест, в котором в качестве ключа передаете 'John'. Потом еще один — где ключ пустая строка. Потом еще — где ключ строка максимально допустимой длины. Потом — где ключ максимально допустимой длины, и имеет юникодные символы. Потом — где ключ это невалидная юникодная строка (ну нужно же проверить, что оно там аккуратно ошибку вернет например, а не расхреначит все внутри). Потом начнутся тесты, где вы в разной последовательности добавляете и удаляете элементы. И вот уже у вас штук 30 тупых однообразных тестов, а потом в проде все неожиданно падает, потому что во внутренней реализации была тупая off-by-one ошибка, которую ваши точечные тесты все равно не поймали. Ну, просто не догадались нужную последовательность действий совершить над хранилищем, чтобы проблема вскрылась. А потом выясняется, что интерфейс этого хранилища надо "чуть-чуть поменять", и вам приходится перефигачивать все несколько десятков тестов. А с подходом на основе свойств — написали штук 5-10 тестов, проверяющих основные части контракта — и пусть оно само пытается придумать кейсы, на котором код сломается. Причем на мой субъективный взгляд писать тесты на основе свойств намного интереснее, чем традиционные. Ну и наконец — несколько традиционных тестов в качестве простых примеров и дополнительной документации никто не отменял.

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

Надеюсь, статья вас не разочарует: https://habr.com/post/434008/

Да, нетривиальные (на мой взгляд) примеры очень даже есть, мотивация написать статью усилилась, осталось только найти время.

Да, были мысли написать сборник идей для поиска свойств с примерами (обычно именно тут в начале самый большой затык с этим подходом происходит). Ну а если основные впечатления и кратко, то:


  • обычные example-based тесты никто не отменял
  • нужен некоторый опыт и определенная повернутость мозга, чтобы быстро придумывать хорошие property-тесты
  • подходит не для всего (хотя чем больше опыта, тем для бОльшего количества проблем получается находить хорошие свойства)
  • когда подходит (в моих случаях — подходит часто), то позволяет относительно небольшими усилиями вылавливать просто горы всяких edge-кейсов

Есть положительный опыт использования самого property based подхода в проекте на C++, есть опыт использования конкретно hypothesis в pet-проекте, и сейчас как раз в процессе переноса этого опыта на ещё один "боевой" проект.

А ещё удивляет, почему так мало пишут про такую классную штуку, как property based testing. Причем в питоне есть просто офигенный фреймворк hypothesis как раз для этого.

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

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

Не знаю насчет гугла, но если быть совсем точным, то Амазон дает 750 часов в месяц t2.micro на год. Да, можно год держать бесплатно одну виртуалку 24/7. А можно вместо этого иногда по необходимости поднимать на несколько часов по 75 (!!!) виртуалок (по умолчанию ограничение 5 инстансов на регион, всего 15 регионов), и это тоже бесплатно. Ну разве что за исходящий трафик могут взять немного, если лимит превысить.

Если верить этой статье, то схема Шамира на самом деле и есть частный случай кодов Рида-Соломона, так что вполне возможно, что Шамир просто разработал свою схему независимо. Правда, как написал выше mrsantak он еще и строго доказал, что в его схеме знание N-1 из N частей не облегчает подбор секрета, а Рид и Соломон вроде не заморачивались на эту тему, так что научная новизна в его работе точно есть. Кстати, в той же статье есть и идеи как сделать схему Шамира более устойчивой к ситуациям когда кто-то подсовывает заведомо неверные куски, либо уменьшить амплификацию данных при разделении секрета ценой уменьшения секьюрности. Более подробно это разжевано здесь (там как раз вопрос был чем же отличаются коды Рида-Соломона от схемы Шамира с точки зрения безопасности)

Information

Rating
Does not participate
Registered
Activity