Search code examples
unit-testingtestingclojureproperty-based-testingtest.check

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


I'm trying to use gen/fmap with two random alphanumeric strings. Then I concatenate them with "@" and append ".com". But I'm struggling with the syntax.

First attempt:

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

But gen/fmap only takes two arguments.

Second attempt, where I group the second part doesn't work either

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

EDIT: I have a partial solution. It generates an email address, but the part before and after the @ are the same. Example: john@john.com

This is the partial solution

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

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

I wrote gen-full-string because the empty string "" was crashing the code. Since I have parsing and plan to make validation functions, I didn't care about the empty string. I wanted to test core functionality not edge cases. Once I implement validation, I will probably remove gen-full-string. So the email generator would become (gen/fmap #(str % "@" % ".com") gen/string-alphanumeric)


Solution

  • When I run this script:

    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
    

    I get this output:

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