clojure-spec

2024-11-21T03:54:12.629599Z

Hi all. Wrote my first generative test. Was just wondering if there is a better way to do it than this.

(s/def :test/data-point (s/tuple inst? (s/and number? pos?)))
(s/def :test/data
  (s/coll-of :test/data-point :kind vector? :distinct true :min-count 0 :max-count 500))

(doseq [sample (gen/sample (s/gen :test/level-data) 500)]
  (try
    (transcriptor/check!
      :some.domain/spec
      (my-test-func sample))
    (catch Throwable e
      (throw (ex-info "Oh no" {:sample sample} e)))))

lassemaatta 2024-11-21T05:21:37.592319Z

I think you're sort of halfway there. Running gen/sample manually like that will certainly produce values, but you don't benefit from shrinking when your test fails. Instead I'd look into defspec (https://clojure.org/guides/test_check_beginner#_defspec); You supply your generators and defspec will generate the values and perform shrinking if the test case fails and give you the smallest example of a failing input.

lassemaatta 2024-11-21T05:32:19.388639Z

And of course if you can describe your functions inputs and outputs with s/fdef then you can leverage clojure.spec.test.alpha/check to check the function (https://clojure.org/guides/spec#_testing).

2024-11-21T06:09:02.155949Z

Ah ok I think the s/fdef is the place to start and then take it from there