2

我正在尝试使用 clojure.spec进行交互式开发,但函数参数的规范存在问题,无法改变很多。例如,如果一个函数接收一个文件名作为参数,我可以编写以下规范:

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

如果我锻炼它:

(s/exercise-fn `test-fn)

该函数将使用大量随机文件名进行测试,这些文件名将无法读取任何文件。可以将文件名限制为一组有效和无效的文件名。这对于测试来说很好,但它会使规范特定于所选集合。

这不仅是文件名的问题,而且对于任何复杂的数据结构,即使是很小的随机更改也可能使其无用。

我该怎么办?有什么相关的技术或好的做法吗?

4

1 回答 1

4

这对于测试来说很好,但它会使规范特定于所选集合。

这是自定义生成器有用的地方:

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

genclojure.test.check.generators或在哪里clojure.spec.gen.alpha。)

现在您的规范的谓词仍然是string?,但从此规范生成的值将始终来自#{"good.txt" "bad.txt"}. 您可以通过多种方式组成生成器,例如,您可以制作一个生成器,该生成器在大约 50% 的时间里从一个字符串集中获取,并为另外大约 50% 的时间生成一个纯粹的“随机”字符串。

仅供参考,clojure.spec.test.alpha/check还需要一张opts允许您覆盖/指定生成器的地图。

于 2018-04-26T12:23:38.943 回答