Integrate functions specs (`fdef`) and clojure.test


I’ve specified my function with clojure.spec/fdef. Now I want to exercise the functions with the spec, in a way that’s integrated with clojure.test. I’ve found some code some time ago, it looks like this :

(defn summarize-results' [spec-check]
  (map (comp #(pprint/write % :stream nil) stest/abbrev-result) spec-check))

(def check-opts {:clojure.spec.test.check/opts {:num-tests 500}})

(defn check' [sym]
  (let [check-result (stest/check sym check-opts)]
    (is (nil? (-> check-result first :failure)) (summarize-results' check-result))))

;; generated tests
(deftest my-function-gen-test
  (check' 'my.ns/my-function))

It kinda worked. Now that I updated to Clojure 1.9 (and removed clojure.spec as an explicit dependency, don’t ask me why I did this at the beginning…) this “trick” doesn’t work any more, or my tests are failing. I have no idea why because the output is quite opaque :

expected: (nil? (-> check-result first :failure))
  actual: (not (nil? false))

The official guide seems targetted at using the REPL. I even opened a ticket in the JIRA because I thought there was a bug, and never understood the answer :sweat_smile:

The question : when you fdef a function, how do you automate the tests based on the provided function spec ?

Thanks (a lot!) in advance, I’ve struggling with this.

I’ve (almost) fixed my problem :

  • one of the change I introduced was keyword args, and I had not spec'ed them correctly. For optional keywords args here’s the correct syntax (AFAICT) : (s/fdef my-function :args (s/cat :kwargs (s/? (s/keys* :opt-un [::a ::b]))))
  • I also simplified the summarize-results' function : (defn summarize-results' [spec-check] (-> spec-check first :clojure.spec.test.check/ret :result-data))

Posting here in case it helps someone else.

Now I need to definitely fix my tests, weird error not related to specs…

BTW, I realized 2 things about my post :

  • Is there a way to mark a post as “solved” in discourse ?
  • I think I could/should have posted this to Stack Overflow. Gonna do it know, I’m curious about how people do it.

Someone already had the same question :

I agree, this is better addressed in Stack Overflow. Thanks for moving it there. It looks like the behavior of stest/check may have changed in that the results don’t look the same. This is something I rely on as well, so I’m going to dig into it.

I’d be happy to have your answer.

I don’t have enough karma on SO to comment there: it looks like you’ve bumped into the root cause of this before, assuming you’re the same Khalid Jebbari:

I’ve provided a work-around there. Hopefully we can get this a resolution to this issue, as I’m sure others will get bitten by this.

I’m not sure what changed: it could be test.check rather than spec.alpha. I didn’t go too far down the rabbit hole of looking for the regression (if there has been one) before just trying to fix it.

1 Like

Yes I’m Khalid Jebbari. Thanks Michael, I’ve answered there and found a solution thanks to you.

You can mark replies as answer by clicking on the little checkbox that appears when clicking the three dots in the bottom right of each reply. :slight_smile:

Muchas gracias amigo

1 Like