Matt Fenwick
Matt Fenwick

Reputation: 49115

How do I expect failure in a unit test?

We're writing unit tests for our code in Clojure using clojure.test.

Some of our tests ignore the API and purposely break the code, in order to serve as documentation for latent deficiencies in the code.

However, we want to distinguish between failures of these tests, and failures of normal tests.

We haven't seen any suggestions in the clojure.test documentation -- only (is (thrown? ...)), which of course doesn't do what we need.

Any suggestions? Basically, we're looking for something like (is (not <condition>)), except that the test framework should record an expected failure -- something like this.

Upvotes: 10

Views: 1143

Answers (4)

hsestupin
hsestupin

Reputation: 1115

As @andy said you can rebind report function.

(defmacro should-fail [body]
  `(let [report-type# (atom nil)]
     (binding [clojure.test/report #(reset! report-type# (:type %))]
       ~body)
     (testing "should fail"
       (is (= @report-type# :fail )))))

And use this macro like this:

(should-fail (is (= 1 2)))

That will be successful passing test.

Upvotes: 3

Alex
Alex

Reputation: 13961

A little late to the party, I know, but if you're using Leiningen you could use test selectors to exclude expected failures from the "normal" build. In your project.clj:

:test-selectors {:default #(not :expected-failure %)
                 :expected-failure :expected-failure}

Then write your test as:

(deftest ^:expected-failure test-with-expected-failure ...)

Calling lein test will run only those tests without the :expected-failure metadata. Calling lein test :expected-failure will run your expected failure tests. Maybe not quite what you were hoping for, but IMHO better than having to use thrown? all over the place. At least this way expected failures are explicitly documented in the code and won't interfere with the build.

Upvotes: 0

river
river

Reputation: 6282

Rebind the report function as documented in clojure.test. From there you can change how the 'failure' is handled and reported on.

Upvotes: 0

Arthur Ulfeldt
Arthur Ulfeldt

Reputation: 91617

I have made tests throw an exception when they 'fail' like this, and then used thrown? to test if the exception arrives as expected. There very well may exist a more elegant way, but this gets the job done.

Upvotes: 3

Related Questions