Clojure test.check生成特定长度的字符串

Clojure test.check生成特定长度的字符串,clojure,test.check,Clojure,Test.check,在使用test.check时,我需要一个特定长度字符串的生成器。电话号码、邮政编码、社会保险号码都是此类数据的示例。虽然示例似乎只是数字,但我的问题是一般的字符串。此函数将生成一个给定长度的字符串,其中包含给定字母表中的字符(可选)。如果您没有将任何字母表作为参数传递,那么将使用默认值,当然您可以更改它 (defn generate-string ([length] (generate-string length (map char (range 49 127

在使用test.check时,我需要一个特定长度字符串的生成器。电话号码、邮政编码、社会保险号码都是此类数据的示例。虽然示例似乎只是数字,但我的问题是一般的字符串。

此函数将生成一个给定长度的字符串,其中包含给定字母表中的字符(可选)。如果您没有将任何字母表作为参数传递,那么将使用默认值,当然您可以更改它

(defn generate-string 
  ([length]
   (generate-string length
            (map char (range 49 127))))
  ([length alphabet]
   (apply str (take length (repeatedly #(rand-nth alphabet))))))
示例:

(generate-string 7 [\a \b \c])
"bacacbb"

(generate-string 10)
"mxqE<OKH3L"
(生成字符串7[\a\b\c])
“bacacbb”
(生成字符串10)

“mxqE给定
长度
下面的生成器生成随机字符串:

(gen/fmap #(apply str %) 
          (gen/vector gen/char-alpha length))
(gen/vector gen/char alpha length)
生成字符序列,然后
fmap
将其转换为字符串:

(apply str [\a \b]) ;; => "ab"
如果需要自定义的
字母表
(比如
[\a\b\c]
),则
gen/char alpha
可以用以下内容替代:

(gen/elements alphabet)

对于更复杂的生成器,如格式化的电话号码,与手动组合官方生成器相比,正则表达式中的“s
字符串”可能是更好的选择。

您可以使用更原始的生成器来快速构建一个这样做的生成器:

对于最小值和最大值之间的字母数字字符串:

(sgen/fmap str/join (sgen/vector (sgen/char-alphanumeric) min max))
用于精确给定长度的字母数字字符串

(sgen/fmap str/join (sgen/vector (sgen/char-alphanumeric) length))
您可以根据您需要的字符范围修改
(sgen/char alphanumeric)
,例如带有字母数字、下划线和破折号字符的最小/最大字符串,每个字符显示的频率不同:

(sgen/fmap str/join
                (sgen/vector
                 (sgen/frequency [[99 (sgen/char-alphanumeric)]
                                  [1 (sgen/elements #{"_" "-"})]])
                 min max))

感谢您指出test.chuck具有此功能和其他良好功能。@MSmith我特别喜欢
检查
为生成性测试测试
),以防其他人使用最新版本的test.check找到此功能。正确的版本是:
(gen/fmap#(apply str%)(gen/vector(gen/char alpha)length))
。注意
gen/char alpha
周围的括号;没有括号,您将看到“断言失败:向量的第一个参数必须是生成器”“。虽然这是创建字符串的一个很好的示例,但它不是test.check生成器。是否有方法同时为固定长度字符串指定规范和生成器?例如,我需要指定一个6位数的数字串(0-9)。@PetrusTheron不确定你在问什么。您可以使用s/with gen将自定义生成器附加到等级库,这是您想要的吗?