Clojure.spec: как определить структуры данных, чувствительные к случайным изменениям? - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь Интерактивная разработка с clojure.spec и у меня проблема со спецификациями для аргументов функций, которые не могут сильно измениться. Например, если функция получает имя файла в качестве аргумента, я могу написать следующую спецификацию:

(s/def ::file-name string?)
(s/fdef test-fn :args (s/cat :x ::file-name))

Если я это упражняю:

(s/exercise-fn `test-fn)

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

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

Что мне делать? Любая соответствующая техника или хорошая практика?

1 Ответ

0 голосов
/ 26 апреля 2018

Это хорошо для тестирования, но это сделает спецификацию специфичной для выбранного набора.

Здесь полезны пользовательские генераторы:

(s/def ::file-name
  (s/with-gen string? #(gen/elements #{"good.txt" "bad.txt"})))
(s/fdef test-fn :args (s/cat :x ::file-name))

(где gen равно clojure.test.check.generators или clojure.spec.gen.alpha.)

Теперь предикат вашей спецификации по-прежнему string?, но значения, сгенерированные из этой спецификации, всегда будут из #{"good.txt" "bad.txt"}. Вы можете составить generators несколькими способами, например, вы можете создать генератор, который брал бы из набора строк ~ 50% времени и генерировал чисто «случайную» строку для других ~ 50%.

FYI clojure.spec.test.alpha/check также принимает карту opts, которая позволяет переопределять / указывать генераторы.

...