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

Hello,

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 : https://stackoverflow.com/questions/40697841/howto-include-clojure-specd-functions-in-a-test-suite

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:

https://dev.clojure.org/jira/browse/CLJ-2246?focusedCommentId=47934#comment-47934

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.

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