Clojure.spec: 如何规范对随机变化敏感的数据结构?
Clojure.spec: how to spec data structures sensitive to random changes?
我正在尝试 Interactive Development with clojure.spec,但函数参数的规范有问题,不能改变太多。例如,如果函数接收文件名作为参数,我可以编写以下规范:
(s/def ::file-name string?)
(s/fdef test-fn :args (s/cat :x ::file-name))
如果我锻炼它:
(s/exercise-fn `test-fn)
该函数将使用大量随机文件名进行测试,这些文件名将无法读取任何文件。可以将文件名限制为一组有效和无效的文件名。这对于测试来说很好,但它会使规范特定于所选集。
这不仅是文件名的问题,而且是任何复杂的数据结构的问题,即使是很小的随机更改也可能使它变得无用。
我该怎么办?有什么相关的技术或好的做法吗?
That is fine for testing, but it will make the spec specific to the chosen set.
这是自定义生成器的用武之地:
(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%%.[= 生成纯 "random" 字符串20=]
仅供参考 clojure.spec.test.alpha/check
还需要一张 opts
地图,允许您 override/specify 发电机。
我正在尝试 Interactive Development with clojure.spec,但函数参数的规范有问题,不能改变太多。例如,如果函数接收文件名作为参数,我可以编写以下规范:
(s/def ::file-name string?)
(s/fdef test-fn :args (s/cat :x ::file-name))
如果我锻炼它:
(s/exercise-fn `test-fn)
该函数将使用大量随机文件名进行测试,这些文件名将无法读取任何文件。可以将文件名限制为一组有效和无效的文件名。这对于测试来说很好,但它会使规范特定于所选集。
这不仅是文件名的问题,而且是任何复杂的数据结构的问题,即使是很小的随机更改也可能使它变得无用。
我该怎么办?有什么相关的技术或好的做法吗?
That is fine for testing, but it will make the spec specific to the chosen set.
这是自定义生成器的用武之地:
(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%%.[= 生成纯 "random" 字符串20=]
仅供参考 clojure.spec.test.alpha/check
还需要一张 opts
地图,允许您 override/specify 发电机。