Clojure.spec — почему это полезно и когда используется

Я недавно смотрел выступление Рича Хики на Cojure Conj 2016, и хотя оно было очень интересным, Я не совсем понял смысл clojure.spec или когда его использовать. Казалось, что большинство идей, таких как соответствие, валидность и т. д., уже имели аналогичные функции в Clojure.

Я изучаю clojure всего около 3 месяцев, так что, возможно, это связано с отсутствием опыта программирования/Clojure.

Работают ли clojure.spec и cljs.spec так же, как Clojure и Cljs, хотя они и не на 100% одинаковы, но основаны на одних и тех же базовых принципах.


person rbb    schedule 11.12.2016    source источник
comment
Возможный дубликат Что такое спецификация Clojure?   -  person nha    schedule 11.12.2016
comment
Где это ранее существовавшее определение conform? (Как вы могли иметь его вообще без формата спецификации для проверки?)   -  person Charles Duffy    schedule 12.12.2016


Ответы (2)


  • Вы устали документировать свои программы?
  • Вызывает ли перспектива придумать еще несколько тестов прокрастинацию?
  • Когда начальник говорит «тестовое покрытие», вы вздрагиваете от страха?
  • Вы забыли, что означают имена ваших данных?

Для плавного выражения жестких спецификаций вам понадобится Clojure.Spec!


Clojure.spec предоставляет единый метод документирования, спецификации и автоматического тестирования ваших программ, а также проверки ваших данных в реальном времени.

Он крадет практически все его идеи. И это не делает ничего, что вы не можете сделать для себя.

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

person Thumbnail    schedule 11.12.2016
comment
Вы используете его в тесте? Каков рабочий процесс? Я предполагаю, что с помощью s/instrument в режиме repl будет какой-то тестовый поток для тестов, которые используют spec. - person Justin Thomas; 12.12.2016
comment
@JustinThomas Каков рабочий процесс? - вот это хороший вопрос. Я думаю, вы должны спросить об этом именно в таких терминах. - person Thumbnail; 12.12.2016

На конференции clojure/conj на прошлой неделе, наверное, в половине презентаций так или иначе упоминалась спецификация, и она еще даже не вышла из альфа-версии. spec — это основная функция clojure; она здесь, чтобы остаться, и она мощная.

В качестве примера его мощности возьмем статическую проверку типов, которую многие приветствуют как своего рода страховочную сетку и определяющую характеристику многих языков программирования. Он невероятно ограничен тем, что хорош только во время компиляции и проверяет только типы. spec, с другой стороны, проверяет и согласовывает любой предикат (не только тип) для аргументов, возврата, а также может проверять отношения между ними. Все это является внешним по отношению к коду функции, отделяя логику функции от смешения с проверкой и документацией по коду.

Относительно РАБОЧЕГО ПРОЦЕССА:

Одним из архетипических примеров преимуществ проверки отношений по сравнению только с проверкой типов является функция, вычисляющая подстроку строки. Проверка типов гарантирует, что в (subs s start end) s является строкой, а start и end — целыми числами. Однако внутри функции необходимо выполнить дополнительную проверку, чтобы убедиться, что start и end являются положительными целыми числами, что end больше, чем start, и что результирующая подстрока не больше исходной строки. Все эти вещи можно указать, например (простите меня, если что-то из этого немного избыточно или, может быть, даже неточно):

(s/fdef clojure.core/subs

        :args (s/and (s/cat :s string? :start nat-int? :end (s/? nat-int?))
                     (fn [{:keys [s start end]}]
                       (if end
                         (<= 0 start end (count s))
                         (<= 0 start (count s)))))

        :ret string?

        :fn (fn [{{:keys [s start end]} :args, substring :ret}]
              (and (if end
                     (= (- end start) (count substring))
                     (= (- (count s) start) (count substring)))
                   (<= (count substring) (count s)))))

Вызовите функцию с демонстрационными данными, соответствующими приведенной выше спецификации args:

(s/exercise-fn `subs)

Или запустите 1000 тестов (это может несколько раз дать сбой, но продолжайте работать, и оно будет работать — это связано с тем, что встроенный генератор не может удовлетворить вторую часть предиката :args; можно написать собственный генератор, если нужный):

(stest/check `subs)

Или хотите проверить, делает ли ваше приложение недействительные вызовы subs во время работы в режиме реального времени? Просто запустите это, и вы получите исключение из спецификации, если функция вызывается, а спецификации не соблюдены:

(stest/instrument `subs)

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

Я предполагаю, что наш рабочий процесс будет состоять в том, чтобы запустить тесты для спецификаций, используя это (найдено в руководстве по спецификациям clojure):

(-> (stest/enumerate-namespace 'user) stest/check)

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

Вы также можете использовать s/conform для деструктуризации сложных данных в самих функциях или использовать s/valid в качестве пред- и пост-условий для запуска функций. Я не слишком заинтересован в этом, так как это накладные расходы в производственной системе, но это возможно.

Нет предела возможностям, и мы только что коснулись поверхности! Крутые вещи появятся в ближайшие месяцы и годы со спецификацией!

person Josh    schedule 12.12.2016
comment
clojure-future-spec — это бэкпорт clojure.spec для Clojure 1.8. Понятия не имею, на что это похоже. - person Thumbnail; 12.12.2016
comment
@Thumbnail не уверен, зачем использовать какой-либо задний порт? 1.9 будет в производстве через 4-6 месяцев скорее всего. - person Josh; 12.12.2016
comment
... зачем вам использовать какой-либо задний порт? - использовать spec всерьез сейчас. - person Thumbnail; 12.12.2016
comment
Я бы доверился alpha14, которая на данный момент достаточно зрелая и которой уже 7 месяцев, а не стороннему бэк-порту, который устареет через несколько месяцев. - person Josh; 12.12.2016
comment
Бэкпорт — это просто копия clojure.spec, clojure.spec.gen и clojure.spec.test из 1.9; с дополнительными функциями clojure.core версии 1.9, перенесенными в clojure.future. С версией 1.8 он устареет через несколько месяцев. - person Thumbnail; 13.12.2016