如何在 test.check 中生成随机电子邮件地址?

How do I generate random email addresses in test.check?

我正在尝试将 gen/fmap 与两个随机字母数字字符串一起使用。然后我将它们与“@”连接起来并附加“.com”。但是我在语法上苦苦挣扎。

第一次尝试:

(gen/fmap str (gen/string-alphanumeric) "@" (gen/string-alphanumeric) ".com")

但是gen/fmap只需要两个参数。

第二次尝试,我将第二部分分组也不起作用

(gen/fmap str ((gen/string-alphanumeric) "@" (gen/string-alphanumeric) ".com"))

编辑:我有一个部分解决方案。它生成一个电子邮件地址,但@前后的部分是相同的。示例:约翰@john.com

这是部分解决方案

(def gen-full-string
  (gen/such-that #(not= % "") gen/string-alphanumeric))

(gen/fmap #(str % "@" % ".com") gen-full-string) 

我写了 gen-full-string 是因为空字符串 "" 使代码崩溃。由于我已经解析并计划制作验证函数,所以我不关心空字符串。我想测试核心功能而不是边缘情况。一旦我实施验证,我可能会删除 gen-full-string。所以电子邮件生成器将变为 (gen/fmap #(str % "@" % ".com") gen/string-alphanumeric)

我喜欢test.check,但是需要花很多时间去了解细节。我创建了 a helper library 你可能会喜欢。一个例子:

(ns tst.demo.core
  (:use tupelo.core tupelo.test)
  (:require
    [tupelo.gen :as tg]
    [clojure.test.check.properties     :as prop]
  ))

(dospec 9
  (do
    (newline)
    (spy :sample)
    (prop/for-all [w tg/word-alpha+]
      (spyx w))))

(dospec 9
  (do
    (newline)
    (spy :emails)
    (prop/for-all [w1 tg/word-alpha+
                   w2 tg/word-alpha+]
      (let [email-addr (str w1 \@ w2 ".com")]
        (spyx email-addr)
        )
      )))

结果:

-----------------------------------
   Clojure 1.10.3    Java 15.0.2
-----------------------------------

Testing tst.demo.core

:spy--tst.demo.core--line-011 => :sample
w => "b"
w => "lb"
w => "k"
w => "Y"
w => "mMWC"
w => "TzD"
w => "Nq"
w => "wQzPrF"
w => "HqEM"
{:result true, :num-tests 9, :seed 1629153846012, :time-elapsed-ms 1, :test-var "dospec-line-8"}

:spy--tst.demo.core--line-018 => :emails
email-addr => "k@v.com"
email-addr => "M@uL.com"
email-addr => "N@a.com"
email-addr => "OUr@B.com"
email-addr => "O@v.com"
email-addr => "UtZ@ndXS.com"
email-addr => "qhtDt@YLfE.com"
email-addr => "mLw@pFjKJJq.com"
email-addr => "hJ@DkCSnpAG.com"
{:result true, :num-tests 9, :seed 1629153846014, :time-elapsed-ms 1, :test-var "dospec-line-15"}

更多details here. The above example uses my favorite template project.

Gary​​ Fredericks 有一个库 https://github.com/gfredericks/test.chuck 可以将字符串正则表达式生成添加到 Spec。这使您可以根据需要为电子邮件地址使用简单或详细的正则表达式。

当我运行这个脚本时:

clojure -Sdeps '{:deps {org.clojure/test.check {:mvn/version "1.1.0"}}}' /dev/stdin <<EOF

  (require '[clojure.test.check.generators :as gen])

  (def gen-email
    (gen/fmap (fn [[s1 s2]] (format "%s@%s.com" s1 s2))
              (gen/tuple gen/string-alphanumeric
                         gen/string-alphanumeric)))

  (run! prn (gen/sample gen-email))
EOF

我得到这个输出:

"@.com"
"@.com"
"9p@VH.com"
"x1@Ws.com"
"23mF@93.com"
"b40@14.com"
"v0n@5Wskg.com"
"mNo@R85LuM.com"
"@.com"
"8Z84B9U0@f9QSJgM.com"