diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index b5a20970..7008ad1d 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -43,7 +43,7 @@ jobs:
         with:
           lein: latest
       - name: Run tests
-        run: lein do clean, all midje, all check
+        run: lein do clean, all test, all check
   deploy:
     concurrency: deploy
     needs: test
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c10479db..7e363a89 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ See also: [compojure-api 1.1.x changelog](./CHANGELOG-1.1.x.md)
 * Add static context optimization coach
   * `-Dcompojure.api.meta.static-context-coach=print` to print hints
   * `-Dcompojure.api.meta.static-context-coach=assert` to assert hints
+* port unit tests from midje to clojure.test
 
 ## 2.0.0-alpha31 (2019-12-20)
 
diff --git a/project.clj b/project.clj
index da6f6156..bfc30239 100644
--- a/project.clj
+++ b/project.clj
@@ -30,14 +30,12 @@
                                       [reloaded.repl "0.2.4"]
                                       [com.stuartsierra/component "0.4.0"]]}
              :dev {:plugins [[lein-clojars "0.9.1"]
-                             [lein-midje "3.2.1"]
                              [lein-ring "0.12.5"]
                              [funcool/codeina "0.5.0"]]
                    :dependencies [[org.clojure/clojure "1.10.1"]
                                   [org.clojure/core.async "0.6.532"]
                                   [javax.servlet/javax.servlet-api "4.0.1"]
                                   [peridot "0.5.2"]
-                                  [midje "1.9.9"]
                                   [com.rpl/specter "1.1.3"]
                                   [com.stuartsierra/component "0.4.0"]
                                   [expound "0.8.2"]
@@ -90,7 +88,7 @@
   :aliases {"all" ["with-profile" "dev:dev,async"]
             "start-thingie" ["run"]
             "aot-uberjar" ["with-profile" "uberjar" "do" "clean," "ring" "uberjar"]
-            "test-ancient" ["midje"]
+            "test-ancient" ["test"]
             "perf" ["with-profile" "default,dev,perf"]
             "deploy!" ^{:doc "Recompile sources, then deploy if tests succeed."}
-            ["do" ["clean"] ["midje"] ["deploy" "clojars"]]})
+            ["do" ["clean"] ["test"] ["deploy" "clojars"]]})
diff --git a/test/compojure/api/coercion/schema_coercion_test.clj b/test/compojure/api/coercion/schema_coercion_test.clj
index 6442d3da..cc9c0247 100644
--- a/test/compojure/api/coercion/schema_coercion_test.clj
+++ b/test/compojure/api/coercion/schema_coercion_test.clj
@@ -1,6 +1,6 @@
 (ns compojure.api.coercion.schema-coercion-test
-  (:require [midje.sweet :refer :all]
-            [schema.core :as s]
+  (:require [schema.core :as s]
+            [clojure.test :refer [deftest is testing]]
             [compojure.api.sweet :refer :all]
             [compojure.api.test-utils :refer :all]
             [compojure.api.request :as request]
@@ -10,66 +10,69 @@
             [compojure.api.coercion.core :as cc])
   (:import (schema.utils ValidationError NamedError)))
 
-(fact "stringify-error"
-  (fact "ValidationError"
-    (class (s/check s/Int "foo")) => ValidationError
-    (cs/stringify (s/check s/Int "foo")) => "(not (integer? \"foo\"))"
-    (cs/stringify (s/check {:foo s/Int} {:foo "foo"})) => {:foo "(not (integer? \"foo\"))"})
-  (fact "NamedError"
-    (class (s/check (s/named s/Int "name") "foo")) => NamedError
-    (cs/stringify (s/check (s/named s/Int "name") "foo")) => "(named (not (integer? \"foo\")) \"name\")")
-  (fact "Schema"
-    (cs/stringify {:total (s/constrained s/Int pos?)}) => {:total "(constrained Int pos?)"}))
+(deftest stringify-error-test
+  (testing "ValidationError"
+    (is (= ValidationError (class (s/check s/Int "foo"))))
+    (is (= "(not (integer? \"foo\"))" (cs/stringify (s/check s/Int "foo"))))
+    (is (= {:foo "(not (integer? \"foo\"))"} (cs/stringify (s/check {:foo s/Int} {:foo "foo"})))))
+  (testing "NamedError"
+    (is (= NamedError (class (s/check (s/named s/Int "name") "foo"))))
+    (is (= "(named (not (integer? \"foo\")) \"name\")" (cs/stringify (s/check (s/named s/Int "name") "foo")))))
+  (testing "Schema"
+    (is (= {:total "(constrained Int pos?)"} (cs/stringify {:total (s/constrained s/Int pos?)})))))
 
-(s/defschema Schema {:kikka s/Keyword})
+(s/defschema Schema2 {:kikka s/Keyword})
 
 (def valid-value {:kikka :kukka})
 (def invalid-value {:kikka "kukka"})
 
-(fact "request-coercion"
-  (let [c! #(coercion/coerce-request! Schema :body-params :body false false %)]
+(deftest request-coercion-test
+  (let [c! #(coercion/coerce-request! Schema2 :body-params :body false false %)]
 
-    (fact "default coercion"
-      (c! {:body-params valid-value}) => valid-value
-      (c! {:body-params invalid-value}) => throws
+    (testing "default coercion"
+      (is (= valid-value (c! {:body-params valid-value})))
+      (is (thrown? Exception (c! {:body-params invalid-value})))
       (try
         (c! {:body-params invalid-value})
         (catch Exception e
-          (ex-data e) => (just {:type :compojure.api.exception/request-validation
-                                :coercion (coercion/resolve-coercion :schema)
-                                :in [:request :body-params]
-                                :schema Schema
-                                :value invalid-value
-                                :errors anything
-                                :request {:body-params {:kikka "kukka"}}}))))
-
-    (fact ":schema coercion"
-      (c! {:body-params valid-value
-           ::request/coercion :schema}) => valid-value
-      (c! {:body-params invalid-value
-           ::request/coercion :schema}) => throws)
-
-    (fact "format-based coercion"
-      (c! {:body-params valid-value
-           :muuntaja/request {:format "application/json"}}) => valid-value
-      (c! {:body-params invalid-value
-           :muuntaja/request {:format "application/json"}}) => valid-value)
-
-    (fact "no coercion"
-      (c! {:body-params valid-value
-           ::request/coercion nil
-           :muuntaja/request {:format "application/json"}}) => valid-value
-      (c! {:body-params invalid-value
-           ::request/coercion nil
-           :muuntaja/request {:format "application/json"}}) => invalid-value)))
+          (is (contains? (ex-data e) :errors))
+          (is (= {:type :compojure.api.exception/request-validation
+                  :coercion (coercion/resolve-coercion :schema)
+                  :in [:request :body-params]
+                  :schema Schema2
+                  :value invalid-value
+                  :request {:body-params {:kikka "kukka"}}}
+                 (select-keys (ex-data e)
+                              [:type :coercion :in :schema :value :request]))))))
+
+    (testing ":schema coercion"
+      (is (= valid-value (c! {:body-params valid-value
+                              ::request/coercion :schema})))
+      (is (thrown? Exception (c! {:body-params invalid-value
+                                  ::request/coercion :schema}))))
+
+    (testing "format-based coercion"
+      (is (= valid-value
+             (c! {:body-params valid-value
+                  :muuntaja/request {:format "application/json"}})))
+      (is (= valid-value
+             (c! {:body-params invalid-value
+                  :muuntaja/request {:format "application/json"}}))))
+
+    (testing "no coercion"
+      (is (= valid-value
+             (c! {:body-params valid-value
+                  ::request/coercion nil
+                  :muuntaja/request {:format "application/json"}})))
+      (is (= invalid-value
+             (c! {:body-params invalid-value
+                  ::request/coercion nil
+                  :muuntaja/request {:format "application/json"}}))))))
 
 (defn ok [body]
   {:status 200, :body body})
 
-(defn ok? [body]
-  (contains (ok body)))
-
-(def responses {200 {:schema Schema}})
+(def responses {200 {:schema Schema2}})
 
 (def custom-coercion
   (cs/->SchemaCoercion
@@ -77,62 +80,81 @@
     (-> cs/default-options
         (assoc-in [:response :formats "application/json"] cs/json-coercion-matcher))))
 
-(fact "response-coercion"
-  (let [c! coercion/coerce-response!]
+(deftest response-coercion-test
+  (let [c! coercion/coerce-response!
+        request {}]
 
-    (fact "default coercion"
-      (c! ..request.. (ok valid-value) responses) => (ok? valid-value)
-      (c! ..request.. (ok invalid-value) responses) => (throws)
+    (testing "default coercion"
+      (is (= (ok valid-value)
+             (select-keys (c! request (ok valid-value) responses)
+                          [:status :body])))
+      (is (thrown? Exception (c! request (ok invalid-value) responses)))
       (try
-        (c! ..request.. (ok invalid-value) responses)
+        (c! request (ok invalid-value) responses)
         (catch Exception e
-          (ex-data e) => (contains {:type :compojure.api.exception/response-validation
-                                    :coercion (coercion/resolve-coercion :schema)
-                                    :in [:response :body]
-                                    :schema Schema
-                                    :value invalid-value
-                                    :errors anything
-                                    :request ..request..}))))
-
-    (fact ":schema coercion"
-      (fact "default coercion"
-        (c! {::request/coercion :schema}
-            (ok valid-value)
-            responses) => (ok? valid-value)
-        (c! {::request/coercion :schema}
-            (ok invalid-value)
-            responses) => throws))
-
-    (fact "format-based custom coercion"
-      (fact "request-negotiated response format"
-        (c! irrelevant
-            (ok invalid-value)
-            responses) => throws
-        (c! {:muuntaja/response {:format "application/json"}
-             ::request/coercion custom-coercion}
-            (ok invalid-value)
-            responses) => (ok? valid-value)))
-
-    (fact "no coercion"
-      (c! {::request/coercion nil}
-          (ok valid-value)
-          responses) => (ok? valid-value)
-      (c! {::request/coercion nil}
-          (ok invalid-value)
-          responses) => (ok? invalid-value))))
+          (is (contains? (ex-data e) :errors))
+          (is (= {:type :compojure.api.exception/response-validation
+                  :coercion (coercion/resolve-coercion :schema)
+                  :in [:response :body]
+                  :schema Schema2
+                  :value invalid-value
+                  :request request}
+                 (select-keys (ex-data e)
+                              [:type :coercion :in :schema :value :request]))))))
+
+    (testing ":schema coercion"
+      (testing "default coercion"
+        (is (= (ok valid-value)
+               (select-keys
+                 (c! {::request/coercion :schema}
+                     (ok valid-value)
+                     responses)
+                 [:status :body])))
+        (is (thrown? Exception
+                     (c! {::request/coercion :schema}
+                         (ok invalid-value)
+                         responses)))))
+
+    (testing "format-based custom coercion"
+      (testing "request-negotiated response format"
+        (is (thrown? Exception
+                     (c! {}
+                         (ok invalid-value)
+                         responses)))
+        (is (= (ok valid-value)
+               (select-keys
+                 (c! {:muuntaja/response {:format "application/json"}
+                      ::request/coercion custom-coercion}
+                     (ok invalid-value)
+                     responses)
+                 [:status :body])))))
+
+    (testing "no coercion"
+      (is (= (ok valid-value)
+             (select-keys
+               (c! {::request/coercion nil}
+                   (ok valid-value)
+                   responses)
+               [:status :body])))
+      (is (= (ok invalid-value)
+             (select-keys
+               (c! {::request/coercion nil}
+                   (ok invalid-value)
+                   responses)
+               [:status :body]))))))
 
 (s/defschema X s/Int)
 (s/defschema Y s/Int)
 (s/defschema Total (s/constrained s/Int pos? 'positive-int))
-(s/defschema Schema {:x X, :y Y})
+(s/defschema Schema1 {:x X, :y Y})
 
-(facts "apis"
+(deftest apis-test
   (let [app (api
               {:swagger {:spec "/swagger.json"}
                :coercion :schema}
 
               (POST "/body" []
-                :body [{:keys [x y]} Schema]
+                :body [{:keys [x y]} Schema1]
                 (ok {:total (+ x y)}))
 
               (POST "/body-map" []
@@ -140,7 +162,7 @@
                 (ok {:total (+ x (or y 0))}))
 
               (GET "/query" []
-                :query [{:keys [x y]} Schema]
+                :query [{:keys [x y]} Schema1]
                 (ok {:total (+ x y)}))
 
               (GET "/query-params" []
@@ -162,7 +184,7 @@
 
               (context "/resource" []
                 (resource
-                  {:get {:parameters {:query-params Schema}
+                  {:get {:parameters {:query-params Schema1}
                          :responses {200 {:schema {:total Total}}}
                          :handler (fn [{{:keys [x y]} :query-params}]
                                     (ok {:total (+ x y)}))}
@@ -171,88 +193,94 @@
                           :handler (fn [{{:keys [x y]} :body-params}]
                                      (ok {:total (+ x (or y 0))}))}})))]
 
-    (fact "query"
+    (testing "query"
       (let [[status body] (get* app "/query" {:x "1", :y 2})]
-        status => 200
-        body => {:total 3})
+        (is (= 200 status))
+        (is (= {:total 3} body)))
       (let [[status body] (get* app "/query" {:x "1", :y "kaks"})]
-        status => 400
-        body => {:coercion "schema"
-                 :in ["request" "query-params"]
-                 :errors {:y "(not (integer? \"kaks\"))"}
-                 :schema "{:x Int, :y Int}"
-                 :type "compojure.api.exception/request-validation"
-                 :value {:x "1", :y "kaks"}}))
-
-    (fact "body"
+        (is (= 400 status))
+        (is (= {:coercion "schema"
+                :in ["request" "query-params"]
+                :errors {:y "(not (integer? \"kaks\"))"}
+                :schema "{:x Int, :y Int}"
+                :type "compojure.api.exception/request-validation"
+                :value {:x "1", :y "kaks"}}
+               body))))
+
+    (testing "body"
       (let [[status body] (post* app "/body" (json-string {:x 1, :y 2, #_#_:z 3}))]
-        status => 200
-        body => {:total 3}))
+        (is (= 200 status))
+        (is (= {:total 3} body))))
 
-    (fact "body-map"
+    (testing "body-map"
       (let [[status body] (post* app "/body-map" (json-string {:x 1, :y 2}))]
-        status => 200
-        body => {:total 3})
+        (is (= 200 status))
+        (is (= {:total 3} body)))
       (let [[status body] (post* app "/body-map" (json-string {:x 1}))]
-        status => 200
-        body => {:total 1}))
+        (is (= 200 status))
+        (is (= {:total 1} body))))
 
-    (fact "body-string"
+    (testing "body-string"
       (let [[status body] (post* app "/body-string" (json-string "kikka"))]
-        status => 200
-        body => {:body "kikka"}))
+        (is (= 200 status))
+        (is (= {:body "kikka"} body))))
 
-    (fact "query-params"
+    (testing "query-params"
       (let [[status body] (get* app "/query-params" {:x "1", :y 2})]
-        status => 200
-        body => {:total 3})
+        (is (= 200 status))
+        (is (= {:total 3} body)))
       (let [[status body] (get* app "/query-params" {:x "1", :y "a"})]
-        status => 400
-        body => (contains {:coercion "schema"
-                           :in ["request" "query-params"]})))
+        (is (= 400 status))
+        (is (= {:coercion "schema"
+                :in ["request" "query-params"]}
+               (select-keys body [:coercion :in])))))
 
-    (fact "body-params"
+    (testing "body-params"
       (let [[status body] (post* app "/body-params" (json-string {:x 1, :y 2}))]
-        status => 200
-        body => {:total 3})
+        (is (= 200 status))
+        (is (= {:total 3} body)))
       (let [[status body] (post* app "/body-params" (json-string {:x 1}))]
-        status => 200
-        body => {:total 1})
+        (is (= 200 status))
+        (is (= {:total 1} body)))
       (let [[status body] (post* app "/body-params" (json-string {:x "1"}))]
-        status => 400
-        body => (contains {:coercion "schema"
-                           :in ["request" "body-params"]})))
+        (is (= 400 status))
+        (is (= {:coercion "schema"
+                :in ["request" "body-params"]}
+               (select-keys body [:coercion :in])))))
 
-    (fact "response"
+    (testing "response"
       (let [[status body] (get* app "/response" {:x 1, :y 2})]
-        status => 200
-        body => {:total 3})
+        (is (= 200 status))
+        (is (= {:total 3} body)))
       (let [[status body] (get* app "/response" {:x -1, :y -2})]
-        status => 500
-        body => (contains {:coercion "schema"
-                           :in ["response" "body"]})))
+        (is (= 500 status))
+        (is (= {:coercion "schema"
+                :in ["response" "body"]}
+               (select-keys body [:coercion :in])))))
 
-    (fact "resource"
-      (fact "parameters as specs"
+    (testing "resource"
+      (testing "parameters as specs"
         (let [[status body] (get* app "/resource" {:x 1, :y 2})]
-          status => 200
-          body => {:total 3})
+          (is (= 200 status))
+          (is (= {:total 3} body)))
         (let [[status body] (get* app "/resource" {:x -1, :y -2})]
-          status => 500
-          body => (contains {:coercion "schema"
-                             :in ["response" "body"]})))
+          (is (= 500 status))
+          (is (= {:coercion "schema"
+                  :in ["response" "body"]}
+                 (select-keys body [:coercion :in])))))
 
-      (fact "parameters as data-specs"
+      (testing "parameters as data-specs"
         (let [[status body] (post* app "/resource" (json-string {:x 1, :y 2}))]
-          status => 200
-          body => {:total 3})
+          (is (= 200 status))
+          (is (= {:total 3} body)))
         (let [[status body] (post* app "/resource" (json-string {:x 1}))]
-          status => 200
-          body => {:total 1})
+          (is (= 200 status))
+          (is (= {:total 1} body)))
         (let [[status body] (post* app "/resource" (json-string {:x -1, :y -2}))]
-          status => 500
-          body => (contains {:coercion "schema"
-                             :in ["response" "body"]}))))
+          (is (= 500 status))
+          (is (= {:coercion "schema"
+                  :in ["response" "body"]}
+                 (select-keys body [:coercion :in]))))))
 
-    (fact "generates valid swagger spec"
-      (validator/validate app) =not=> (throws))))
+    (testing "generates valid swagger spec"
+      (is (validator/validate app)))))
diff --git a/test/compojure/api/coercion_test.clj b/test/compojure/api/coercion_test.clj
index f12e08e4..811a91fd 100644
--- a/test/compojure/api/coercion_test.clj
+++ b/test/compojure/api/coercion_test.clj
@@ -1,23 +1,22 @@
 (ns compojure.api.coercion-test
   (:require [compojure.api.sweet :refer :all]
             [compojure.api.test-utils :refer :all]
-            [midje.sweet :refer :all]
+            [clojure.test :refer [deftest]]
+            [clojure.test :refer [deftest testing is]]
             [ring.util.http-response :refer :all]
             [clojure.core.async :as a]
             [schema.core :as s]
             [compojure.api.coercion.schema :as cs]))
 
-(defn has-body [expected]
-  (fn [value]
-    (= (second value) expected)))
+(defn is-has-body [expected value]
+  (is (= (second value) expected)))
 
-(defn fails-with [expected-status]
-  (fn [[status body]]
-    (and (= status expected-status)
-         (every? (partial contains? body) [:type :coercion :in :value :schema :errors]))))
+(defn is-fails-with [expected-status [status body]]
+  (is (= status expected-status))
+  (is (every? (partial contains? body) [:type :coercion :in :value :schema :errors])))
 
-(facts "schema coercion"
-  (fact "response schemas"
+(deftest schema-coercion-test
+  (testing "response schemas"
     (let [r-200 (GET "/" []
                   :query-params [{value :- s/Int nil}]
                   :responses {200 {:schema {:value s/Str}}}
@@ -31,133 +30,133 @@
                           :responses {200 {:schema {:value s/Str}}
                                       :default {:schema {:value s/Int}}}
                           (ok {:value (or value "123")}))]
-      (fact "200"
-        (get* (api r-200) "/") => (has-body {:value "123"})
-        (get* (api r-200) "/" {:value 123}) => (fails-with 500))
-
-      (fact "exception data"
-        (get* (api r-200) "/" {:value 123})
-        => (contains
-             [500
-              {:type "compojure.api.exception/response-validation"
-               :coercion "schema",
-               :in ["response" "body"],
-               :value {:value 123},
-               :schema "{:value java.lang.String}",
-               :errors {:value "(not (instance? java.lang.String 123))"}}]))
-
-      (fact ":default"
-        (get* (api r-default) "/") => (has-body {:value "123"})
-        (get* (api r-default) "/" {:value 123}) => (fails-with 500))
-
-      (fact ":default"
-        (get* (api r-200-default) "/") => (has-body {:value "123"})
-        (get* (api r-200-default) "/" {:value 123}) => (fails-with 500))))
-
-  (fact "custom coercion"
-
-    (fact "response coercion"
+      (testing "200"
+        (is-has-body {:value "123"} (get* (api r-200) "/"))
+        (is-fails-with 500 (get* (api r-200) "/" {:value 123})))
+
+      (testing "exception data"
+        (let [ex (get* (api r-200) "/" {:value 123})]
+          (is (= 500 (first ex)))
+          (is (= {:type "compojure.api.exception/response-validation"
+                  :coercion "schema",
+                  :in ["response" "body"],
+                  :value {:value 123},
+                  :schema "{:value java.lang.String}",
+                  :errors {:value "(not (instance? java.lang.String 123))"}}
+                 (select-keys (second ex) [:type :coercion :in :value :schema :errors])))))
+
+      (testing ":default"
+        (is-has-body {:value "123"} (get* (api r-default) "/"))
+        (is-fails-with 500 (get* (api r-default) "/" {:value 123})))
+
+      (testing ":default"
+        (is-has-body {:value "123"} (get* (api r-200-default) "/"))
+        (is-fails-with 500 (get* (api r-200-default) "/" {:value 123})))))
+
+  (testing "custom coercion"
+
+    (testing "response coercion"
       (let [ping-route (GET "/ping" []
                          :return {:pong s/Str}
                          (ok {:pong 123}))]
 
-        (fact "by default, applies response coercion"
+        (testing "by default, applies response coercion"
           (let [app (api
                       ping-route)]
-            (get* app "/ping") => (fails-with 500)))
+            (is-fails-with 500 (get* app "/ping"))))
 
-        (fact "response-coercion can be disabled"
-          (fact "separately"
+        (testing "response-coercion can be disabled"
+          (testing "separately"
             (let [app (api
                         {:coercion (cs/create-coercion (dissoc cs/default-options :response))}
                         ping-route)]
               (let [[status body] (get* app "/ping")]
-                status => 200
-                body => {:pong 123})))
-          (fact "all coercion"
+                (is (= 200 status))
+                (is (= {:pong 123} body)))))
+          (testing "all coercion"
             (let [app (api
                         {:coercion nil}
                         ping-route)]
               (let [[status body] (get* app "/ping")]
-                status => 200
-                body => {:pong 123}))))
+                (is (= 200 status))
+                (is (= {:pong 123} body))))))
 
-        (fact "coercion for async handlers"
+        (testing "coercion for async handlers"
           (binding [*async?* true]
-            (fact "successful"
+            (testing "successful"
               (let [app (api (GET "/async" []
                                :return s/Str
                                (a/go (ok "abc"))))]
-                (get* app "/async") => (has-body "abc")))
-            (fact "failing"
+                (is-has-body "abc" (get* app "/async"))))
+            (testing "failing"
               (let [app (api (GET "/async" []
                                :return s/Int
                                (a/go (ok "foo"))))]
-                (get* app "/async") => (fails-with 500)))))))
+                (is-fails-with 500 (get* app "/async"))))))))
 
-    (fact "body coersion"
+    (testing "body coersion"
       (let [beer-route (POST "/beer" []
                          :body [body {:beers #{(s/enum "ipa" "apa")}}]
                          (ok body))]
 
-        (fact "by default, applies body coercion (to set)"
+        (testing "by default, applies body coercion (to set)"
           (let [app (api
                       beer-route)]
             (let [[status body] (post* app "/beer" (json-string {:beers ["ipa" "apa" "ipa"]}))]
-              status => 200
-              body => {:beers ["ipa" "apa"]})))
+              (is (= 200 status))
+              (is (= {:beers ["ipa" "apa"]} body)))))
 
-        (fact "body-coercion can be disabled"
+        (testing "body-coercion can be disabled"
           (let [no-body-coercion (cs/create-coercion (dissoc cs/default-options :body))
                 app (api
                       {:coercion no-body-coercion}
                       beer-route)]
             (let [[status body] (post* app "/beer" (json-string {:beers ["ipa" "apa" "ipa"]}))]
-              status => 200
-              body => {:beers ["ipa" "apa" "ipa"]}))
+              (is (= 200 status))
+              (is (= {:beers ["ipa" "apa" "ipa"]} body))))
           (let [app (api
                       {:coercion nil}
                       beer-route)]
             (let [[status body] (post* app "/beer" (json-string {:beers ["ipa" "apa" "ipa"]}))]
-              status => 200
-              body => {:beers ["ipa" "apa" "ipa"]})))
+              (is (= 200 status))
+              (is (= {:beers ["ipa" "apa" "ipa"]} body)))))
 
-        (fact "body-coercion can be changed"
+        (testing "body-coercion can be changed"
           (let [nop-body-coercion (cs/create-coercion (assoc cs/default-options :body {:default (constantly nil)}))
                 app (api
                       {:coercion nop-body-coercion}
                       beer-route)]
-            (post* app "/beer" (json-string {:beers ["ipa" "apa" "ipa"]})) => (fails-with 400)))))
+            (is-fails-with 400 (post* app "/beer" (json-string {:beers ["ipa" "apa" "ipa"]})))))))
 
-    (fact "query coercion"
+    (testing "query coercion"
       (let [query-route (GET "/query" []
                           :query-params [i :- s/Int]
                           (ok {:i i}))]
 
-        (fact "by default, applies query coercion (string->int)"
+        (testing "by default, applies query coercion (string->int)"
           (let [app (api
                       query-route)]
             (let [[status body] (get* app "/query" {:i 10})]
-              status => 200
-              body => {:i 10})))
+              (is (= 200 status))
+              (is (= {:i 10} body)))))
 
-        (fact "query-coercion can be disabled"
+        (testing "query-coercion can be disabled"
           (let [no-query-coercion (cs/create-coercion (dissoc cs/default-options :string))
                 app (api
                       {:coercion no-query-coercion}
                       query-route)]
             (let [[status body] (get* app "/query" {:i 10})]
-              status => 200
-              body => {:i "10"})))
+              (is (= 200 status))
+              (is (= {:i "10"} body)))))
 
-        (fact "query-coercion can be changed"
+        (testing "query-coercion can be changed"
           (let [nop-query-coercion (cs/create-coercion (assoc cs/default-options :string {:default (constantly nil)}))
                 app (api
                       {:coercion nop-query-coercion}
                       query-route)]
-            (get* app "/query" {:i 10}) => (fails-with 400)))))
+            (is-fails-with 400 (get* app "/query" {:i 10}))))))
 
-    (fact "route-specific coercion"
+    (testing "route-specific coercion"
       (let [app (api
                   (GET "/default" []
                     :query-params [i :- s/Int]
@@ -171,62 +170,62 @@
                     :query-params [i :- s/Int]
                     (ok {:i i})))]
 
-        (fact "default coercion"
+        (testing "default coercion"
           (let [[status body] (get* app "/default" {:i 10})]
-            status => 200
-            body => {:i 10}))
-
-        (fact "disabled coercion"
-          (get* app "/disabled-coercion" {:i 10}) => (fails-with 400))
-
-        (fact "exception data"
-          (get* app "/disabled-coercion" {:i 10})
-          => (contains
-               [400
-                (contains
-                  {:type "compojure.api.exception/request-validation"
-                   :coercion "schema",
-                   :in ["request" "query-params"],
-                   :value {:i "10"}
-                   :schema "{Keyword Any, :i Int}",
-                   :errors {:i "(not (integer? \"10\"))"}})]))
-
-        (fact "no coercion"
+            (is (= 200 status))
+            (is (= {:i 10} body))))
+
+        (testing "disabled coercion"
+          (is-fails-with 400 (get* app "/disabled-coercion" {:i 10})))
+
+        (testing "exception data"
+          (let [ex (get* app "/disabled-coercion" {:i 10})]
+            (is (= 400 (first ex)))
+            (is (= {:type "compojure.api.exception/request-validation"
+                    :coercion "schema",
+                    :in ["request" "query-params"],
+                    :value {:i "10"}
+                    :schema "{Keyword Any, :i Int}",
+                    :errors {:i "(not (integer? \"10\"))"}}
+                   (select-keys (second ex)
+                                [:type :coercion :in :value :schema :errors])))))
+
+        (testing "no coercion"
           (let [[status body] (get* app "/no-coercion" {:i 10})]
-            status => 200
-            body => {:i "10"})))))
+            (is (= 200 status))
+            (is (= {:i "10"} body)))))))
 
-  (facts "apiless coercion"
+  (testing "apiless coercion"
 
-    (fact "use default-coercion-matchers by default"
+    (testing "use default-coercion-matchers by default"
       (let [app (context "/api" []
                   :query-params [{y :- Long 0}]
                   (GET "/ping" []
                     :query-params [x :- Long]
                     (ok [x y])))]
-        (app {:request-method :get :uri "/api/ping" :query-params {}}) => (throws)
-        (app {:request-method :get :uri "/api/ping" :query-params {:x "abba"}}) => (throws)
-        (app {:request-method :get :uri "/api/ping" :query-params {:x "1"}}) => (contains {:body [1 0]})
-        (app {:request-method :get :uri "/api/ping" :query-params {:x "1", :y 2}}) => (contains {:body [1 2]})
-        (app {:request-method :get :uri "/api/ping" :query-params {:x "1", :y "abba"}}) => (throws)))
+        (is (thrown? Exception (app {:request-method :get :uri "/api/ping" :query-params {}})))
+        (is (thrown? Exception (app {:request-method :get :uri "/api/ping" :query-params {:x "abba"}})))
+        (is (= [1 0] (:body (app {:request-method :get :uri "/api/ping" :query-params {:x "1"}}))))
+        (is (= [1 2] (:body (app {:request-method :get :uri "/api/ping" :query-params {:x "1", :y 2}}))))
+        (is (thrown? Exception (app {:request-method :get :uri "/api/ping" :query-params {:x "1", :y "abba"}})))))
 
-    (fact "coercion can be overridden"
+    (testing "coercion can be overridden"
       (let [app (context "/api" []
                   :query-params [{y :- Long 0}]
                   (GET "/ping" []
                     :coercion nil
                     :query-params [x :- Long]
                     (ok [x y])))]
-        (app {:request-method :get :uri "/api/ping" :query-params {}}) => (throws)
-        (app {:request-method :get :uri "/api/ping" :query-params {:x "abba"}}) => (contains {:body ["abba" 0]})
-        (app {:request-method :get :uri "/api/ping" :query-params {:x "1"}}) => (contains {:body ["1" 0]})
-        (app {:request-method :get :uri "/api/ping" :query-params {:x "1", :y 2}}) => (contains {:body ["1" 2]})
-        (app {:request-method :get :uri "/api/ping" :query-params {:x "1", :y "abba"}}) => (throws)))
+        (is (thrown? Exception (app {:request-method :get :uri "/api/ping" :query-params {}})))
+        (is (= ["abba" 0] (:body (app {:request-method :get :uri "/api/ping" :query-params {:x "abba"}}))))
+        (is (= ["1" 0] (:body (app {:request-method :get :uri "/api/ping" :query-params {:x "1"}}))))
+        (is (= ["1" 2] (:body (app {:request-method :get :uri "/api/ping" :query-params {:x "1", :y 2}}))))
+        (is (thrown? Exception (app {:request-method :get :uri "/api/ping" :query-params {:x "1", :y "abba"}})))))
 
-    (fact "context coercion is used for subroutes"
+    (testing "context coercion is used for subroutes"
       (let [app (context "/api" []
                   :coercion nil
                   (GET "/ping" []
                     :query-params [x :- Long]
                     (ok x)))]
-        (app {:request-method :get :uri "/api/ping" :query-params {:x "abba"}}) => (contains {:body "abba"})))))
+        (is (= "abba" (:body (app {:request-method :get :uri "/api/ping" :query-params {:x "abba"}}))))))))
diff --git a/test/compojure/api/common_test.clj b/test/compojure/api/common_test.clj
index 54d39ea6..58a5de28 100644
--- a/test/compojure/api/common_test.clj
+++ b/test/compojure/api/common_test.clj
@@ -1,38 +1,38 @@
 (ns compojure.api.common-test
   (:require [compojure.api.common :as common]
-            [midje.sweet :refer :all]
+            [clojure.test :refer [deftest testing is]]
             [criterium.core :as cc]))
 
-(fact "group-with"
-  (common/group-with pos? [1 -10 2 -4 -1 999]) => [[1 2 999] [-10 -4 -1]]
-  (common/group-with pos? [1 2 999]) => [[1 2 999] nil])
+(deftest group-with-test
+  (is (= (common/group-with pos? [1 -10 2 -4 -1 999]) [[1 2 999] [-10 -4 -1]]))
+  (is (= (common/group-with pos? [1 2 999]) [[1 2 999] nil])))
 
-(fact "extract-parameters"
+(deftest extract-parameters-test
 
-  (facts "expect body"
-    (common/extract-parameters [] true) => [{} nil]
-    (common/extract-parameters [{:a 1}] true) => [{} [{:a 1}]]
-    (common/extract-parameters [:a 1] true) => [{:a 1} nil]
-    (common/extract-parameters [{:a 1} {:b 2}] true) => [{:a 1} [{:b 2}]]
-    (common/extract-parameters [:a 1 {:b 2}] true) => [{:a 1} [{:b 2}]])
+  (testing "expect body"
+    (is (= (common/extract-parameters [] true) [{} nil]))
+    (is (= (common/extract-parameters [{:a 1}] true) [{} [{:a 1}]]))
+    (is (= (common/extract-parameters [:a 1] true) [{:a 1} nil]))
+    (is (= (common/extract-parameters [{:a 1} {:b 2}] true) [{:a 1} [{:b 2}]]))
+    (is (= (common/extract-parameters [:a 1 {:b 2}] true) [{:a 1} [{:b 2}]])))
 
-  (facts "don't expect body"
-    (common/extract-parameters [] false) => [{} nil]
-    (common/extract-parameters [{:a 1}] false) => [{:a 1} nil]
-    (common/extract-parameters [:a 1] false) => [{:a 1} nil]
-    (common/extract-parameters [{:a 1} {:b 2}] false) => [{:a 1} [{:b 2}]]
-    (common/extract-parameters [:a 1 {:b 2}] false) => [{:a 1} [{:b 2}]]))
+  (testing "don't expect body"
+    (is (= (common/extract-parameters [] false) [{} nil]))
+    (is (= (common/extract-parameters [{:a 1}] false) [{:a 1} nil]))
+    (is (= (common/extract-parameters [:a 1] false) [{:a 1} nil]))
+    (is (= (common/extract-parameters [{:a 1} {:b 2}] false) [{:a 1} [{:b 2}]]))
+    (is (= (common/extract-parameters [:a 1 {:b 2}] false) [{:a 1} [{:b 2}]]))))
 
-(fact "merge-vector"
-  (common/merge-vector nil) => nil
-  (common/merge-vector [{:a 1}]) => {:a 1}
-  (common/merge-vector [{:a 1} {:b 2}]) => {:a 1 :b 2})
+(deftest merge-vector-test
+  (is (= (common/merge-vector nil) nil))
+  (is (= (common/merge-vector [{:a 1}]) {:a 1}))
+  (is (= (common/merge-vector [{:a 1} {:b 2}]) {:a 1 :b 2})))
 
-(fact "fast-merge-map"
+(deftest fast-merge-map-test
   (let [x {:a 1, :b 2, :c 3}
         y {:a 2, :d 4, :e 5}]
-    (common/fast-map-merge x y) => {:a 2, :b 2, :c 3 :d 4, :e 5}
-    (common/fast-map-merge x y) => (merge x y)))
+    (is (= (common/fast-map-merge x y) {:a 2, :b 2, :c 3 :d 4, :e 5}))
+    (is (= (common/fast-map-merge x y) (merge x y)))))
 
 (comment
   (require '[criterium.core :as cc])
diff --git a/test/compojure/api/help_test.clj b/test/compojure/api/help_test.clj
index 85abfb7f..b7e72a1f 100644
--- a/test/compojure/api/help_test.clj
+++ b/test/compojure/api/help_test.clj
@@ -1,14 +1,14 @@
 (ns compojure.api.help-test
   (:require [compojure.api.help :as help]
             [compojure.api.meta :as meta]
-            [midje.sweet :refer :all]))
+            [clojure.test :refer [deftest is testing]]))
 
-(facts "help-for-api-meta"
-  (fact "all restructure-param methods have a help text"
+(deftest help-for-api-meta-test
+  (testing "all restructure-param methods have a help text"
     (let [restructure-method-names (-> meta/restructure-param methods keys)
           meta-help-topics (-> (methods help/help-for)
                                (dissoc ::help/default)
                                keys
                                (->> (filter #(= :meta (first %)))
                                     (map second)))]
-      (set restructure-method-names) => (set meta-help-topics))))
+      (is (= (set restructure-method-names) (set meta-help-topics))))))
diff --git a/test/compojure/api/integration_test.clj b/test/compojure/api/integration_test.clj
index 3cfe35d6..037bc46e 100644
--- a/test/compojure/api/integration_test.clj
+++ b/test/compojure/api/integration_test.clj
@@ -1,9 +1,11 @@
 (ns compojure.api.integration-test
   (:require [compojure.api.sweet :refer :all]
+            [clojure.string :as str]
+            [clojure.test :refer [deftest is testing]]
+            [compojure.api.test-domain :refer [Pizza burger-routes]]
             [compojure.api.test-utils :refer :all]
             [compojure.api.exception :as ex]
             [compojure.api.swagger :as swagger]
-            [midje.sweet :refer :all]
             [ring.util.http-response :refer :all]
             [ring.util.http-predicates :as http]
             [schema.core :as s]
@@ -45,6 +47,9 @@
 
 (def mw* "mw")
 
+(defn is-200-status [status]
+  (is (= 200 status)))
+
 (defn middleware*
   "This middleware appends given value or 1 to a header in request and response."
   ([handler] (middleware* handler 1))
@@ -101,26 +106,26 @@
 ;; Facts
 ;;
 
-(facts "core routes"
+(deftest core-routes-test
 
-  (fact "keyword options"
+  (testing "keyword options"
     (let [route (GET "/ping" []
                   :return String
                   (ok "kikka"))]
-      (route {:request-method :get :uri "/ping"}) => (contains {:body "kikka"})))
+      (is (= "kikka" (:body (route {:request-method :get :uri "/ping"}))))))
 
-  (fact "map options"
+  (testing "map options"
     (let [route (GET "/ping" []
                   {:return String}
                   (ok "kikka"))]
-      (route {:request-method :get :uri "/ping"}) => (contains {:body "kikka"})))
+      (is (= "kikka" (:body (route {:request-method :get :uri "/ping"}))))))
 
-  (fact "map return"
+  (testing "map return"
     (let [route (GET "/ping" []
                   {:body "kikka"})]
-      (route {:request-method :get :uri "/ping"}) => (contains {:body "kikka"}))))
+      (is (= "kikka" (:body (route {:request-method :get :uri "/ping"})))))))
 
-(facts "middleware ordering"
+(deftest middleware-ordering-test
   (let [app (api
               {:middleware [[middleware* 0]]}
               (route-middleware [[middleware* "a"] [middleware* "b"]]
@@ -133,22 +138,22 @@
                       :middleware [(fn [handler] (middleware* handler "e")) [middleware* "f"]]
                       (reply-mw* req))))))]
 
-    (fact "are applied left-to-right"
+    (testing "are applied left-to-right"
       (let [[status _ headers] (get* app "/middlewares/simple" {})]
-        status => 200
-        (get headers mw*) => "012ab/ba210"))
+        (is (= 200 status))
+        (is (= "012ab/ba210" (get headers mw*)))))
 
-    (fact "are applied left-to-right closest one first"
+    (testing "are applied left-to-right closest one first"
       (let [[status _ headers] (get* app "/middlewares/nested" {})]
-        status => 200
-        (get headers mw*) => "012abcd/dcba210"))
+        (is (= 200 status))
+        (is (= "012abcd/dcba210" (get headers mw*)))))
 
-    (fact "are applied left-to-right for both nested & declared closest one first"
+    (testing "are applied left-to-right for both nested & declared closest one first"
       (let [[status _ headers] (get* app "/middlewares/nested-declared" {})]
-        status => 200
-        (get headers mw*) => "012abcdef/fedcba210"))))
+        (is (= 200 status))
+        (is (= "012abcdef/fedcba210" (get headers mw*)))))))
 
-(facts "context middleware"
+(deftest context-middleware-test
   (let [app (api
               (context "/middlewares" []
                 :middleware [(fn [h] (fn mw
@@ -156,12 +161,12 @@
                                        ([r respond _] (respond (mw r)))))]
                 (GET "/simple" req (reply-mw* req))))]
 
-    (fact "is applied even if route is not matched"
+    (testing "is applied even if route is not matched"
       (let [[status body] (get* app "/middlewares/non-existing" {})]
-        status => 200
-        body => {:middleware "hello"}))))
+        (is (= 200 status))
+        (is (= {:middleware "hello"} body))))))
 
-(facts "middleware - multiple routes"
+(deftest middleware-multiple-routes-test
   (let [app (api
               (GET "/first" []
                 (ok {:value "first"}))
@@ -170,31 +175,31 @@
                 (ok {:value "second"}))
               (GET "/third" []
                 (ok {:value "third"})))]
-    (fact "first returns first"
+    (testing "first returns first"
       (let [[status body] (get* app "/first" {})]
-        status => 200
-        body => {:value "first"}))
-    (fact "second returns foo"
+        (is (= 200 status))
+        (is (= {:value "first"} body))))
+    (testing "second returns foo"
       (let [[status body] (get* app "/second" {})]
-        status => 200
-        body => {:value "foo"}))
-    (fact "third returns third"
+        (is-200-status status)
+        (is (= {:value "foo"} body))))
+    (testing "third returns third"
       (let [[status body] (get* app "/third" {})]
-        status => 200
-        body => {:value "third"}))))
+        (is-200-status status)
+        (is (= {:value "third"} body))))))
 
-(facts "middleware - editing request"
+(deftest middleware-editing-request-test
   (let [app (api
               (GET "/first" []
                 :query-params [x :- Long]
                 :middleware [middleware-x]
                 (ok {:value x})))]
-    (fact "middleware edits the parameter before route body"
+    (testing "middleware edits the parameter before route body"
       (let [[status body] (get* app "/first?x=5" {})]
-        status => 200
-        body => {:value 10}))))
+        (is-200-status status)
+        (is (= {:value 10} body))))))
 
-(fact ":body, :query, :headers and :return"
+(deftest body-query-headers-and-return-test
   (let [app (api
               (context "/models" []
                 (GET "/pertti" []
@@ -229,60 +234,59 @@
                   :return User
                   (ok user))))]
 
-    (fact "GET"
+    (testing "GET"
       (let [[status body] (get* app "/models/pertti")]
-        status => 200
-        body => pertti))
+        (is-200-status status)
+        (is (= pertti body))))
 
-    (fact "GET with smart destructuring"
+    (testing "GET with smart destructuring"
       (let [[status body] (get* app "/models/user" pertti)]
-        status => 200
-        body => pertti))
+        (is-200-status status)
+        (is (= pertti body))))
 
-    (fact "POST with smart destructuring"
+    (testing "POST with smart destructuring"
       (let [[status body] (post* app "/models/user" (json-string pertti))]
-        status => 200
-        body => pertti))
+        (is-200-status status)
+        (is (= pertti body))))
 
-    (fact "POST with smart destructuring - lists"
+    (testing "POST with smart destructuring - lists"
       (let [[status body] (post* app "/models/user_list" (json-string [pertti]))]
-        status => 200
-        body => [pertti]))
+        (is-200-status status)
+        (is (= [pertti] body))))
 
-    (fact "POST with smart destructuring - sets"
+    (testing "POST with smart destructuring - sets"
       (let [[status body] (post* app "/models/user_set" (json-string #{pertti}))]
-        status => 200
-        body => [pertti]))
+        (is-200-status status)
+        (is (= [pertti] body))))
 
-    (fact "POST with compojure destructuring"
+    (testing "POST with compojure destructuring"
       (let [[status body] (post* app "/models/user_legacy" (json-string pertti))]
-        status => 200
-        body => pertti))
+        (is-200-status status)
+        (is (= pertti body))))
 
-    (fact "POST with smart destructuring - headers"
+    (testing "POST with smart destructuring - headers"
       (let [[status body] (headers-post* app "/models/user_headers" pertti)]
-        status => 200
-        body => pertti))
+        (is-200-status status)
+        (is (= pertti body))))
 
-    (fact "Validation of returned data"
+    (testing "Validation of returned data"
       (let [[status] (get* app "/models/invalid-user")]
-        status => 500))
+        (is (= 500 status))))
 
-    (fact "Routes without a :return parameter aren't validated"
+    (testing "Routes without a :return parameter aren't validated"
       (let [[status body] (get* app "/models/not-validated")]
-        status => 200
-        body => invalid-user))
+        (is-200-status status)
+        (is (= invalid-user body))))
 
-    (fact "Invalid json in body causes 400 with error message in json"
+    (testing "Invalid json in body causes 400 with error message in json"
       (let [[status body] (post* app "/models/user" "{INVALID}")]
-        status => 400
-        body => (contains
-                  {:type "compojure.api.exception/request-parsing"
-                   :message (contains "Malformed application/json")
-                   :original (contains "Unexpected character")})))))
-
-(fact ":responses"
-  (fact "normal cases"
+        (is (= 400 status))
+        (is (= "compojure.api.exception/request-parsing" (:type body)))
+        (is (str/starts-with? (:message body) "Malformed application/json"))
+        (is (str/starts-with? (:original body) "Unexpected character"))))))
+
+(deftest responses-test
+  (testing "normal cases"
     (let [app (api
                 (swagger-routes)
                 (GET "/lotto/:x" []
@@ -297,35 +301,35 @@
                     4 (forbidden [1])
                     (not-found {:message "not-found"}))))]
 
-      (fact "return case"
+      (testing "return case"
         (let [[status body] (get* app "/lotto/1")]
-          status => 200
-          body => [1]))
+          (is-200-status status)
+          (is (= [1] body))))
 
-      (fact "return case, non-matching model"
+      (testing "return case, non-matching model"
         (let [[status body] (get* app "/lotto/2")]
-          status => 500
-          body => (contains {:errors vector?})))
+          (is (= 500 status))
+          (is (vector? (:errors body)))))
 
-      (fact "error case"
+      (testing "error case"
         (let [[status body] (get* app "/lotto/3")]
-          status => 403
-          body => ["error"]))
+          (is (= 403 status))
+          (is (= ["error"] body))))
 
-      (fact "error case, non-matching model"
+      (testing "error case, non-matching model"
         (let [[status body] (get* app "/lotto/4")]
-          status => 500
-          body => (contains {:errors vector?})))
+          (is (= 500 status))
+          (is (-> body :errors vector?))))
 
-      (fact "returning non-predefined http-status code works"
+      (testing "returning non-predefined http-status code works"
         (let [[status body] (get* app "/lotto/5")]
-          body => {:message "not-found"}
-          status => 404))
+          (is (= {:message "not-found"} body))
+          (is (= 404 status))))
 
-      (fact "swagger-docs for multiple returns"
+      (testing "swagger-docs for multiple returns"
         (-> app get-spec :paths vals first :get :responses keys set))))
 
-  (fact ":responses 200 and :return"
+  (testing ":responses 200 and :return"
     (let [app (api
                 (GET "/lotto/:x" []
                   :path-params [x :- Long]
@@ -335,18 +339,19 @@
                     1 (ok {:return "ok"})
                     2 (ok {:value "ok"}))))]
 
-      (fact "return case"
+      (testing "return case"
         (let [[status body] (get* app "/lotto/1")]
-          status => 500
-          body => (contains {:errors {:return "disallowed-key"
-                                      :value "missing-required-key"}})))
+          (is (= 500 status))
+          (is (= {:return "disallowed-key"
+                  :value "missing-required-key"}
+                 (:errors body)))))
 
-      (fact "return case"
+      (testing "return case"
         (let [[status body] (get* app "/lotto/2")]
-          status => 200
-          body => {:value "ok"}))))
+          (is-200-status status)
+          (is (= {:value "ok"} body))))))
 
-  (fact ":responses 200 and :return - other way around"
+  (testing ":responses 200 and :return - other way around"
     (let [app (api
                 (GET "/lotto/:x" []
                   :path-params [x :- Long]
@@ -356,18 +361,19 @@
                     1 (ok {:return "ok"})
                     2 (ok {:value "ok"}))))]
 
-      (fact "return case"
+      (testing "return case"
         (let [[status body] (get* app "/lotto/1")]
-          status => 200
-          body => {:return "ok"}))
+          (is-200-status status)
+          (is (= {:return "ok"} body))))
 
-      (fact "return case"
+      (testing "return case"
         (let [[status body] (get* app "/lotto/2")]
-          status => 500
-          body => (contains {:errors {:return "missing-required-key"
-                                      :value "disallowed-key"}}))))))
+          (is (= 500 status))
+          (is (= {:return "missing-required-key"
+                  :value "disallowed-key"}
+                 (:errors body))))))))
 
-(fact ":query-params, :path-params, :header-params , :body-params and :form-params"
+(deftest query-params-path-params-header-params-body-params-and-form-params-test
   (let [app (api
               (context "/smart" []
                 (GET "/plus" []
@@ -386,37 +392,37 @@
                   :form-params [x :- Long y :- Long]
                   (ok {:total (/ x y)}))))]
 
-    (fact "query-parameters"
+    (testing "query-parameters"
       (let [[status body] (get* app "/smart/plus" {:x 2 :y 3})]
-        status => 200
-        body => {:total 5}))
+        (is-200-status status)
+        (is (= {:total 5} body))))
 
-    (fact "path-parameters"
+    (testing "path-parameters"
       (let [[status body] (get* app "/smart/multiply/2/3")]
-        status => 200
-        body => {:total 6}))
+        (is-200-status status)
+        (is (= {:total 6} body))))
 
-    (fact "header-parameters"
+    (testing "header-parameters"
       (let [[status body] (get* app "/smart/power" {} {:x 2 :y 3})]
-        status => 200
-        body => {:total 8}))
+        (is-200-status status)
+        (is (= {:total 8} body))))
 
-    (fact "form-parameters"
+    (testing "form-parameters"
       (let [[status body] (form-post* app "/smart/divide" {:x 6 :y 3})]
-        status => 200
-        body => {:total 2}))
+        (is-200-status status)
+        (is (= {:total 2} body))))
 
-    (fact "body-parameters"
+    (testing "body-parameters"
       (let [[status body] (post* app "/smart/minus" (json-string {:x 2 :y 3}))]
-        status => 200
-        body => {:total -1}))
+        (is-200-status status)
+        (is (= {:total -1} body))))
 
-    (fact "default parameters"
+    (testing "default parameters"
       (let [[status body] (post* app "/smart/minus" (json-string {:x 2}))]
-        status => 200
-        body => {:total 1}))))
+        (is-200-status status)
+        (is (= {:total 1} body))))))
 
-(fact "primitive support"
+(deftest primitive-support-test
   (let [app (api
               {:swagger {:spec "/swagger.json"}}
               (context "/primitives" []
@@ -433,46 +439,46 @@
                   :body [longs [Long]]
                   (ok longs))))]
 
-    (fact "when :return is set, longs can be returned"
+    (testing "when :return is set, longs can be returned"
       (let [[status body] (raw-get* app "/primitives/return-long")]
-        status => 200
-        body => "1"))
+        (is-200-status status)
+        (is (= "1" body))))
 
-    (fact "when :return is not set, longs won't be encoded"
+    (testing "when :return is not set, longs won't be encoded"
       (let [[status body] (raw-get* app "/primitives/long")]
-        status => 200
-        body => number?))
+        (is-200-status status)
+        (is (number? body))))
 
-    (fact "when :return is set, raw strings can be returned"
+    (testing "when :return is set, raw strings can be returned"
       (let [[status body] (raw-get* app "/primitives/return-string")]
-        status => 200
-        body => "\"kikka\""))
+        (is-200-status status)
+        (is (= "\"kikka\"" body))))
 
-    (fact "primitive arrays work"
+    (testing "primitive arrays work"
       (let [[status body] (raw-post* app "/primitives/arrays" (json-string [1 2 3]))]
-        status => 200
-        body => "[1,2,3]"))
+        (is-200-status status)
+        (is (= "[1,2,3]" body))))
 
-    (fact "swagger-spec is valid"
+    (testing "swagger-spec is valid"
       (validator/validate app))
 
-    (fact "primitive array swagger-docs are good"
+    (testing "primitive array swagger-docs are good"
 
-      (-> app get-spec :paths (get "/primitives/arrays") :post :parameters)
-      => [{:description ""
-           :in "body"
-           :name ""
-           :required true
-           :schema {:items {:format "int64"
-                            :type "integer"}
-                    :type "array"}}]
+      (is (= [{:description ""
+               :in "body"
+               :name ""
+               :required true
+               :schema {:items {:format "int64"
+                                :type "integer"}
+                        :type "array"}}]
+             (-> app get-spec :paths (get "/primitives/arrays") :post :parameters)))
 
-      (-> app get-spec :paths (get "/primitives/arrays") :post :responses :200 :schema)
-      => {:items {:format "int64",
-                  :type "integer"},
-          :type "array"})))
+      (is (= {:items {:format "int64",
+                      :type "integer"},
+              :type "array"}
+             (-> app get-spec :paths (get "/primitives/arrays") :post :responses :200 :schema))))))
 
-(fact "compojure destructuring support"
+(deftest compojure-destructuring-support-test
   (let [app (api
               (context "/destructuring" []
                 (GET "/regular" {{:keys [a]} :params}
@@ -496,12 +502,12 @@
                        :b b}))))]
 
     (doseq [uri ["regular" "regular2" "vector" "vector2" "symbol" "integrated"]]
-      (fact {:midje/description uri}
+      (testing uri
         (let [[status body] (get* app (str "/destructuring/" uri) {:a "a" :b "b"})]
-          status => 200
-          body => {:a "a" :b "b"})))))
+          (is-200-status status)
+          (is (= {:a "a" :b "b"} body)))))))
 
-(fact "counting execution times, issue #19"
+(deftest counting-execution-times-issue-19-test
   (let [execution-times (atom 0)
         app (api
               (GET "/user" []
@@ -510,14 +516,14 @@
                 (swap! execution-times inc)
                 (ok user)))]
 
-    (fact "body is executed one"
-      @execution-times => 0
+    (testing "body is executed one"
+      (is (zero? @execution-times))
       (let [[status body] (get* app "/user" pertti)]
-        status => 200
-        body => pertti)
-      @execution-times => 1)))
+        (is-200-status status)
+        (is (= pertti body)))
+      (is (= 1 @execution-times)))))
 
-(fact "swagger-docs"
+(deftest swagger-docs-test
   (let [app (api
               {:formats (m/select-formats
                           m/default-options
@@ -526,102 +532,100 @@
               (GET "/user" []
                 (continue)))]
 
-    (fact "api-listing shows produces & consumes for known types"
-      (get-spec app) => {:swagger "2.0"
-                         :info {:title "Swagger API"
-                                :version "0.0.1"}
-                         :basePath "/"
-                         :consumes ["application/json" "application/edn"]
-                         :produces ["application/json" "application/edn"]
-                         :definitions {}
-                         :paths {"/user" {:get {:responses {:default {:description ""}}}}}}))
+    (testing "api-listing shows produces & consumes for known types"
+      (is (= {:swagger "2.0"
+              :info {:title "Swagger API"
+                     :version "0.0.1"}
+              :basePath "/"
+              :consumes ["application/json" "application/edn"]
+              :produces ["application/json" "application/edn"]
+              :definitions {}
+              :paths {"/user" {:get {:responses {:default {:description ""}}}}}}
+             (get-spec app)))))
 
-  (fact "swagger-routes"
+  (testing "swagger-routes"
 
-    (fact "with defaults"
+    (testing "with defaults"
       (let [app (api (swagger-routes))]
 
-        (fact "api-docs are mounted to /"
+        (testing "api-docs are mounted to /"
           (let [[status body] (raw-get* app "/")]
-            status => 200
-            body => #"<title>Swagger UI</title>"))
+            (is-200-status status)
+            (is (str/includes? body "<title>Swagger UI</title>"))))
 
-        (fact "spec is mounted to /swagger.json"
+        (testing "spec is mounted to /swagger.json"
           (let [[status body] (get* app "/swagger.json")]
-            status => 200
-            body => (contains {:swagger "2.0"})))))
+            (is-200-status status)
+            (is (= "2.0" (:swagger body)))))))
 
-    (fact "with partial overridden values"
+    (testing "with partial overridden values"
       (let [app (api (swagger-routes {:ui "/api-docs"
                                       :data {:info {:title "Kikka"}
                                              :paths {"/ping" {:get {}}}}}))]
 
-        (fact "api-docs are mounted"
+        (testing "api-docs are mounted"
           (let [[status body] (raw-get* app "/api-docs")]
-            status => 200
-            body => #"<title>Swagger UI</title>"))
+            (is-200-status status)
+            (is (str/includes? body "<title>Swagger UI</title>"))))
 
-        (fact "spec is mounted to /swagger.json"
+        (testing "spec is mounted to /swagger.json"
           (let [[status body] (get* app "/swagger.json")]
-            status => 200
-            body => (contains
-                      {:swagger "2.0"
-                       :info (contains
-                               {:title "Kikka"})
-                       :paths (contains
-                                {(keyword "/ping") anything})}))))))
+            (is-200-status status)
+            (is (= "2.0" (:swagger body)))
+            (is (= "Kikka" (-> body :info :title)))
+            (is (some? (-> body :paths (get (keyword "/ping"))))))))))
 
-  (fact "swagger via api-options"
+  (testing "swagger via api-options"
 
-    (fact "with defaults"
+    (testing "with defaults"
       (let [app (api)]
 
-        (fact "api-docs are not mounted"
+        (testing "api-docs are not mounted"
           (let [[status body] (raw-get* app "/")]
-            status => nil))
+            (is (nil? status))))
 
-        (fact "spec is not mounted"
+        (testing "spec is not mounted"
           (let [[status body] (get* app "/swagger.json")]
-            status => nil))))
+            (is (= nil status))))))
 
-    (fact "with spec"
+    (testing "with spec"
       (let [app (api {:swagger {:spec "/swagger.json"}})]
 
-        (fact "api-docs are not mounted"
+        (testing "api-docs are not mounted"
           (let [[status body] (raw-get* app "/")]
-            status => nil))
+            (is (= nil status))))
 
-        (fact "spec is mounted to /swagger.json"
+        (testing "spec is mounted to /swagger.json"
           (let [[status body] (get* app "/swagger.json")]
-            status => 200
-            body => (contains {:swagger "2.0"}))))))
+            (is-200-status status)
+            (is (= "2.0" (:swagger body))))))))
 
-  (fact "with ui"
+  (testing "with ui"
     (let [app (api {:swagger {:ui "/api-docs"}})]
 
-      (fact "api-docs are mounted"
+      (testing "api-docs are mounted"
         (let [[status body] (raw-get* app "/api-docs")]
-          status => 200
-          body => #"<title>Swagger UI</title>"))
+          (is-200-status status)
+          (is (str/includes? body "<title>Swagger UI</title>"))))
 
-      (fact "spec is not mounted"
+      (testing "spec is not mounted"
         (let [[status body] (get* app "/swagger.json")]
-          status => nil))))
+          (is (= nil status))))))
 
-  (fact "with ui and spec"
+  (testing "with ui and spec"
     (let [app (api {:swagger {:spec "/swagger.json", :ui "/api-docs"}})]
 
-      (fact "api-docs are mounted"
+      (testing "api-docs are mounted"
         (let [[status body] (raw-get* app "/api-docs")]
-          status => 200
-          body => #"<title>Swagger UI</title>"))
+          (is-200-status status)
+          (str/includes? body "<title>Swagger UI</title>")))
 
-      (fact "spec is mounted to /swagger.json"
+      (testing "spec is mounted to /swagger.json"
         (let [[status body] (get* app "/swagger.json")]
-          status => 200
-          body => (contains {:swagger "2.0"}))))))
+          (is-200-status status)
+          (is (= "2.0" (:swagger body))))))))
 
-(facts "swagger-docs with anonymous Return and Body models"
+(deftest swagger-docs-with-anonymous-Return-and-Body-models-test
   (let [app (api
               (swagger-routes)
               (POST "/echo" []
@@ -629,19 +633,19 @@
                 :body [_ (s/maybe {:a String})]
                 identity))]
 
-    (fact "api-docs"
+    (testing "api-docs"
       (let [spec (get-spec app)]
 
         (let [operation (some-> spec :paths vals first :post)
               body-ref (some-> operation :parameters first :schema :$ref)
               return-ref (get-in operation [:responses :200 :schema :$ref])]
 
-          (fact "generated body-param is found in Definitions"
-            (find-definition spec body-ref) => truthy)
+          (testing "generated body-param is found in Definitions"
+            (is (find-definition spec body-ref)))
 
-          (fact "generated return-param is found in Definitions"
-            return-ref => truthy
-            (find-definition spec body-ref) => truthy))))))
+          (testing "generated return-param is found in Definitions"
+            (is return-ref)
+            (is (find-definition spec body-ref))))))))
 
 (def Boundary
   {:type (s/enum "MultiPolygon" "Polygon" "MultiPoint" "Point")
@@ -650,7 +654,8 @@
 (def ReturnValue
   {:boundary (s/maybe Boundary)})
 
-(facts "https://github.com/metosin/compojure-api/issues/53"
+;; "https://github.com/metosin/compojure-api/issues/53"
+(deftest issue-53-test
   (let [app (api
               (swagger-routes)
               (POST "/" []
@@ -658,25 +663,25 @@
                 :body [_ Boundary]
                 identity))]
 
-    (fact "api-docs"
+    (testing "api-docs"
       (let [spec (get-spec app)]
 
         (let [operation (some-> spec :paths vals first :post)
               body-ref (some-> operation :parameters first :schema :$ref)
               return-ref (get-in operation [:responses :200 :schema :$ref])]
 
-          (fact "generated body-param is found in Definitions"
-            (find-definition spec body-ref) => truthy)
+          (testing "generated body-param is found in Definitions"
+            (is (find-definition spec body-ref)))
 
-          (fact "generated return-param is found in Definitions"
-            return-ref => truthy
-            (find-definition spec body-ref) => truthy))))))
+          (testing "generated return-param is found in Definitions"
+            (is return-ref)
+            (is (find-definition spec body-ref))))))))
 
 (s/defschema Urho {:kaleva {:kekkonen {s/Keyword s/Any}}})
 (s/defschema Olipa {:kerran {:avaruus {s/Keyword s/Any}}})
 
 ; https://github.com/metosin/compojure-api/issues/94
-(facts "preserves deeply nested schema names"
+(deftest preserves-deeply-nested-schema-names-test
   (let [app (api
               (swagger-routes)
               (POST "/" []
@@ -684,16 +689,15 @@
                 :body [_ Olipa]
                 identity))]
 
-    (fact "api-docs"
+    (testing "api-docs"
       (let [spec (get-spec app)]
 
-        (fact "nested models are discovered correctly"
-          (-> spec :definitions keys set)
-
-          => #{:Urho :UrhoKaleva :UrhoKalevaKekkonen
-               :Olipa :OlipaKerran :OlipaKerranAvaruus})))))
+        (testing "nested models are discovered correctly"
+          (is (= #{:Urho :UrhoKaleva :UrhoKalevaKekkonen
+                   :Olipa :OlipaKerran :OlipaKerranAvaruus}
+                 (-> spec :definitions keys set))))))))
 
-(fact "swagger-docs works with the :middleware"
+(deftest swagger-docs-works-with-the-middleware-test
   (let [app (api
               (swagger-routes)
               (GET "/middleware" []
@@ -701,16 +705,16 @@
                 :middleware [[constant-middleware (ok 1)]]
                 (ok 2)))]
 
-    (fact "api-docs"
-      (-> app get-spec :paths vals first)
-      => {:get {:parameters [{:description ""
-                              :in "query"
-                              :name "x"
-                              :required true
-                              :type "string"}]
-                :responses {:default {:description ""}}}})))
+    (testing "api-docs"
+      (is (= {:get {:parameters [{:description ""
+                                  :in "query"
+                                  :name "x"
+                                  :required true
+                                  :type "string"}]
+                    :responses {:default {:description ""}}}}
+             (-> app get-spec :paths vals first))))))
 
-(fact "sub-context paths"
+(deftest sub-context-paths-test
   (let [response {:ping "pong"}
         ok (ok response)
         ok? (fn [[status body]]
@@ -727,65 +731,60 @@
                   (GET "/" [] ok)
                   (GET "/b2" [] ok))))]
 
-    (fact "valid routes"
-      (get* app "/") => ok?
-      (get* app "/a") => ok?
-      (get* app "/b/b1") => ok?
-      (get* app "/b") => ok?
-      (get* app "/b/b2") => ok?)
+    (testing "valid routes"
+      (is (ok? (get* app "/")))
+      (is (ok? (get* app "/a")))
+      (is (ok? (get* app "/b/b1")))
+      (is (ok? (get* app "/b")))
+      (is (ok? (get* app "/b/b2"))))
 
-    (fact "undocumented compojure easter eggs"
-      (get* app "/b/b1/") => ok?
-      (get* app "/b/") => ok?
-      (fact "this is fixed in compojure 1.5.1"
-        (get* app "/b//") =not=> ok?))
+    (testing "undocumented compojure easter eggs"
+      (is (ok? (get* app "/b/b1/")))
+      (is (ok? (get* app "/b/")))
+      (testing "this is fixed in compojure 1.5.1"
+        (is (not (ok? (get* app "/b//"))))))
 
-    (fact "swagger-docs have trailing slashes removed"
-      (->> app get-spec :paths keys)
-      => (just ["/" "/a" "/b/b1" "/b" "/b/b2"] :in-any-order))))
+    (testing "swagger-docs have trailing slashes removed"
+      (is (= (sort ["/" "/a" "/b/b1" "/b" "/b/b2"])
+             (-> app get-spec :paths keys sort))))))
 
-(fact "formats supported by ring-middleware-format"
+(deftest formats-supported-by-ring-middleware-format-test
   (let [app (api
               (POST "/echo" []
                 :body-params [foo :- String]
                 (ok {:foo foo})))]
 
-    (tabular
-      (facts
-        (fact {:midje/description (str ?content-type " to json")}
+    (doseq [[?content-type ?body] [["application/json" "{\"foo\":\"bar\"}"]
+                                   ["application/edn" "{:foo \"bar\"}"]
+                                   ["application/transit+json" "[\"^ \",\"~:foo\",\"bar\"]"]]]
+      (testing (pr-str [?content-type ?body])
+        (testing (str ?content-type " to json")
           (let [[status body]
                 (raw-post* app "/echo" ?body ?content-type {:accept "application/json"})]
-            status => 200
-            body => "{\"foo\":\"bar\"}"))
-        (fact {:midje/description (str "json to " ?content-type)}
+            (is-200-status status)
+            (is (= "{\"foo\":\"bar\"}" body))))
+        (testing (str "json to " ?content-type)
           (let [[status body]
                 (raw-post* app "/echo" "{\"foo\":\"bar\"}" "application/json" {:accept ?content-type})]
-            status => 200
-            body => ?body)))
+            (is-200-status status)
+            (is (= ?body body))))))))
 
-      ?content-type ?body
-      "application/json" "{\"foo\":\"bar\"}"
-      "application/edn" "{:foo \"bar\"}"
-      "application/transit+json" "[\"^ \",\"~:foo\",\"bar\"]")))
-
-(fact "multiple routes in context"
+(deftest multiple-routes-in-context-test
   (let [app (api
               (context "/foo" []
                 (GET "/bar" [] (ok ["bar"]))
                 (GET "/baz" [] (ok ["baz"]))))]
 
-    (fact "first route works"
+    (testing "first route works"
       (let [[status body] (get* app "/foo/bar")]
-        status => 200
-        body => ["bar"]))
-    (fact "second route works"
+        (is-200-status status)
+        (is (= ["bar"] body))))
+    (testing "second route works"
       (let [[status body] (get* app "/foo/baz")]
-        status => 200
-        body => ["baz"]))))
-
-(require '[compojure.api.test-domain :refer [Pizza burger-routes]])
+        (is-200-status status)
+        (is (= ["baz"] body))))))
 
-(fact "external deep schemas"
+(deftest external-deep-schemas-test
   (let [app (api
               (swagger-routes)
               burger-routes
@@ -794,22 +793,23 @@
                 :body [body Pizza]
                 (ok body)))]
 
-    (fact "direct route with nested named schema works when called"
+    (testing "direct route with nested named schema works when called"
       (let [pizza {:toppings [{:name "cheese"}]}
             [status body] (post* app "/pizza" (json-string pizza))]
-        status => 200
-        body => pizza))
+        (is-200-status status)
+        (is (= pizza body))))
 
-    (fact "defroute*'d route with nested named schema works when called"
+    (testing "defroute*'d route with nested named schema works when called"
       (let [burger {:ingredients [{:name "beef"}, {:name "egg"}]}
             [status body] (post* app "/burger" (json-string burger))]
-        status => 200
-        body => burger))
+        (is-200-status status)
+        (is (= burger body))))
 
-    (fact "generates correct swagger-spec"
-      (-> app get-spec :definitions keys set) => #{:Topping :Pizza :Burger :Beef})))
+    (testing "generates correct swagger-spec"
+      (is (= #{:Topping :Pizza :Burger :Beef}
+             (-> app get-spec :definitions keys set))))))
 
-(fact "multiple routes with same path & method in same file"
+(deftest multiple-routes-with-same-path-and-method-in-same-file-test
   (let [app (api
               (swagger-routes)
               (GET "/ping" []
@@ -819,15 +819,15 @@
                 :summary "passive-ping"
                 (ok {:ping "passive"})))]
 
-    (fact "first route matches with Compojure"
+    (testing "first route matches with Compojure"
       (let [[status body] (get* app "/ping" {})]
-        status => 200
-        body => {:ping "active"}))
+        (is-200-status status)
+        (is (= {:ping "active"} body))))
 
-    (fact "generates correct swagger-spec"
-      (-> app get-spec :paths vals first :get :summary) => "active-ping")))
+    (testing "generates correct swagger-spec"
+      (is (= "active-ping" (-> app get-spec :paths vals first :get :summary))))))
 
-(fact "multiple routes with same path & method over context"
+(deftest multiple-routes-with-same-path-and-method-over-context-test
   (let [app (api
               (swagger-routes)
               (context "/api" []
@@ -841,15 +841,16 @@
                     :summary "passive-ping"
                     (ok {:ping "passive"})))))]
 
-    (fact "first route matches with Compojure"
+    (testing "first route matches with Compojure"
       (let [[status body] (get* app "/api/ipa/ping" {})]
-        status => 200
-        body => {:ping "active"}))
+        (is-200-status status)
+        (is (= {:ping "active"} body))))
 
-    (fact "generates correct swagger-spec"
-      (-> app get-spec :paths vals first :get :summary) => "active-ping")))
+    (testing "generates correct swagger-spec"
+      (is (= "active-ping" (-> app get-spec :paths vals first :get :summary))))))
 
-(fact "multiple routes with same overall path (with different path sniplets & method over context"
+;; multiple routes with same overall path (with different path sniplets & method over context)
+(deftest multiple-routes-with-same-overall-path-test
   (let [app (api
               (swagger-routes)
               (context "/api/ipa" []
@@ -862,72 +863,73 @@
                     :summary "passive-ping"
                     (ok {:ping "passive"})))))]
 
-    (fact "first route matches with Compojure"
+    (testing "first route matches with Compojure"
       (let [[status body] (get* app "/api/ipa/ping" {})]
-        status => 200
-        body => {:ping "active"}))
+        (is-200-status status)
+        (is (= {:ping "active"} body))))
 
-    (fact "generates correct swagger-spec"
-      (-> app get-spec :paths vals first :get :summary) => "active-ping")))
+    (testing "generates correct swagger-spec"
+      (is (= "active-ping" (-> app get-spec :paths vals first :get :summary))))))
 
 ; https://github.com/metosin/compojure-api/issues/98
 ; https://github.com/metosin/compojure-api/issues/134
-(fact "basePath"
+(deftest basePath-test
   (let [app (api (swagger-routes))]
 
-    (fact "no context"
-      (-> app get-spec :basePath) => "/")
+    (testing "no context"
+      (is (= "/" (-> app get-spec :basePath))))
 
-    (fact "app-servers with given context"
-      (against-background (rsc/context anything) => "/v2")
-      (-> app get-spec :basePath) => "/v2"))
+    (testing "app-servers with given context"
+      (with-redefs [rsc/context (fn [& args] "/v2")]
+        (is (= "/v2" (-> app get-spec :basePath))))))
 
   (let [app (api (swagger-routes {:data {:basePath "/serve/from/here"}}))]
-    (fact "override it"
-      (-> app get-spec :basePath) => "/serve/from/here"))
+    (testing "override it"
+      (is (= "/serve/from/here" (-> app get-spec :basePath)))))
 
   (let [app (api (swagger-routes {:data {:basePath "/"}}))]
-    (fact "can set it to the default"
-      (-> app get-spec :basePath) => "/")))
+    (testing "can set it to the default"
+      (is (= "/" (-> app get-spec :basePath))))))
 
-(fact "multiple different models with same name"
+(deftest multiple-different-models-with-same-name-test
 
-  (fact "schemas with same regexps are not equal"
-    {:d #"\D"} =not=> {:d #"\D"})
+  (testing "schemas with same regexps are not equal"
+    (is (not= {:d #"\D"} {:d #"\D"})))
 
-  (fact "api-spec with 2 schemas with non-equal contents"
+  (testing "api-spec with 2 schemas with non-equal contents"
     (let [app (api
                 (swagger-routes)
                 (GET "/" []
                   :responses {200 {:schema (s/schema-with-name {:a {:d #"\D"}} "Kikka")}
                               201 {:schema (s/schema-with-name {:a {:d #"\D"}} "Kikka")}}
                   identity))]
-      (fact "api spec doesn't fail (#102)"
-        (get-spec app) => anything))))
+      (testing "api spec doesn't fail (#102)"
+        (is (get-spec app))))))
 
 (def over-the-hills-and-far-away
   (POST "/" []
     :body-params [a :- s/Str]
     identity))
 
-(fact "anonymous body models over defined routes"
+(deftest anonymous-body-models-over-defined-routes-test
   (let [app (api
               (swagger-routes)
               over-the-hills-and-far-away)]
-    (fact "generated model doesn't have namespaced keys"
-      (-> app get-spec :definitions vals first :properties keys first) => :a)))
+    (testing "generated model doesn't have namespaced keys"
+      (is (= :a (-> app get-spec :definitions vals first :properties keys first))))))
 
 (def foo
   (GET "/foo" []
     (let [foo {:foo "bar"}]
       (ok foo))))
 
-(fact "defroutes with local symbol usage with same name (#123)"
+;;defroutes with local symbol usage with same name (#123)
+(deftest defroutes-with-local-symbol-usage-with-same-name-test
   (let [app (api
               foo)]
     (let [[status body] (get* app "/foo")]
-      status => 200
-      body => {:foo "bar"})))
+      (is-200-status status)
+      (is (= {:foo "bar"} body)))))
 
 (def response-descriptions-routes
   (GET "/x" []
@@ -935,13 +937,13 @@
                      :description "Horror"}}
     identity))
 
-(fact "response descriptions"
+(deftest response-descriptions-test
   (let [app (api
               (swagger-routes)
               response-descriptions-routes)]
-    (-> app get-spec :paths vals first :get :responses :500 :description) => "Horror"))
+    (is (= "Horror" (-> app get-spec :paths vals first :get :responses :500 :description)))))
 
-(fact "exceptions options with custom validation error handler"
+(deftest exceptions-options-with-custom-validation-error-handler-test
   (let [app (api
               {:exceptions {:handlers {::ex/request-validation custom-validation-error-handler
                                        ::ex/request-parsing custom-validation-error-handler
@@ -954,27 +956,27 @@
                   1 (ok 1)
                   (ok "not a number"))))]
 
-    (fact "return case, valid request & valid model"
+    (testing "return case, valid request & valid model"
       (let [[status body] (post* app "/get-long" "{\"x\": 1}")]
-        status => 200
-        body => 1))
+        (is-200-status status)
+        (is (= 1 body))))
 
-    (fact "return case, not schema valid request"
+    (testing "return case, not schema valid request"
       (let [[status body] (post* app "/get-long" "{\"x\": \"1\"}")]
-        status => 400
-        body => (contains {:custom-error "/get-long"})))
+        (is (= 400 status))
+        (is (= "/get-long" (:custom-error body)))))
 
-    (fact "return case, invalid json request"
+    (testing "return case, invalid json request"
       (let [[status body] (post* app "/get-long" "{x: 1}")]
-        status => 400
-        body => (contains {:custom-error "/get-long"})))
+        (is (= 400 status))
+        (is (= "/get-long" (:custom-error body)))))
 
-    (fact "return case, valid request & invalid model"
+    (testing "return case, valid request & invalid model"
       (let [[status body] (post* app "/get-long" "{\"x\": 2}")]
-        status => 501
-        body => (contains {:custom-error "/get-long"})))))
+        (is (= 501 status))
+        (is (= "/get-long" (:custom-error body)))))))
 
-(fact "exceptions options with custom exception and error handler"
+(deftest exceptions-options-with-custom-exception-and-error-handler-test
   (let [app (api
               {:exceptions {:handlers {::ex/default (custom-exception-handler :custom-exception)
                                        SQLException (custom-exception-handler :sql-exception)
@@ -991,72 +993,72 @@
               (GET "/sub-class" []
                 (throw (SQLWarning.))))]
 
-    (fact "uses default exception handler for unknown exceptions"
+    (testing "uses default exception handler for unknown exceptions"
       (let [[status body] (get* app "/some-exception")]
-        status => 200
-        body => {:custom-exception "java.lang.RuntimeException"}))
+        (is-200-status status)
+        (is (= {:custom-exception "java.lang.RuntimeException"} body))))
 
-    (fact "uses default exception handler for unknown errors"
+    (testing "uses default exception handler for unknown errors"
       (let [[status body] (get* app "/some-error")]
-        status => 200
-        (:custom-exception body) => (contains ":data \"some error\"")))
+        (is-200-status status)
+        (is (str/includes? (:custom-exception body) ":data \"some error\"" ))))
 
-    (fact "uses specific error handler for ::custom-errors"
+    (testing "uses specific error handler for ::custom-errors"
       (let [[_ body] (get* app "/specific-error")]
-        body => {:custom-error "my error"}))
+        (is (= {:custom-error "my error"} body))))
 
-    (fact "direct class"
+    (testing "direct class"
       (let [[_ body] (get* app "/class")]
-        body => (contains {:sql-exception "java.sql.SQLException"})))
+        (is (= "java.sql.SQLException" (:sql-exception body)))))
 
-    (fact "sub-class"
+    (testing "sub-class"
       (let [[_ body] (get* app "/sub-class")]
-        body => (contains {:sql-exception "java.sql.SQLWarning"})))))
+        (is (= "java.sql.SQLWarning" (:sql-exception body)))))))
 
-(fact "exception handling can be disabled"
+(deftest exception-handling-can-be-disabled-test
   (let [app (api
               {:exceptions nil}
               (GET "/throw" []
                 (throw (new RuntimeException))))]
-    (get* app "/throw") => throws))
+    (is (thrown? RuntimeException (get* app "/throw")))))
 
 (s/defn schema-error [a :- s/Int]
   {:bar a})
 
-(fact "handling schema.core/error"
+;; handling schema.core/error
+(deftest handling-schema-core-error-test
   (let [app (api
               {:exceptions {:handlers {:schema.core/error ex/schema-error-handler}}}
               (GET "/:a" []
                 :path-params [a :- s/Str]
                 (ok (s/with-fn-validation (schema-error a)))))]
     (let [[status body] (get* app "/foo")]
-      status => 400
-      body => (contains {:errors vector?}))))
+      (is (= 400 status))
+      (is (-> body :errors vector?)))))
 
-(fact "ring-swagger options"
+(deftest ring-swagger-options-test
   (let [app (api
               {:ring-swagger {:default-response-description-fn status/get-description}}
               (swagger-routes)
               (GET "/ping" []
                 :responses {500 nil}
                 identity))]
-    (-> app get-spec :paths vals first :get :responses :500 :description)
-    => "There was an internal server error."))
+    (is (= "There was an internal server error." (-> app get-spec :paths vals first :get :responses :500 :description)))))
 
-(fact "path-for"
-  (fact "simple case"
+(deftest path-for-test
+  (testing "simple case"
     (let [app (api
                 (GET "/api/pong" []
                   :name :pong
                   (ok {:pong "pong"}))
                 (GET "/api/ping" []
                   (moved-permanently (path-for :pong))))]
-      (fact "path-for works"
+      (testing "path-for works"
         (let [[status body] (get* app "/api/ping" {})]
-          status => 200
-          body => {:pong "pong"}))))
+          (is-200-status status)
+          (is (= {:pong "pong"} body))))))
 
-  (fact "with path parameters"
+  (testing "with path parameters"
     (let [app (api
                 (GET "/lost-in/:country/:zip" []
                   :name :lost
@@ -1066,25 +1068,24 @@
                 (GET "/api/ping" []
                   (moved-permanently
                     (path-for :lost {:country :FI, :zip 33200}))))]
-      (fact "path-for resolution"
+      (testing "path-for resolution"
         (let [[status body] (get* app "/api/ping" {})]
-          status => 200
-          body => {:country "FI"
-                   :zip 33200}))))
+          (is-200-status status)
+          (is (= {:country "FI" :zip 33200} body))))))
 
-  (fact "https://github.com/metosin/compojure-api/issues/150"
+  (testing "https://github.com/metosin/compojure-api/issues/150"
     (let [app (api
                 (GET "/companies/:company-id/refresh" []
                   :path-params [company-id :- s/Int]
                   :name :refresh-company
                   :return String
                   (ok (path-for :refresh-company {:company-id company-id}))))]
-      (fact "path-for resolution"
+      (testing "path-for resolution"
         (let [[status body] (get* app "/companies/4/refresh")]
-          status => 200
-          body => "/companies/4/refresh"))))
+          (is-200-status status)
+          (is (= "/companies/4/refresh" body))))))
 
-  (fact "multiple routes with same name fail at compile-time"
+  (testing "multiple routes with same name fail at compile-time"
     (let [app' `(api
                   (GET "/api/pong" []
                     :name :pong
@@ -1092,115 +1093,113 @@
                   (GET "/api/ping" []
                     :name :pong
                     identity))]
-      (eval app') => (throws RuntimeException)))
+      (is (thrown? RuntimeException (eval app')))))
 
-  (fact "bindings with wrong syntax should fail nicely"
+  (testing "bindings with wrong syntax should fail nicely"
     (let [app' `(api
                   (GET "/api/:id/pong" []
                     :path-params [id ::id]
                     :name :pong
                     identity))]
-      (eval app') => (throws RuntimeException))))
+      (is (thrown? RuntimeException (eval app'))))))
 
-(fact "swagger-spec-path"
-  (fact "defaults to /swagger.json"
+(deftest swagger-spec-path-test
+  (testing "defaults to /swagger.json"
     (let [app (api (swagger-routes))]
-      (swagger/swagger-spec-path app) => "/swagger.json"))
-  (fact "follows defined path"
+      (is (= "/swagger.json" (swagger/swagger-spec-path app)))))
+  (testing "follows defined path"
     (let [app (api (swagger-routes {:spec "/api/api-docs/swagger.json"}))]
-      (swagger/swagger-spec-path app) => "/api/api-docs/swagger.json")))
+      (is (= "/api/api-docs/swagger.json" (swagger/swagger-spec-path app))))))
 
 (defrecord NonSwaggerRecord [data])
 
-(fact "api validation"
+(deftest api-validation-test
 
-  (fact "a swagger api with valid swagger records"
+  (testing "a swagger api with valid swagger records"
     (let [app (api
                 (swagger-routes)
                 (GET "/ping" []
                   :return {:data s/Str}
                   (ok {:data "ping"})))]
 
-      (fact "works"
+      (testing "works"
         (let [[status body] (get* app "/ping")]
-          status => 200
-          body => {:data "ping"}))
+          (is-200-status status)
+          (is (= {:data "ping"} body))))
 
-      (fact "the api is valid"
-        (validator/validate app) => app)))
+      (testing "the api is valid"
+        (is (= app (validator/validate app))))))
 
-  (fact "a swagger api with invalid swagger records"
+  (testing "a swagger api with invalid swagger records"
     (let [app (api
                 (swagger-routes)
                 (GET "/ping" []
                   :return NonSwaggerRecord
                   (ok (->NonSwaggerRecord "ping"))))]
 
-      (fact "works"
+      (testing "works"
         (let [[status body] (get* app "/ping")]
-          status => 200
-          body => {:data "ping"}))
-
-      (fact "the api is invalid"
-        (validator/validate app)
-        => (throws
-             IllegalArgumentException
-             (str
-               "don't know how to convert class compojure.api.integration_test.NonSwaggerRecord "
-               "into a Swagger Schema. Check out ring-swagger docs for details.")))))
-
-  (fact "a non-swagger api with invalid swagger records"
+          (is-200-status status)
+          (is (= {:data "ping"} body))))
+
+      (testing "the api is invalid"
+        (is (thrown-with-msg?
+              IllegalArgumentException
+              #"don't know how to convert class compojure.api.integration_test.NonSwaggerRecord into a Swagger Schema. Check out ring-swagger docs for details."
+              (validator/validate app))))))
+
+  (testing "a non-swagger api with invalid swagger records"
     (let [app (api
                 (GET "/ping" []
                   :return NonSwaggerRecord
                   (ok (->NonSwaggerRecord "ping"))))]
 
-      (fact "works"
+      (testing "works"
         (let [[status body] (get* app "/ping")]
-          status => 200
-          body => {:data "ping"}))
+          (is-200-status status)
+          (is (= {:data "ping"} body))))
 
-      (fact "the api is valid"
-        (validator/validate app) => app))))
+      (testing "the api is valid"
+        (is (= app (validator/validate app)))))))
 
-(fact "component integration"
+(deftest component-integration-test
   (let [system {:magic 42}]
-    (fact "via options"
+    (testing "via options"
       (let [app (api
                   {:components system}
                   (GET "/magic" []
                     :components [magic]
                     (ok {:magic magic})))]
         (let [[status body] (get* app "/magic")]
-          status => 200
-          body => {:magic 42})))
+          (is-200-status status)
+          (is (= {:magic 42} body)))))
 
-    (fact "via middleware"
+    (testing "via middleware"
       (let [handler (api
                       (GET "/magic" []
                         :components [magic]
                         (ok {:magic magic})))
             app (mw/wrap-components handler system)]
         (let [[status body] (get* app "/magic")]
-          status => 200
-          body => {:magic 42})))))
+          (is-200-status status)
+          (is (= {:magic 42} body)))))))
 
-(fact "sequential string parameters"
+(deftest sequential-string-parameters-test
   (let [app (api
               (GET "/ints" []
                 :query-params [i :- [s/Int]]
                 (ok {:i i})))]
-    (fact "multiple values"
+    (testing "multiple values"
       (let [[status body] (get* app "/ints?i=1&i=2&i=3")]
-        status => 200
-        body => {:i [1, 2, 3]}))
-    (fact "single value"
+        (is-200-status status)
+        (is (= {:i [1, 2, 3]} body))))
+    (testing "single value"
       (let [[status body] (get* app "/ints?i=42")]
-        status => 200
-        body => {:i [42]}))))
+        (is-200-status status)
+        (is (= {:i [42]} body))))))
 
-(fact ":swagger params just for ducumentation"
-  (fact "compile-time values"
+(deftest swagger-params-just-for-documentation-test
+  (testing "compile-time values"
     (let [app (api
                 (swagger-routes)
                 (GET "/route" [q]
@@ -1210,23 +1209,23 @@
                             :parameters {:query {:q s/Bool}}}
                   (ok {:q q})))]
 
-      (fact "there is no coercion"
+      (testing "there is no coercion"
         (let [[status body] (get* app "/route" {:q "kikka"})]
-          status => 200
-          body => {:q "kikka"}))
-
-      (fact "swagger-docs are generated"
-        (-> app get-spec :paths vals first :get)
-        => (contains
-             {:x-name "boolean"
-              :operationId "echoBoolean"
-              :description "Echoes a boolean"
-              :parameters [{:description ""
-                            :in "query"
-                            :name "q"
-                            :required true
-                            :type "boolean"}]}))))
-  (fact "run-time values"
+          (is-200-status status)
+          (is (= {:q "kikka"} body))))
+
+      (testing "swagger-docs are generated"
+        (is (= {:x-name "boolean"
+                :operationId "echoBoolean"
+                :description "Echoes a boolean"
+                :parameters [{:description ""
+                              :in "query"
+                              :name "q"
+                              :required true
+                              :type "boolean"}]}
+               (-> app get-spec :paths vals first :get
+                   (select-keys [:x-name :operationId :description :parameters])))))))
+  (testing "run-time values"
     (let [runtime-data {:x-name :boolean
                         :operationId "echoBoolean"
                         :description "Echoes a boolean"
@@ -1237,24 +1236,25 @@
                   :swagger runtime-data
                   (ok {:q q})))]
 
-      (fact "there is no coercion"
+      (testing "there is no coercion"
         (let [[status body] (get* app "/route" {:q "kikka"})]
-          status => 200
-          body => {:q "kikka"}))
-
-      (fact "swagger-docs are generated"
-        (-> app get-spec :paths vals first :get)
-        => (contains
-             {:x-name "boolean"
-              :operationId "echoBoolean"
-              :description "Echoes a boolean"
-              :parameters [{:description ""
-                            :in "query"
-                            :name "q"
-                            :required true
-                            :type "boolean"}]})))))
-
-(fact "swagger-docs via api options, #218"
+          (is-200-status status)
+          (is (= {:q "kikka"} body))))
+
+      (testing "swagger-docs are generated"
+        (is (= {:x-name "boolean"
+                :operationId "echoBoolean"
+                :description "Echoes a boolean"
+                :parameters [{:description ""
+                              :in "query"
+                              :name "q"
+                              :required true
+                              :type "boolean"}]}
+               (-> app get-spec :paths vals first :get
+                   (select-keys [:x-name :operationId :description :parameters]))))))))
+
+;; swagger-docs via api options, #218
+(deftest swagger-docs-via-api-options
   (let [routes (routes
                  (context "/api" []
                    (GET "/ping" []
@@ -1268,14 +1268,15 @@
         api1 (api {:swagger {:spec "/swagger.json", :ui "/"}} routes)
         api2 (api (swagger-routes) routes)]
 
-    (fact "both generate same swagger-spec"
-      (get-spec api1) => (get-spec api2))
+    (testing "both generate same swagger-spec"
+      (is (= (get-spec api1) (get-spec api2))))
 
-    (fact "not-found handler works"
-      (second (get* api1 "/missed")) => {:message "404"}
-      (second (get* api2 "/missed")) => {:message "404"})))
+    (testing "not-found handler works"
+      (is (= {:message "404"} (second (get* api1 "/missed"))))
+      (is (= {:message "404"} (second (get* api2 "/missed")))))))
 
-(fact "more swagger-data can be (deep-)merged in - either via swagger-docs at runtime via mws, fixes #170"
+;; more swagger-data can be (deep-)merged in - either via swagger-docs at runtime via mws, fixes #170
+(deftest issue-170-test
   (let [app (api
               (route-middleware [[rsm/wrap-swagger-data {:paths {"/runtime" {:get {}}}}]]
                 (swagger-routes
@@ -1283,30 +1284,29 @@
                    {:info {:version "2.0.0"}
                     :paths {"/extra" {:get {}}}}})
                 (GET "/normal" [] (ok))))]
-    (get-spec app) => (contains
-                        {:paths (just
-                                  {"/normal" irrelevant
-                                   "/extra" irrelevant
-                                   "/runtime" irrelevant})})))
+    (is (= #{"/normal" "/extra" "/runtime"}
+           (-> (get-spec app) :paths keys set)))))
 
 
-(fact "handling invalid routes with api"
+(deftest handling-invalid-routes-with-api-test
   (let [invalid-routes (routes (constantly nil))]
 
-    (fact "by default, logs the exception"
-      (api invalid-routes) => truthy
-      (provided
-        (compojure.api.impl.logging/log! :warn irrelevant) => irrelevant :times 1))
+    (testing "by default, logs the exception"
+      (let [a (atom [])]
+        (with-redefs [compojure.api.impl.logging/log! (fn [& args] (swap! a conj args))]
+          (is (api invalid-routes)))
+        (is (= [:warn] (map first @a)))))
 
-    (fact "ignoring invalid routes doesn't log"
-      (api {:api {:invalid-routes-fn nil}} invalid-routes) => truthy
-      (provided
-        (compojure.api.impl.logging/log! :warn irrelevant) => irrelevant :times 0))
+    (testing "ignoring invalid routes doesn't log"
+      (let [a (atom [])]
+        (with-redefs [compojure.api.impl.logging/log! (fn [& args] (swap! a conj args))]
+          (is (api {:api {:invalid-routes-fn nil}} invalid-routes)))
+        (is (empty? @a))))
 
-    (fact "throwing exceptions"
-      (api {:api {:invalid-routes-fn routes/fail-on-invalid-child-routes}} invalid-routes)) => throws))
+    (testing "throwing exceptions"
+      (is (thrown? Exception (api {:api {:invalid-routes-fn routes/fail-on-invalid-child-routes}} invalid-routes))))))
 
-(fact "using local symbols for restructuring params"
+(deftest using-local-symbols-for-restructuring-params-test
   (let [responses {400 {:schema {:fail s/Str}}}
         app (api
               {:swagger {:spec "/swagger.json"
@@ -1319,32 +1319,39 @@
                 :responses (assoc responses 500 {:schema {:m s/Str}})
                 :return {:ok s/Str}
                 (ok)))
-        paths (:paths (get-spec app))]
-
-    (get-in paths ["/a" :get :responses])
-    => (just {:400 (just {:schema anything :description ""})
-              :200 (just {:schema anything :description ""})})
-
-    (get-in paths ["/b" :get :responses])
-    => (just {:400 (just {:schema anything :description ""})
-              :200 (just {:schema anything :description ""})
-              :500 (just {:schema anything :description ""})})))
-
-(fact "when functions are returned"
+        paths (:paths (get-spec app))
+        a-resp (get-in paths ["/a" :get :responses])
+        b-resp (get-in paths ["/b" :get :responses])]
+
+    (is (= #{:200 :400} (-> a-resp keys set)))
+    (is (= #{:schema :description} (-> a-resp :400 keys set)))
+    (is (= #{:schema :description} (-> a-resp :200 keys set)))
+    (is (= "" (-> a-resp :400 :description)))
+    (is (= "" (-> a-resp :200 :description)))
+
+    (is (= #{:200 :400 :500} (-> b-resp keys set)))
+    (is (= #{:schema :description} (-> b-resp :500 keys set)))
+    (is (= #{:schema :description} (-> b-resp :400 keys set)))
+    (is (= #{:schema :description} (-> b-resp :200 keys set)))
+    (is (= "" (-> b-resp :500 :description)))
+    (is (= "" (-> b-resp :400 :description)))
+    (is (= "" (-> b-resp :200 :description)))))
+
+(deftest when-functions-are-returned-test
   (let [wrap-mw-params (fn [handler value]
                          (fn [request]
                            (handler
                              (update request ::mw #(str % value)))))]
-    (fact "from endpoint"
+    (testing "from endpoint"
       (let [app (GET "/ping" []
                   :middleware [[wrap-mw-params "1"]]
                   :query-params [{a :- s/Str "a"}]
                   (fn [req] (str (::mw req) a)))]
 
-        (app {:request-method :get, :uri "/ping", :query-params {}}) => (contains {:body "1a"})
-        (app {:request-method :get, :uri "/ping", :query-params {:a "A"}}) => (contains {:body "1A"})))
+        (is (= "1a" (:body (app {:request-method :get, :uri "/ping", :query-params {}}))))
+        (is (= "1A" (:body (app {:request-method :get, :uri "/ping", :query-params {:a "A"}}))))))
 
-    (fact "from endpoint under context"
+    (testing "from endpoint under context"
       (let [app (context "/api" []
                   :middleware [[wrap-mw-params "1"]]
                   :query-params [{a :- s/Str "a"}]
@@ -1353,9 +1360,9 @@
                     :query-params [{b :- s/Str "b"}]
                     (fn [req] (str (::mw req) a b))))]
 
-        (app {:request-method :get, :uri "/api/ping", :query-params {}}) => (contains {:body "12ab"})
-        (app {:request-method :get, :uri "/api/ping", :query-params {:a "A"}}) => (contains {:body "12Ab"})
-        (app {:request-method :get, :uri "/api/ping", :query-params {:a "A", :b "B"}}) => (contains {:body "12AB"})))))
+        (is (= "12ab" (:body (app {:request-method :get, :uri "/api/ping", :query-params {}}))))
+        (is (= "12Ab" (:body (app {:request-method :get, :uri "/api/ping", :query-params {:a "A"}}))))
+        (is (= "12AB" (:body (app {:request-method :get, :uri "/api/ping", :query-params {:a "A", :b "B"}}))))))))
 
 (defn check-for-response-handler
   "This response-validation handler checks for the existence of :response in its input. If it's there, it
@@ -1365,7 +1372,7 @@
     (ok {:message "Found :response in data!" :attempted-body (get-in data [:response :body])})
     (not-found "No :response key present in data!")))
 
-(fact "response-validation handler has access to response value that failed coercion"
+(deftest response-validation-handler-has-access-to-response-value-that-failed-coercion-test
   (let [incorrect-return-value {:incorrect "response"}
         app (api
               {:exceptions {:handlers {::ex/response-validation check-for-response-handler}}}
@@ -1375,46 +1382,50 @@
                 ; This should fail and trigger our error handler
                 (ok incorrect-return-value)))]
 
-    (fact "return case, valid request & valid model"
+    (testing "return case, valid request & valid model"
       (let [[status body] (get* app "/test-response")]
-        status => 200
-        (:attempted-body body) => incorrect-return-value))))
+        (is-200-status status)
+        (is (= incorrect-return-value (:attempted-body body)))))))
 
-(fact "correct swagger parameter order with small number or parameters, #224"
+;; "correct swagger parameter order with small number or parameters, #224"
+(deftest issue-224-test
   (let [app (api
               (swagger-routes)
               (GET "/ping" []
                 :query-params [a b c d e]
                 (ok {:a a, :b b, :c c, :d d, :e e})))]
-    (fact "api works"
+    (testing "api works"
       (let [[status body] (get* app "/ping" {:a "A" :b "B" :c "C" :d "D" :e "E"})]
-        status => 200
-        body => {:a "A" :b "B" :c "C" :d "D" :e "E"}))
-    (fact "swagger parameters are in correct order"
-      (-> app get-spec :paths (get "/ping") :get :parameters (->> (map (comp keyword :name)))) => [:a :b :c :d :e])))
-
-(fact "empty top-level route, #https://github.com/metosin/ring-swagger/issues/92"
+        (is-200-status status)
+        (is (= {:a "A" :b "B" :c "C" :d "D" :e "E"} body))))
+    (testing "swagger parameters are in correct order"
+      (is (= [:a :b :c :d :e]
+             (-> app get-spec :paths (get "/ping") :get :parameters (->> (map (comp keyword :name)))))))))
+
+;; empty top-level route, #https://github.com/metosin/ring-swagger/issues/92
+(deftest issue-92-test 
   (let [app (api
               {:swagger {:spec "/swagger.json"}}
               (GET "/" [] (ok {:kikka "kukka"})))]
-    (fact "api works"
+    (testing "api works"
       (let [[status body] (get* app "/")]
-        status => 200
-        body => {:kikka "kukka"}))
-    (fact "swagger docs"
-      (-> app get-spec :paths keys) => ["/"])))
+        (is-200-status status)
+        (is (= {:kikka "kukka"} body))))
+    (testing "swagger docs"
+      (is (= ["/"] (-> app get-spec :paths keys))))))
 
-(fact "describe works on anonymous bodys, #168"
+;; describe works on anonymous bodys, #168
+(deftest issue-168-test
   (let [app (api
               (swagger-routes)
               (POST "/" []
                 :body [body (describe {:kikka [{:kukka String}]} "kikkas")]
                 (ok body)))]
-    (fact "description is in place"
-      (-> app get-spec :paths (get "/") :post :parameters first)
-      => (contains {:description "kikkas"}))))
+    (testing "description is in place"
+      (is (= "kikkas" (-> app get-spec :paths (get "/") :post :parameters first :description))))))
 
-(facts "swagger responses headers are mapped correctly, #232"
+;; swagger responses headers are mapped correctly, #232
+(deftest issue-232-test
   (let [app (api
               (swagger-routes)
               (context "/resource" []
@@ -1422,25 +1433,26 @@
                   {:get {:responses {200 {:schema {:size s/Str}
                                           :description "size"
                                           :headers {"X-men" (describe s/Str "mutant")}}}}})))]
-    (-> app get-spec :paths vals first :get :responses :200 :headers)
-    => {:X-men {:description "mutant", :type "string"}}))
+    (is (= {:X-men {:description "mutant", :type "string"}}
+           (-> app get-spec :paths vals first :get :responses :200 :headers)))))
 
-(facts "api-middleware can be disabled"
+(deftest api-middleware-can-be-disabled-test
   (let [app (api
               {:api {:disable-api-middleware? true}}
               (swagger-routes)
               (GET "/params" [x] (ok {:x x}))
               (GET "/throw" [] (throw (RuntimeException. "kosh"))))]
 
-    (fact "json-parsing & wrap-params is off"
+    (testing "json-parsing & wrap-params is off"
       (let [[status body] (raw-get* app "/params" {:x 1})]
-        status => 200
-        body => {:x nil}))
+        (is-200-status status)
+        (is (= {:x nil} body))))
 
-    (fact "exceptions are not caught"
-      (raw-get* app "/throw") => throws)))
+    (testing "exceptions are not caught"
+      (is (thrown? Exception (raw-get* app "/throw"))))))
 
-(facts "custom formats contribute to Swagger :consumes & :produces"
+;"custom formats contribute to Swagger :consumes & :produces"
+(deftest custom-formats-contribute-to-Swagger-consumes-produces-test
   (let [custom-type "application/vnd.vendor.v1+json"
         app (api
               {:swagger {:spec "/swagger.json"}
@@ -1451,32 +1463,34 @@
                 :body [data {:kikka s/Str}]
                 (ok data)))]
 
-    (fact "it works"
+    (testing "it works"
       (let [response (app {:uri "/echo"
                            :request-method :post
                            :body (json-stream {:kikka "kukka"})
                            :headers {"content-type" "application/vnd.vendor.v1+json"
                                      "accept" "application/vnd.vendor.v1+json"}})]
 
-        (-> response :body slurp) => (json-string {:kikka "kukka"})
-        (-> response :headers) => (contains {"Content-Type" "application/vnd.vendor.v1+json; charset=utf-8"})))
+        (is (= (json-string {:kikka "kukka"}) (-> response :body slurp)))
+        (is (= "application/vnd.vendor.v1+json; charset=utf-8"
+               (-> response :headers (get "Content-Type"))))))
 
-    (fact "spec is correct"
-      (get-spec app)
-      => (contains
-           {:produces (just ["application/vnd.vendor.v1+json" "application/json"] :in-any-order)
-            :consumes (just ["application/vnd.vendor.v1+json" "application/json"] :in-any-order)}))))
+    (testing "spec is correct"
+      (let [res (get-spec app)]
+        (is (= (sort ["application/vnd.vendor.v1+json" "application/json"])
+               (-> res :produces sort)))
+        (is (= (sort ["application/vnd.vendor.v1+json" "application/json"])
+               (-> res :consumes sort)))))))
 
-(facts "muuntaja is bound in request"
+(deftest muuntaja-is-bound-in-request-test
   (let [app (api
               (GET "/ping" {:keys [::request/muuntaja]}
                 (ok {:pong (slurp (m/encode muuntaja "application/json" {:is "json"}))})))]
 
     (let [[status body] (get* app "/ping")]
-      status => 200
-      body => {:pong "{\"is\":\"json\"}"})))
+      (is-200-status status)
+      (is (= {:pong "{\"is\":\"json\"}"} body)))))
 
-(facts ":body doesn't keywordize keys"
+(deftest body-doesnt-keywordize-keys-test
   (let [m (m/create)
         data {:items {"kikka" 42}}
         body* (atom nil)
@@ -1491,23 +1505,23 @@
                 (reset! body* body)
                 (ok)))]
 
-    (facts ":body-params keywordizes params"
-      (app {:uri "/echo"
-            :request-method :post
-            :body (m/encode m "application/transit+json" data)
-            :headers {"content-type" "application/transit+json"
-                      "accept" "application/transit+json"}}) => http/ok?
-      @body* => {:items {:kikka 42}})
-
-    (facts ":body does not keywordizes params"
-      (app {:uri "/echo2"
-            :request-method :post
-            :body (m/encode m "application/transit+json" data)
-            :headers {"content-type" "application/transit+json"
-                      "accept" "application/transit+json"}}) => http/ok?
-      @body* => {:items {"kikka" 42}})
-
-    (facts "swagger spec is generated both ways"
+    (testing ":body-params keywordizes params"
+      (is (http/ok? (app {:uri "/echo"
+                          :request-method :post
+                          :body (m/encode m "application/transit+json" data)
+                          :headers {"content-type" "application/transit+json"
+                                    "accept" "application/transit+json"}})))
+       (is (= {:items {:kikka 42}} @body*)))
+
+    (testing ":body does not keywordizes params"
+      (is (http/ok? (app {:uri "/echo2"
+                          :request-method :post
+                          :body (m/encode m "application/transit+json" data)
+                          :headers {"content-type" "application/transit+json"
+                                    "accept" "application/transit+json"}})))
+      (is (= {:items {"kikka" 42}} @body*)))
+
+    (testing "swagger spec is generated both ways"
       (let [spec (get-spec app)
             echo-schema-name (-> (get-in spec [:paths "/echo" :post :parameters 0 :name])
                                  name (str "Items") keyword)
@@ -1515,16 +1529,16 @@
                                   name (str "Items") keyword)
             echo-schema (get-in spec [:definitions echo-schema-name :properties])
             echo2-schema (get-in spec [:definitions echo2-schema-name :properties])]
-        echo-schema => {:kikka {:type "integer", :format "int64"}}
-        echo2-schema => {:kikka {:type "integer", :format "int64"}}))))
+        (is (= {:kikka {:type "integer", :format "int64"}} echo-schema))
+        (is (= {:kikka {:type "integer", :format "int64"}} echo2-schema))))))
 
 
 (def ^:dynamic *response* nil)
 
-(facts "format-based body & response coercion"
+(deftest format-based-body-and-response-coercion-test
   (let [m (mw/create-muuntaja)]
 
-    (facts "application/transit & application/edn validate request & response (no coercion)"
+    (testing "application/transit & application/edn validate request & response (no coercion)"
       (let [valid-data {:items {"kikka" :kukka}}
             invalid-data {"items" {"kikka" :kukka}}
             Schema {:items {(s/required-key "kikka") s/Keyword}}
@@ -1535,22 +1549,22 @@
                     (ok *response*)))]
 
         (doseq [format ["application/transit+json" "application/edn"]]
-          (fact {:midje/description format}
+          (testing format
 
-            (fact "fails with invalid body"
-              (app (ring-request m format invalid-data)) => http/bad-request?)
+            (testing "fails with invalid body"
+              (is (http/bad-request? (app (ring-request m format invalid-data)))))
 
-            (fact "fails with invalid response"
+            (testing "fails with invalid response"
               (binding [*response* invalid-data]
-                (app (ring-request m format valid-data)) => http/internal-server-error?))
+                (is (http/internal-server-error? (app (ring-request m format valid-data))))))
 
-            (fact "succeeds with valid body & response"
+            (testing "succeeds with valid body & response"
               (binding [*response* valid-data]
                 (let [response (app (ring-request m format valid-data))]
-                  response => http/ok?
-                  (m/decode m format (:body response)) => valid-data)))))))
+                  (is (http/ok? response))
+                  (is (= valid-data (m/decode m format (:body response)))))))))))
 
-    (facts "application/json - coerce request, validate response"
+    (testing "application/json - coerce request, validate response"
       (let [valid-data {:int 1, :keyword "kikka"}
             valid-response-data {:int 1, :keyword :kikka}
             invalid-data {:int "1", :keyword "kikka"}
@@ -1562,43 +1576,43 @@
                     (ok *response*)))]
 
         (doseq [format ["application/json"]]
-          (fact {:midje/description format}
+          (testing format
 
-            (fact "fails with invalid body"
-              (app (ring-request m format invalid-data)) => http/bad-request?)
+            (testing "fails with invalid body"
+              (is (http/bad-request? (app (ring-request m format invalid-data)))))
 
-            (fact "fails with invalid response"
+            (testing "fails with invalid response"
               (binding [*response* invalid-data]
-                (app (ring-request m format valid-data)) => http/internal-server-error?))
+                (is (http/internal-server-error? (app (ring-request m format valid-data))))))
 
-            (fact "does not coerce response"
+            (testing "does not coerce response"
               (binding [*response* valid-data]
-                (app (ring-request m format valid-data)) => http/internal-server-error?))
+                (is (http/internal-server-error? (app (ring-request m format valid-data))))))
 
-            (fact "succeeds with valid body & response"
+            (testing "succeeds with valid body & response"
               (binding [*response* valid-response-data]
                 (let [response (app (ring-request m format valid-data))]
-                  response => http/ok?
-                  (m/decode m format (:body response)) => valid-data)))))))))
+                  (is (http/ok? response))
+                  (is (= valid-data (m/decode m format (:body response)))))))))))))
 
-(fact "static contexts just work"
+(deftest static-contexts-just-work-test
   (let [app (context "/:a" [a]
               (GET "/:b" [b]
                 (ok [a b])))]
-    (app {:request-method :get, :uri "/a/b"}) => (contains {:body ["a" "b"]})
-    (app {:request-method :get, :uri "/b/c"}) => (contains {:body ["b" "c"]})))
+    (is (= ["a" "b"] (:body (app {:request-method :get, :uri "/a/b"}))))
+    (is (= ["b" "c"] (:body (app {:request-method :get, :uri "/b/c"}))))))
 
-(facts "file responses don't get coerced"
+(deftest file-responses-dont-get-coerced-test
   (let [app (api
               (swagger-routes)
               (GET "/file" []
                 :return File
                 (ok (io/file "project.clj"))))]
     (let [{:keys [status body]} (app {:uri "/file", :request-method :get})]
-      status => 200
-      body => (partial instance? File))))
+      (is-200-status status)
+      (is (instance? File body)))))
 
-(fact "nil routes are ignored"
+(deftest nil-routes-are-ignored-test
   (let [create-app (fn [{:keys [dev?]}]
                      (context "/api" []
                        (GET "/ping" [] (ok))
@@ -1609,20 +1623,20 @@
                          (context "/dev" []
                            (GET "/tools" [] (ok))))))]
 
-    (facts "with routes"
+    (testing "with routes"
       (let [app (create-app {:dev? true})]
-        (app {:request-method :get, :uri "/api/ping"}) => http/ok?
-        (app {:request-method :get, :uri "/api/db/drop"}) => http/ok?
-        (app {:request-method :get, :uri "/api/dev/tools"}) => http/ok?))
+        (is (http/ok? (app {:request-method :get, :uri "/api/ping"})))
+        (is (http/ok? (app {:request-method :get, :uri "/api/db/drop"})))
+        (is (http/ok? (app {:request-method :get, :uri "/api/dev/tools"})))))
 
-    (facts "without routes"
+    (testing "without routes"
       (let [app (create-app {:dev? false})]
-        (app {:request-method :get, :uri "/api/ping"}) => http/ok?
-        (app {:request-method :get, :uri "/api/db/drop"}) => nil
-        (app {:request-method :get, :uri "/api/dev/tools"}) => nil))))
+        (is (http/ok? (app {:request-method :get, :uri "/api/ping"})))
+        (is (nil? (app {:request-method :get, :uri "/api/db/drop"})))
+        (is (nil? (app {:request-method :get, :uri "/api/dev/tools"})))))))
 
-(facts "wrap-routes"
-  (fact "simple middleware"
+(deftest wrap-routes-test
+  (testing "simple middleware"
     (let [called? (atom false)
           app (api
                 (route-middleware
@@ -1636,17 +1650,17 @@
                   (ok {:ok true})))
           response (app {:uri "/a"
                          :request-method :get})]
-      (-> response :body slurp) => (json-string {:ok true})
-      (fact "middleware is called"
-        @called? => truthy)
+      (is (= (json-string {:ok true}) (-> response :body slurp)))
+      (testing "middleware is called"
+        (is @called?))
 
       (reset! called? false)
       (let [response (app {:uri "/b"
                            :request-method :get})]
-        (-> response :body slurp) => (json-string {:ok true})
-        @called? => falsey)))
+        (is (= (json-string {:ok true}) (-> response :body slurp)))
+        (is (not @called?)))))
 
-  (fact "middleware with args"
+  (testing "middleware with args"
     (let [mw-value (atom nil)
           app (api
                 (route-middleware
@@ -1661,33 +1675,34 @@
                   (ok {:ok true})))
           response (app {:uri "/a"
                          :request-method :get})]
-      (-> response :body slurp) => (json-string {:ok true})
-      (fact "middleware is called"
-        @mw-value => :foo-bar)
+      (is (= (json-string {:ok true}) (-> response :body slurp)))
+      (testing "middleware is called"
+        (is (= :foo-bar @mw-value)))
 
       (reset! mw-value nil)
       (let [response (app {:uri "/b"
                            :request-method :get})]
-        (-> response :body slurp) => (json-string {:ok true})
-        @mw-value => nil))))
+        (is (= (json-string {:ok true}) (-> response :body slurp)))
+        (is (nil? @mw-value))))))
 
-(facts "ring-handler"
+(deftest ring-handler-test
   (let [app (api (GET "/ping" [] (ok)))
         ring-app (c/ring-handler app)]
-    (fact "both work"
-      (get* app "/ping") => (contains 200)
-      (get* ring-app "/ping") => (contains 200))
-    (fact "ring-app is also a Fn"
-      app =not=> fn?
-      ring-app => fn?)))
-
-(fact ":body-params are set to :params"
+    (testing "both work"
+      (is (some #{200} (get* app "/ping")))
+      (is (some #{200} (get* ring-app "/ping"))))
+    (testing "ring-app is also a Fn"
+      (is (not (fn? app)))
+      (is (fn? ring-app)))))
+
+(deftest body-params-are-set-to-params-test
   (let [app (api (POST "/echo" [x] (ok {:x x})))
         [status body] (post* app "/echo" (json-string {:x 1}))]
-    status => 200
-    body => {:x 1}))
+    (is-200-status status)
+    (is (= {:x 1} body))))
 
-(facts "body in error handling, #306 & #313"
+;; #306 & #313"
+(deftest body-in-error-handling-test
   (let [app (api
               {:exceptions
                {:handlers
@@ -1697,45 +1712,45 @@
               (POST "/error" []
                 (throw (RuntimeException. "error"))))
         [status body] (post* app "/error" (json-string {:kikka 6}))]
-    status => 500
-    body => {:kikka 6}))
+    (is (= 500 status))
+    (is (= {:kikka 6} body))))
 
-(fact "sequential routes"
+(deftest sequential-routes-test
 
-  (fact "context"
+  (testing "context"
     (let [app (api
                 (context "/api" []
                   (for [path ["/ping" "/pong"]]
                     (GET path [] (ok {:path path})))))]
 
-      (fact "all routes can be invoked"
+      (testing "all routes can be invoked"
         (let [[status body] (get* app "/api/ping")]
-          status => 200
-          body => {:path "/ping"})
+          (is-200-status status)
+          (is (= {:path "/ping"} body)))
 
         (let [[status body] (get* app "/api/pong")]
-          status => 200
-          body => {:path "/pong"}))))
+          (is-200-status status)
+          (is (= {:path "/pong"} body))))))
 
-  (fact "routes"
+  (testing "routes"
     (let [app (api
                 (routes
                   (for [path ["/ping" "/pong"]]
                     (GET path [] (ok {:path path})))))]
 
-      (fact "all routes can be invoked"
+      (testing "all routes can be invoked"
         (let [[status body] (get* app "/ping")]
-          status => 200
-          body => {:path "/ping"})
+          (is-200-status status)
+          (is (= {:path "/ping"} body)))
 
         (let [[status body] (get* app "/pong")]
-          status => 200
-          body => {:path "/pong"})))))
+          (is-200-status status)
+          (is (= {:path "/pong"} body)))))))
 
-(fact "wrap-format, #374"
+(deftest wrap-format-issue-374-test
   (let [data {:war "hammer"}]
 
-    (fact "first api consumes the body"
+    (testing "first api consumes the body"
       (let [app (routes
                   (api
                     (POST "/echo1" []
@@ -1746,16 +1761,16 @@
                       :body [body s/Any]
                       (ok body))))]
 
-        (fact "first api sees the body"
+        (testing "first api sees the body"
           (let [[status body] (post* app "/echo1" (json-string data))]
-            status => 200
-            body => data))
+            (is-200-status status)
+            (is (= data body))))
 
-        (fact "second api fails"
+        (testing "second api fails"
           (let [[status] (post* app "/echo2" (json-string data))]
-            status => 400)))
+            (is (= 400 status)))))
 
-      (fact "wrap-format with defaults"
+      (testing "wrap-format with defaults"
         (let [app (-> (routes
                         (api
                           (POST "/echo1" []
@@ -1768,17 +1783,17 @@
                             (ok body))))
                       (mw/wrap-format))]
 
-          (fact "first api sees the body"
+          (testing "first api sees the body"
             (let [[status body] (post* app "/echo1" (json-string data))]
-              status => 200
-              body => data))
+              (is-200-status status)
+              (is (= data body))))
 
-          (fact "second api sees it too!"
+          (testing "second api sees it too!"
             (let [[status body] (post* app "/echo2" (json-string data))]
-              status => 200
-              body => data))))
+              (is-200-status status)
+              (is (= data body))))))
 
-      (fact "wrap-format with configuration"
+      (testing "wrap-format with configuration"
         (let [muuntaja (m/create
                          (m/select-formats
                            m/default-options
@@ -1799,34 +1814,35 @@
                       (mw/wrap-format
                         {:formats muuntaja}))]
 
-          (fact "first api sees the body"
+          (testing "first api sees the body"
             (let [[status body] (post* app "/echo1" (json-string data))]
-              status => 200
-              body => data))
+              (is-200-status status)
+              (is (= data body))))
 
-          (fact "second api sees it too!"
+          (testing "second api sees it too!"
             (let [[status body] (post* app "/echo2" (json-string data))]
-              status => 200
-              body => data))
+              (is-200-status status)
+              (is (= data body))))
 
-          (fact "top-level muuntaja effect both"
+          (testing "top-level muuntaja effect both"
             (let [[status body] (get* app "/swagger1.json")]
-              status => 200
-              body => (contains
-                        {:produces ["application/json"]
-                         :consumes ["application/json"]}))
+              (is-200-status status)
+              (is (= {:produces ["application/json"]
+                      :consumes ["application/json"]}
+                     (select-keys body [:produces :consumes]))))
             (let [[status body] (get* app "/swagger2.json")]
-              status => 200
-              body => (contains
-                        {:produces ["application/json"]
-                         :consumes ["application/json"]}))))))))
+              (is-200-status status)
+              (is (= {:produces ["application/json"]
+                      :consumes ["application/json"]}
+                     (select-keys body [:produces :consumes]))))))))))
 
-(fact "2.* will fail fast with :format"
+;;"2.* will fail fast with :format"
+(deftest compojure-2x-will-fail-fast-with-format-test 
   (let [app' `(api {:format (m/create)})]
-    (eval app') => (throws AssertionError)))
+    (is (thrown? AssertionError (eval app')))))
 
-(fact "Muuntaja 0.6.0 options"
-  (fact "new formats"
+(deftest Muuntaja-0-6-0-options-test
+  (testing "new formats"
     (let [muuntaja (m/create
                      (-> m/default-options
                          (m/install muuntaja.format.msgpack/format)
@@ -1843,12 +1859,12 @@
                       "application/x-yaml"
                       "application/transit+json"
                       "application/transit+msgpack"]]
-        (fact {:midje/description (str "format " (pr-str format))}
+        (testing (str "format " (pr-str format))
           (let [{:keys [status body]} (app (ring-request muuntaja format data))]
-            status => 200
-            (m/decode muuntaja format body) => data)))))
+            (is-200-status status)
+            (is (= data (m/decode muuntaja format body))))))))
 
-  (fact "return types"
+  (testing "return types"
     (doseq [[return type] {:input-stream ByteArrayInputStream
                            :bytes (class (make-array Byte/TYPE 0))
                            :output-stream StreamableResponse}]
@@ -1856,7 +1872,7 @@
                   {:formats (assoc m/default-options :return return)}
                   (GET "/" []
                     (ok {:kikka "kukka"})))]
-        (fact {:midje/description (str "return " (pr-str return))}
+        (testing (str "return " (pr-str return))
           (let [{:keys [status body]} (app {:uri "/", :request-method :get})]
-            status => 200
-            body => (partial instance? type)))))))
+            (is-200-status status)
+            (is (instance? type body))))))))
diff --git a/test/compojure/api/middleware_test.clj b/test/compojure/api/middleware_test.clj
index c06e0bc9..8b0d6b49 100644
--- a/test/compojure/api/middleware_test.clj
+++ b/test/compojure/api/middleware_test.clj
@@ -1,7 +1,7 @@
 (ns compojure.api.middleware-test
   (:require [compojure.api.middleware :refer :all]
             [compojure.api.exception :as ex]
-            [midje.sweet :refer :all]
+            [clojure.test :refer [deftest is testing]]
             [ring.util.http-response :refer [ok]]
             [ring.util.http-status :as status]
             [ring.util.test])
@@ -20,24 +20,23 @@
        (finally
          (System/setErr err#)))))
 
-(facts encode?
-  (tabular
-    (fact
-      (encode? nil
-               {:body ?body
-                :compojure.api.meta/serializable? ?serializable?}) => ?res)
-    ?body ?serializable? ?res
-    5 true true
-    5 false false
-    "foobar" true true
-    "foobar" false false
+(deftest encode?-test
+  (doseq [[?body ?serializable? ?res :as test-case]
+          [[5 true true]
+           [5 false false]
+           ["foobar" true true]
+           ["foobar" false false]
+           [{:foobar "1"} false true]
+           [{:foobar "1"} true true]
+           [[1 2 3] false true]
+           [[1 2 3] true true]
+           [(ring.util.test/string-input-stream "foobar") false false]]]
 
-    {:foobar "1"} false true
-    {:foobar "1"} true true
-    [1 2 3] false true
-    [1 2 3] true true
-
-    (ring.util.test/string-input-stream "foobar") false false))
+    (testing (pr-str test-case)
+      (is (= (encode? nil
+                      {:body ?body
+                       :compojure.api.meta/serializable? ?serializable?})
+             ?res)))))
 
 (def default-options (:exceptions api-middleware-defaults))
 
@@ -50,7 +49,7 @@
         (throw value))
       (throw (Exception. "Timeout while waiting for the request handler.")))))
 
-(facts "wrap-exceptions"
+(deftest wrap-exceptions-test
   (with-out-str
     (without-err
       (let [exception (RuntimeException. "kosh")
@@ -60,42 +59,47 @@
             async-handler (-> (fn [_ _ raise] (raise exception))
                               (wrap-exceptions default-options))]
 
-        (fact "converts exceptions into safe internal server errors"
-          (handler {}) => (contains {:status status/internal-server-error
-                                     :body (contains {:class exception-class
-                                                      :type "unknown-exception"})})
-          (call-async async-handler {}) => (contains {:status status/internal-server-error
-                                                      :body (contains {:class exception-class
-                                                                       :type "unknown-exception"})})))))
+        (testing "converts exceptions into safe internal server errors"
+          (is (= {:status status/internal-server-error
+                  :body {:class exception-class
+                         :type "unknown-exception"}}
+                 (-> (handler {})
+                     (select-keys [:status :body]))))
+          (is (= {:status status/internal-server-error
+                  :body {:class exception-class
+                         :type "unknown-exception"}}
+                 (-> (call-async async-handler {})
+                     (select-keys [:status :body]))))))))
 
   (with-out-str
     (without-err
-      (fact "Thrown ex-info type can be matched"
+      (testing "Thrown ex-info type can be matched"
         (let [handler (-> (fn [_] (throw (ex-info "kosh" {:type ::test})))
                           (wrap-exceptions (assoc-in default-options [:handlers ::test] (fn [ex _ _] {:status 500 :body "hello"}))))]
-          (handler {}) => (contains {:status status/internal-server-error
-                                     :body "hello"})))))
+          (is (= {:status status/internal-server-error
+                  :body "hello"}
+                 (select-keys (handler {}) [:status :body])))))))
 
   (without-err
-    (fact "Default handler logs exceptions to console"
+    (testing "Default handler logs exceptions to console"
       (let [handler (-> (fn [_] (throw (RuntimeException. "kosh")))
                         (wrap-exceptions default-options))]
-        (with-out-str (handler {})) => "ERROR kosh\n")))
+        (is (= "ERROR kosh\n" (with-out-str (handler {})))))))
 
   (without-err
-    (fact "Default request-parsing handler does not log messages"
+    (testing "Default request-parsing handler does not log messages"
       (let [handler (-> (fn [_] (throw (ex-info "Error parsing request" {:type ::ex/request-parsing} (RuntimeException. "Kosh"))))
                         (wrap-exceptions default-options))]
-        (with-out-str (handler {})) => "")))
+        (is (= "" (with-out-str (handler {})))))))
 
   (without-err
-    (fact "Logging can be added to a exception handler"
+    (testing "Logging can be added to a exception handler"
       (let [handler (-> (fn [_] (throw (ex-info "Error parsing request" {:type ::ex/request-parsing} (RuntimeException. "Kosh"))))
                         (wrap-exceptions (assoc-in default-options [:handlers ::ex/request-parsing] (ex/with-logging ex/request-parsing-handler :info))))]
-        (with-out-str (handler {})) => "INFO Error parsing request\n"))))
+        (is (= "INFO Error parsing request\n" (with-out-str (handler {}))))))))
 
-(facts "compose-middeleware strips nils aways. #228"
+(deftest issue-228-test ; "compose-middeleware strips nils aways. #228"
   (let [times2-mw (fn [handler]
                     (fn [request]
                       (* 2 (handler request))))]
-    (((compose-middleware [nil times2-mw nil]) (constantly 3)) anything) => 6))
+    (is (= 6 (((compose-middleware [nil times2-mw nil]) (constantly 3)) nil)))))
diff --git a/test/compojure/api/resource_test.clj b/test/compojure/api/resource_test.clj
index d57e7e30..450f3aed 100644
--- a/test/compojure/api/resource_test.clj
+++ b/test/compojure/api/resource_test.clj
@@ -2,60 +2,59 @@
   (:require [compojure.api.sweet :refer :all]
             [compojure.api.test-utils :refer :all]
             [plumbing.core :refer [fnk]]
-            [midje.sweet :refer :all]
+            [clojure.test :refer [deftest is testing]]
             [ring.util.http-response :refer :all]
             [clojure.core.async :as a]
             [schema.core :as s]
             [compojure.api.test-utils :refer [call]])
   (:import (clojure.lang ExceptionInfo)))
 
-(defn has-body [expected]
-  (fn [{:keys [body]}]
-    (= body expected)))
+(defn is-has-body [expected {:keys [body]}]
+  (is (= body expected)))
 
-(def request-validation-failed?
-  (throws ExceptionInfo #"Request validation failed"))
+(defmacro is-request-validation-failed? [form]
+  `(is (~'thrown? ExceptionInfo #"Request validation failed" ~form)))
 
-(def response-validation-failed?
-  (throws ExceptionInfo #"Response validation failed"))
+(defmacro is-response-validation-failed? [form]
+  `(is (~'thrown? ExceptionInfo #"Response validation failed" ~form)))
 
-(facts "resource definitions"
+(deftest resource-definitions-test
 
-  (fact "only top-level handler"
+  (testing "only top-level handler"
     (let [handler (resource
                     {:handler (constantly (ok {:total 10}))})]
 
-      (fact "paths and methods don't matter"
-        (call handler {:request-method :get, :uri "/"}) => (has-body {:total 10})
-        (call handler {:request-method :head, :uri "/kikka"}) => (has-body {:total 10}))))
+      (testing "paths and methods don't matter"
+        (is-has-body {:total 10} (call handler {:request-method :get, :uri "/"}))
+        (is-has-body {:total 10} (call handler {:request-method :head, :uri "/kikka"})))))
 
-  (fact "top-level parameter coercions"
+  (testing "top-level parameter coercions"
     (let [handler (resource
                     {:parameters {:query-params {:x Long}}
                      :handler (fnk [[:query-params x]]
                                 (ok {:total x}))})]
 
-      (call handler {:request-method :get}) => request-validation-failed?
-      (call handler {:request-method :get, :query-params {:x "1"}}) => (has-body {:total 1})
-      (call handler {:request-method :get, :query-params {:x "1", :y "2"}}) => (has-body {:total 1})))
+      (is-request-validation-failed? (call handler {:request-method :get}))
+      (is-has-body {:total 1} (call handler {:request-method :get, :query-params {:x "1"}}))
+      (is-has-body {:total 1} (call handler {:request-method :get, :query-params {:x "1", :y "2"}}))))
 
-  (fact "top-level and operation-level parameter coercions"
+  (testing "top-level and operation-level parameter coercions"
     (let [handler (resource
                     {:parameters {:query-params {:x Long}}
                      :get {:parameters {:query-params {(s/optional-key :y) Long}}}
                      :handler (fnk [[:query-params x {y 0}]]
                                 (ok {:total (+ x y)}))})]
 
-      (call handler {:request-method :get}) => request-validation-failed?
-      (call handler {:request-method :get, :query-params {:x "1"}}) => (has-body {:total 1})
-      (call handler {:request-method :get, :query-params {:x "1", :y "a"}}) => request-validation-failed?
-      (call handler {:request-method :get, :query-params {:x "1", :y "2"}}) => (has-body {:total 3})
+      (is-request-validation-failed? (call handler {:request-method :get}))
+      (is-has-body {:total 1} (call handler {:request-method :get, :query-params {:x "1"}}))
+      (is-request-validation-failed? (call handler {:request-method :get, :query-params {:x "1", :y "a"}}))
+      (is-has-body {:total 3} (call handler {:request-method :get, :query-params {:x "1", :y "2"}}))
 
-      (fact "non-matching operation level parameters are not used"
-        (call handler {:request-method :post, :query-params {:x "1"}}) => (has-body {:total 1})
-        (call handler {:request-method :post, :query-params {:x "1", :y "2"}}) => (throws ClassCastException))))
+      (testing "non-matching operation level parameters are not used"
+        (is-has-body {:total 1} (call handler {:request-method :post, :query-params {:x "1"}}))
+        (is (thrown? ClassCastException (call handler {:request-method :post, :query-params {:x "1", :y "2"}}))))))
 
-  (fact "middleware"
+  (testing "middleware"
     (let [mw (fn [handler k] (fn [req] (update-in (handler req) [:body :mw] (fnil conj '()) k)))
           handler (resource
                     {:middleware [[mw :top1] [mw :top2]]
@@ -63,13 +62,13 @@
                      :post {:middleware [[mw :post1] [mw :post2]]}
                      :handler (constantly (ok))})]
 
-      (fact "top + method-level mw are applied if they are set"
-        (call handler {:request-method :get}) => (has-body {:mw [:top1 :top2 :get1 :get2]})
-        (call handler {:request-method :post}) => (has-body {:mw [:top1 :top2 :post1 :post2]}))
-      (fact "top-level mw are applied if method doesn't have mw"
-        (call handler {:request-method :put}) => (has-body {:mw [:top1 :top2]}))))
+      (testing "top + method-level mw are applied if they are set"
+        (is-has-body {:mw [:top1 :top2 :get1 :get2]} (call handler {:request-method :get}))
+        (is-has-body {:mw [:top1 :top2 :post1 :post2]} (call handler {:request-method :post})))
+      (testing "top-level mw are applied if method doesn't have mw"
+        (is-has-body {:mw [:top1 :top2]} (call handler {:request-method :put})))))
 
-  (fact "operation-level handlers"
+  (testing "operation-level handlers"
     (let [handler (resource
                     {:parameters {:query-params {:x Long}}
                      :get {:parameters {:query-params {(s/optional-key :y) Long}}
@@ -77,23 +76,23 @@
                                       (ok {:total (+ x y)}))}
                      :post {:parameters {:query-params {:z Long}}}})]
 
-      (call handler {:request-method :get}) => request-validation-failed?
-      (call handler {:request-method :get, :query-params {:x "1"}}) => (has-body {:total 1})
-      (call handler {:request-method :get, :query-params {:x "1", :y "a"}}) => request-validation-failed?
-      (call handler {:request-method :get, :query-params {:x "1", :y "2"}}) => (has-body {:total 3})
+      (is-request-validation-failed? (call handler {:request-method :get}))
+      (is-has-body {:total 1} (call handler {:request-method :get, :query-params {:x "1"}}))
+      (is-request-validation-failed? (call handler {:request-method :get, :query-params {:x "1", :y "a"}}))
+      (is-has-body {:total 3} (call handler {:request-method :get, :query-params {:x "1", :y "2"}}))
 
-      (fact "if no handler is found, nil is returned"
-        (call handler {:request-method :post, :query-params {:x "1"}}) => nil)))
+      (testing "if no handler is found, nil is returned"
+        (is (nil? (call handler {:request-method :post, :query-params {:x "1"}}))))))
 
-  (fact "handler preference"
+  (testing "handler preference"
     (let [handler (resource
                     {:get {:handler (constantly (ok {:from "get"}))}
                      :handler (constantly (ok {:from "top"}))})]
 
-      (call handler {:request-method :get}) => (has-body {:from "get"})
-      (call handler {:request-method :post}) => (has-body {:from "top"})))
+      (is-has-body {:from "get"} (call handler {:request-method :get}))
+      (is-has-body {:from "top"} (call handler {:request-method :post}))))
 
-  (fact "resource without coercion"
+  (testing "resource without coercion"
     (let [handler (resource
                     {:coercion nil
                      :get {:parameters {:query-params {(s/optional-key :y) Long
@@ -102,12 +101,12 @@
                                       (ok {:x x
                                            :y y}))}})]
 
-      (call handler {:request-method :get}) => (has-body {:x nil, :y nil})
-      (call handler {:request-method :get, :query-params {:x "1"}}) => (has-body {:x "1", :y nil})
-      (call handler {:request-method :get, :query-params {:x "1", :y "a"}}) => (has-body {:x "1", :y "a"})
-      (call handler {:request-method :get, :query-params {:x 1, :y 2}}) => (has-body {:x 1, :y 2})))
-
-  (fact "parameter mappings"
+      (is-has-body {:x nil, :y nil} (call handler {:request-method :get}))
+      (is-has-body {:x "1", :y nil} (call handler {:request-method :get, :query-params {:x "1"}}))
+      (is-has-body {:x "1", :y "a"} (call handler {:request-method :get, :query-params {:x "1", :y "a"}}))
+      (is-has-body {:x 1, :y 2} (call handler {:request-method :get, :query-params {:x 1, :y 2}}))))
+ 
+  (testing "parameter mappings"
     (let [handler (resource
                     {:get {:parameters {:query-params {:q s/Str}
                                         :body-params {:b s/Str}
@@ -121,20 +120,21 @@
                                                                 :header-params
                                                                 :path-params])))}})]
 
-      (call handler {:request-method :get
-                     :query-params {:q "q"}
-                     :body-params {:b "b"}
-                     :form-params {:f "f"}
-                     ;; the ring headers
-                     :headers {"h" "h"}
-                     ;; compojure routing
-                     :route-params {:p "p"}}) => (has-body {:query-params {:q "q"}
-                                                            :body-params {:b "b"}
-                                                            :form-params {:f "f"}
-                                                            :header-params {:h "h"}
-                                                            :path-params {:p "p"}})))
-
-  (fact "response coercion"
+      (is-has-body {:query-params {:q "q"}
+                    :body-params {:b "b"}
+                    :form-params {:f "f"}
+                    :header-params {:h "h"}
+                    :path-params {:p "p"}}
+                   (call handler {:request-method :get
+                                  :query-params {:q "q"}
+                                  :body-params {:b "b"}
+                                  :form-params {:f "f"}
+                                  ;; the ring headers
+                                  :headers {"h" "h"}
+                                  ;; compojure routing
+                                  :route-params {:p "p"}}))))
+
+  (testing "response coercion"
     (let [handler (resource
                     {:responses {200 {:schema {:total (s/constrained Long pos? 'pos)}}}
                      :parameters {:query-params {:x Long}}
@@ -144,13 +144,13 @@
                      :handler (fnk [[:query-params x]]
                                 (ok {:total x}))})]
 
-      (call handler {:request-method :get}) => request-validation-failed?
-      (call handler {:request-method :get, :query-params {:x "-1"}}) => response-validation-failed?
-      (call handler {:request-method :get, :query-params {:x "1"}}) => response-validation-failed?
-      (call handler {:request-method :get, :query-params {:x "10"}}) => (has-body {:total 10})
-      (call handler {:request-method :post, :query-params {:x "1"}}) => (has-body {:total 1}))))
+      (is-request-validation-failed? (call handler {:request-method :get}))
+      (is-response-validation-failed? (call handler {:request-method :get, :query-params {:x "-1"}}))
+      (is-response-validation-failed? (call handler {:request-method :get, :query-params {:x "1"}}))
+      (is-has-body {:total 10} (call handler {:request-method :get, :query-params {:x "10"}}))
+      (is-has-body {:total 1} (call handler {:request-method :post, :query-params {:x "1"}})))))
 
-(fact "explicit async tests"
+(deftest explicit-async-tests-test
   (let [handler (resource
                   {:parameters {:query-params {:x Long}}
                    :responses {200 {:schema {:total (s/constrained Long pos? 'pos)}}}
@@ -173,44 +173,44 @@
                                       (a/<! (a/timeout 100))
                                       (ok {:total (* x 100)})))}})]
 
-    (fact "top-level async handler"
+    (testing "top-level async handler"
       (let [respond (promise), res-raise (promise), req-raise (promise)]
         (handler {:query-params {:x 1}} respond (promise))
         (handler {:query-params {:x -1}} (promise) res-raise)
         (handler {:query-params {:x "x"}} (promise) req-raise)
 
-        (deref respond 1000 :timeout) => (has-body {:total 1})
-        (throw (deref res-raise 1000 :timeout)) => response-validation-failed?
-        (throw (deref req-raise 1000 :timeout)) => request-validation-failed?))
+        (is-has-body {:total 1} (deref respond 1000 :timeout))
+        (is-response-validation-failed? (throw (deref res-raise 1000 :timeout)))
+        (is-request-validation-failed? (throw (deref req-raise 1000 :timeout)))))
 
-    (fact "operation-level async handler"
+    (testing "operation-level async handler"
       (let [respond (promise)]
         (handler {:request-method :get, :query-params {:x 1}} respond (promise))
-        (deref respond 1000 :timeout) => (has-body {:total 2})))
+        (is-has-body {:total 2} (deref respond 1000 :timeout))))
 
-    (fact "sync handler can be called from async"
+    (testing "sync handler can be called from async"
       (let [respond (promise)]
         (handler {:request-method :post, :query-params {:x 1}} respond (promise))
-        (deref respond 1000 :timeout) => (has-body {:total 10}))
-      (fact "response coercion works"
+        (is-has-body {:total 10} (deref respond 1000 :timeout)))
+      (testing "response coercion works"
         (let [raise (promise)]
           (handler {:request-method :post, :query-params {:x -1}} (promise) raise)
-          (throw (deref raise 1000 :timeout)) => response-validation-failed?)))
+          (is-response-validation-failed? (throw (deref raise 1000 :timeout))))))
 
-    (fact "core.async ManyToManyChannel"
-      (fact "works with 3-arity"
+    (testing "core.async ManyToManyChannel"
+      (testing "works with 3-arity"
         (let [respond (promise)]
           (handler {:request-method :put, :query-params {:x 1}} respond (promise))
-          (deref respond 2000 :timeout) => (has-body {:total 100}))
-        (fact "response coercion works"
+          (is-has-body {:total 100} (deref respond 2000 :timeout)))
+        (testing "response coercion works"
           (let [raise (promise)]
             (handler {:request-method :put, :query-params {:x -1}} (promise) raise)
-            (throw (deref raise 2000 :timeout)) => response-validation-failed?)))
-      (fact "fails with 1-arity"
-        (handler {:request-method :put, :query-params {:x 1}}) => (throws) #_(has-body {:total 100})
-        (handler {:request-method :put, :query-params {:x -1}}) => (throws) #_response-validation-failed?))))
+            (is-response-validation-failed? (throw (deref raise 2000 :timeout))))))
+      (testing "fails with 1-arity"
+        (is (thrown? Exception (handler {:request-method :put, :query-params {:x 1}}))) #_(is-has-body {:total 100})
+        (is (thrown? Exception (handler {:request-method :put, :query-params {:x -1}}))) #_response-validation-failed?))))
 
-(fact "compojure-api routing integration"
+(deftest compojure-api-routing-integration-test
   (let [app (context "/rest" []
 
               (GET "/no" request
@@ -236,34 +236,44 @@
                 {:get {:handler (fn [request]
                                   (ok (select-keys request [:uri :path-info])))}}))]
 
-    (fact "normal endpoint works"
-      (call app {:request-method :get, :uri "/rest/no"}) => (has-body {:uri "/rest/no", :path-info "/no"}))
+    (testing "normal endpoint works"
+      (is-has-body
+        {:uri "/rest/no", :path-info "/no"}
+        (call app {:request-method :get, :uri "/rest/no"})))
 
-    (fact "wrapped in ANY works"
-      (call app {:request-method :get, :uri "/rest/any"}) => (has-body "ANY"))
+    (testing "wrapped in ANY works"
+      (is-has-body
+        "ANY"
+        (call app {:request-method :get, :uri "/rest/any"})))
 
-    (fact "wrapped in context works"
-      (call app {:request-method :get, :uri "/rest/context"}) => (has-body "CONTEXT"))
+    (testing "wrapped in context works"
+      (is-has-body
+        "CONTEXT"
+        (call app {:request-method :get, :uri "/rest/context"})))
 
-    (fact "only exact path match works"
-      (call app {:request-method :get, :uri "/rest/context/2"}) => nil)
+    (testing "only exact path match works"
+      (is (nil? (call app {:request-method :get, :uri "/rest/context/2"}))))
 
-    (fact "path-parameters work: route-params are left untoucehed, path-params are coerced"
-      (call app {:request-method :get, :uri "/rest/path/12"}) => (has-body {:path-params {:id 12}
-                                                                            :route-params {:id "12"}}))
+    (testing "path-parameters work: route-params are left untoucehed, path-params are coerced"
+      (is-has-body
+        {:path-params {:id 12}
+         :route-params {:id "12"}}
+        (call app {:request-method :get, :uri "/rest/path/12"})))
 
-    (fact "top-level GET without extra path works"
-      (call app {:request-method :get, :uri "/rest"}) => (has-body {:uri "/rest"
-                                                                    :path-info "/"}))
+    (testing "top-level GET without extra path works"
+      (is-has-body
+        {:uri "/rest"
+         :path-info "/"}
+        (call app {:request-method :get, :uri "/rest"})))
 
-    (fact "top-level POST without extra path works"
-      (call app {:request-method :post, :uri "/rest"}) => nil)
+    (testing "top-level POST without extra path works"
+      (is (nil? (call app {:request-method :post, :uri "/rest"}))))
 
-    (fact "top-level GET with extra path misses"
-      (call app {:request-method :get, :uri "/rest/in-peaces"}) => nil)))
+    (testing "top-level GET with extra path misses"
+      (is (nil? (call app {:request-method :get, :uri "/rest/in-peaces"}))))))
 
-(fact "swagger-integration"
-  (fact "explicitely defined methods produce api-docs"
+(deftest swagger-integration-test
+  (testing "explicitly defined methods produce api-docs"
     (let [app (api
                 (swagger-routes)
                 (context "/rest" []
@@ -276,19 +286,19 @@
                      :handler (constantly (ok {:total 1}))})))
           spec (get-spec app)]
 
-      spec => (contains
-                {:definitions (just
-                                {:Error irrelevant
-                                 :Total irrelevant})
-                 :paths (just
-                          {"/rest" (just
-                                     {:get (just
-                                             {:parameters (two-of irrelevant)
-                                              :responses (just {:200 irrelevant, :400 irrelevant})})
-                                      :post (just
-                                              {:parameters (one-of irrelevant)
-                                               :responses (just {:400 irrelevant})})})})})))
-  (fact "top-level handler doesn't contribute to docs"
+      (is (= {:definitions #{:Error :Total}
+              :paths {"/rest" {:get {:parameters 2
+                                     :responses #{:200 :400}}
+                               :post {:parameters 1
+                                      :responses #{:400}}}}}
+            (-> spec
+                (select-keys [:definitions :paths])
+                (update :definitions (comp set keys))
+                (update-in [:paths "/rest" :get :parameters] count)
+                (update-in [:paths "/rest" :get :responses] (comp set keys))
+                (update-in [:paths "/rest" :post :parameters] count)
+                (update-in [:paths "/rest" :post :responses] (comp set keys)))))))
+  (testing "top-level handler doesn't contribute to docs"
     (let [app (api
                 (swagger-routes)
                 (context "/rest" []
@@ -296,5 +306,4 @@
                     {:handler (constantly (ok {:total 1}))})))
           spec (get-spec app)]
 
-      spec => (contains
-                {:paths {}}))))
+      (is (= {} (:paths spec))))))
diff --git a/test/compojure/api/routes_test.clj b/test/compojure/api/routes_test.clj
index 5394103a..dd313f52 100644
--- a/test/compojure/api/routes_test.clj
+++ b/test/compojure/api/routes_test.clj
@@ -1,5 +1,5 @@
 (ns compojure.api.routes-test
-  (:require [midje.sweet :refer :all]
+  (:require [clojure.test :refer [deftest is testing]]
             [compojure.api.sweet :refer :all]
             [compojure.api.routes :as routes]
             [ring.util.http-response :refer :all]
@@ -10,26 +10,26 @@
   (:import (org.joda.time LocalDate)
            (clojure.lang ExceptionInfo)))
 
-(facts "path-string"
+(deftest path-string-test
 
-  (fact "missing path parameter"
-    (#'routes/path-string muuntaja "/api/:kikka" {})
-    => (throws IllegalArgumentException))
+  (testing "missing path parameter"
+    (is (thrown? IllegalArgumentException (#'routes/path-string muuntaja "/api/:kikka" {}))))
 
-  (fact "missing serialization"
-    (#'routes/path-string muuntaja "/api/:kikka" {:kikka (reify Comparable)})
-    => (throws ExceptionInfo #"Malformed application/json"))
+  (testing "missing serialization"
+    (is (thrown-with-msg?
+          ExceptionInfo #"Malformed application/json"
+          (#'routes/path-string muuntaja "/api/:kikka" {:kikka (reify Comparable)}))))
 
-  (fact "happy path"
-    (#'routes/path-string muuntaja "/a/:b/:c/d/:e/f" {:b (LocalDate/parse "2015-05-22")
-                                                      :c 12345
-                                                      :e :kikka})
-    => "/a/2015-05-22/12345/d/kikka/f"))
+  (testing "happy path"
+    (is (= "/a/2015-05-22/12345/d/kikka/f"
+           (#'routes/path-string muuntaja "/a/:b/:c/d/:e/f" {:b (LocalDate/parse "2015-05-22")
+                                                             :c 12345
+                                                             :e :kikka})))))
 
-(fact "string-path-parameters"
-  (#'routes/string-path-parameters "/:foo.json") => {:foo String})
+(deftest string-path-parameters-test
+  (is (= {:foo String} (#'routes/string-path-parameters "/:foo.json"))))
 
-(facts "nested routes"
+(deftest nested-routes-test
   (let [mw (fn [handler]
              (fn ([request] (handler request))
                ([request raise respond] (handler request raise respond))))
@@ -56,76 +56,74 @@
               (swagger-routes)
               routes)]
 
-    (fact "all routes can be invoked"
+    (testing "all routes can be invoked"
       (let [[status body] (get* app "/api/v1/hello" {:name "Tommi"})]
-        status = 200
-        body => {:message "Hello, Tommi"})
+        (is (= 200 status))
+        (is (= body {:message "Hello, Tommi"})))
 
       (let [[status body] (get* app "/api/v1/ping")]
-        status = 200
-        body => {:message "pong - v1"})
+        (is (= status 200))
+        (is (= body {:message "pong - v1"})))
 
       (let [[status body] (get* app "/api/v2/ping")]
-        status = 200
-        body => {:message "pong - v2"})
+        (is (= status 200))
+        (is (= body {:message "pong - v2"})))
 
       (let [[status body] (get* app "/api/v3/more")]
-        status => 200
-        body => {:message "v3"}))
-
-    (fact "routes can be extracted at runtime"
-      (routes/get-routes app)
-      => [["/swagger.json" :get {:no-doc true
-                                 :coercion :schema
-                                 :name :compojure.api.swagger/swagger
-                                 :public {:x-name :compojure.api.swagger/swagger}}]
-          ["/api/:version/ping" :get {:coercion :schema
-                                      :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
-          ["/api/:version/ping" :post {:coercion :schema
-                                       :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
-          ;; 'ANY' expansion
-          ["/api/:version/foo" :get {:coercion :schema
-                                     :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
-          ["/api/:version/foo" :patch {:coercion :schema
-                                       :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
-          ["/api/:version/foo" :delete {:coercion :schema
-                                        :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
-          ["/api/:version/foo" :head {:coercion :schema
-                                      :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
-          ["/api/:version/foo" :post {:coercion :schema
-                                      :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
-          ["/api/:version/foo" :options {:coercion :schema
+        (is (= status 200))
+        (is (= body {:message "v3"}))))
+
+    (testing "routes can be extracted at runtime"
+      (is (= [["/swagger.json" :get {:no-doc true
+                                     :coercion :schema
+                                     :name :compojure.api.swagger/swagger
+                                     :public {:x-name :compojure.api.swagger/swagger}}]
+              ["/api/:version/ping" :get {:coercion :schema
+                                          :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
+              ["/api/:version/ping" :post {:coercion :schema
+                                           :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
+              ;; 'ANY' expansion
+              ["/api/:version/foo" :get {:coercion :schema
                                          :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
-          ["/api/:version/foo" :put {:coercion :schema
-                                     :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
-          ;;
-          ["/api/:version/hello" :get {:coercion :schema
-                                       :public {:parameters {:query {:name String, s/Keyword s/Any}
-                                                             :path {:version String, s/Keyword s/Any}}
-                                                :responses {200 {:description "", :schema {:message String}}}
-                                                :summary "cool ping"}}]
-          ["/api/:version/more" :get {:coercion :schema
-                                      :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]])
-
-    (fact "swagger-docs can be generated"
-      (-> app get-spec :paths keys)
-      => (just
-           ["/api/{version}/ping"
-            "/api/{version}/foo"
-            "/api/{version}/hello"
-            "/api/{version}/more"]
-           :in-any-order))))
+              ["/api/:version/foo" :patch {:coercion :schema
+                                           :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
+              ["/api/:version/foo" :delete {:coercion :schema
+                                            :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
+              ["/api/:version/foo" :head {:coercion :schema
+                                          :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
+              ["/api/:version/foo" :post {:coercion :schema
+                                          :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
+              ["/api/:version/foo" :options {:coercion :schema
+                                             :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
+              ["/api/:version/foo" :put {:coercion :schema
+                                         :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]
+              ;;
+              ["/api/:version/hello" :get {:coercion :schema
+                                           :public {:parameters {:query {:name String, s/Keyword s/Any}
+                                                                 :path {:version String, s/Keyword s/Any}}
+                                                    :responses {200 {:description "", :schema {:message String}}}
+                                                    :summary "cool ping"}}]
+              ["/api/:version/more" :get {:coercion :schema
+                                          :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]]
+           (routes/get-routes app))))
+
+    (testing "swagger-docs can be generated"
+      (is (= (sort ["/api/{version}/ping"
+                    "/api/{version}/foo"
+                    "/api/{version}/hello"
+                    "/api/{version}/more"])
+             (-> app get-spec :paths keys sort))))))
 
 (def more-routes
   (routes
     (GET "/more" []
       (ok {:gary "moore"}))))
 
-(facts "following var-routes, #219"
+(deftest issue-219-test ;"following var-routes, #219"
   (let [routes (context "/api" [] #'more-routes)]
-    (routes/get-routes routes) => [["/api/more" :get {:static-context? true}]]))
+    (is (= (routes/get-routes routes) [["/api/more" :get {:static-context? true}]]))))
 
-(facts "dynamic routes"
+(deftest dynamic-routes-test
   (let [more-routes (fn [version]
                       (GET (str "/" version) []
                         (ok {:message version})))
@@ -136,72 +134,74 @@
               (swagger-routes)
               routes)]
 
-    (fact "all routes can be invoked"
+    (testing "all routes can be invoked"
       (let [[status body] (get* app "/api/v3/v3")]
-        status => 200
-        body => {:message "v3"})
+        (is (= status 200))
+        (is (= body {:message "v3"})))
 
       (let [[status body] (get* app "/api/v6/v6")]
-        status => 200
-        body => {:message "v6"}))
-
-    (fact "routes can be extracted at runtime"
-      (routes/get-routes app)
-      => [["/swagger.json" :get {:no-doc true,
-                                 :coercion :schema
-                                 :name :compojure.api.swagger/swagger
-                                 :public {:x-name :compojure.api.swagger/swagger}}]
-          ["/api/:version/[]" :get {:coercion :schema
-                                    :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]])
-
-    (fact "swagger-docs can be generated"
-      (-> app get-spec :paths keys)
-      => ["/api/{version}/[]"])))
-
-(fact "route merging"
-  (routes/get-routes (routes (routes))) => []
-  (routes/get-routes (routes (swagger-routes {:spec nil}))) => []
-  (routes/get-routes (routes (routes (GET "/ping" [] "pong")))) => [["/ping" :get {}]])
-
-(fact "invalid route options"
+        (is (= status 200))
+        (is (= body {:message "v6"}))))
+
+    (testing "routes can be extracted at runtime"
+      (is (= (routes/get-routes app)
+             [["/swagger.json" :get {:no-doc true,
+                                     :coercion :schema
+                                     :name :compojure.api.swagger/swagger
+                                     :public {:x-name :compojure.api.swagger/swagger}}]
+              ["/api/:version/[]" :get {:coercion :schema
+                                        :public {:parameters {:path {:version String, s/Keyword s/Any}}}}]])))
+
+    (testing "swagger-docs can be generated"
+      (is (= (-> app get-spec :paths keys)
+             ["/api/{version}/[]"])))))
+
+(deftest route-merging-test
+  (is (= (routes/get-routes (routes (routes))) []))
+  (is (= (routes/get-routes (routes (swagger-routes {:spec nil}))) []))
+  (is (= (routes/get-routes (routes (routes (GET "/ping" [] "pong")))) [["/ping" :get {}]])))
+
+(deftest invalid-route-options-test
   (let [r (routes (constantly nil))]
 
-    (fact "ignore 'em all"
-      (routes/get-routes r) => []
-      (routes/get-routes r nil) => []
-      (routes/get-routes r {:invalid-routes-fn nil}) => [])
+    (testing "ignore 'em all"
+      (is (= (routes/get-routes r) []))
+      (is (= (routes/get-routes r nil) []))
+      (is (= (routes/get-routes r {:invalid-routes-fn nil}) [])))
 
-    (fact "log warnings"
-      (routes/get-routes r {:invalid-routes-fn routes/log-invalid-child-routes}) => []
-      (provided
-        (compojure.api.impl.logging/log! :warn irrelevant) => irrelevant :times 1))
+    (testing "log warnings"
+      (let [a (atom [])]
+        (with-redefs [compojure.api.impl.logging/log! (fn [& args] (swap! a conj args))]
+          (is (= [] (routes/get-routes r {:invalid-routes-fn routes/log-invalid-child-routes}))))
+        (is (= 1 (count @a)))))
 
-    (fact "throw exception"
-      (routes/get-routes r {:invalid-routes-fn routes/fail-on-invalid-child-routes})) => throws))
+    (testing "throw exception"
+      (is (thrown? Exception (routes/get-routes r {:invalid-routes-fn routes/fail-on-invalid-child-routes}))))))
 
-(fact "context routes with compojure destructuring"
+(deftest context-routes-with-compojure-destructuring-test
   (let [app (context "/api" req
               (GET "/ping" [] (ok (:magic req))))]
-    (app {:request-method :get :uri "/api/ping" :magic {:just "works"}}) => (contains {:body {:just "works"}})))
+    (is (= {:just "works"}
+           (:body (app {:request-method :get :uri "/api/ping" :magic {:just "works"}}))))))
 
-(fact "dynamic context routes"
+(deftest dynamic-context-routes-test
   (let [endpoint? (atom true)
         app (context "/api" []
               :dynamic true
               (when @endpoint?
                 (GET "/ping" [] (ok "pong"))))]
-    (fact "the endpoint exists"
-      (app {:request-method :get :uri "/api/ping"}) => (contains {:body "pong"}))
+    (testing "the endpoint exists"
+      (is (= (:body (app {:request-method :get :uri "/api/ping"})) "pong")))
 
     (reset! endpoint? false)
-    (fact "the endpoint does not exist"
-      (app {:request-method :get :uri "/api/ping"}) => nil)))
+    (testing "the endpoint does not exist"
+      (is (= (app {:request-method :get :uri "/api/ping"}) nil)))))
 
-(fact "listing static context routes"
+(deftest listing-static-context-routes-test
   (let [app (routes
               (context "/static" []
                 (GET "/ping" [] (ok "pong")))
               (context "/dynamic" req
                 (GET "/ping" [] (ok "pong"))))]
-    (routes/get-static-context-routes app)
-    => [["/static/ping" :get {:static-context? true}]]))
+    (is (= (routes/get-static-context-routes app)
+           [["/static/ping" :get {:static-context? true}]]))))
diff --git a/test/compojure/api/swagger_ordering_test.clj b/test/compojure/api/swagger_ordering_test.clj
index 55112ecf..62c8bf69 100644
--- a/test/compojure/api/swagger_ordering_test.clj
+++ b/test/compojure/api/swagger_ordering_test.clj
@@ -1,5 +1,5 @@
 (ns compojure.api.swagger-ordering-test
-  (:require [midje.sweet :refer :all]
+  (:require [clojure.test :refer [deftest is testing]]
             [compojure.api.sweet :refer :all]
             [compojure.api.test-utils :refer :all]))
 
@@ -9,7 +9,7 @@
     (GET "/7" [] identity)
     (GET "/8" [] identity)))
 
-(facts "with 10+ routes"
+(deftest with-10+-routes-test
   (let [app (api
               (context "/a" []
                 (GET "/1" [] identity)
@@ -23,14 +23,15 @@
                   (GET "/9" [] identity)
                   (GET "/10" [] identity))))]
 
-    (fact "swagger-api order is maintained"
-      (keys (extract-paths app)) => ["/a/1"
-                                     "/a/2"
-                                     "/a/3"
-                                     "/a/b/4"
-                                     "/a/b/5"
-                                     "/a/c/6"
-                                     "/a/c/7"
-                                     "/a/c/8"
-                                     "/a/c/9"
-                                     "/a/c/10"])))
+    (testing "swagger-api order is maintained"
+      (is (= (keys (extract-paths app))
+             ["/a/1"
+              "/a/2"
+              "/a/3"
+              "/a/b/4"
+              "/a/b/5"
+              "/a/c/6"
+              "/a/c/7"
+              "/a/c/8"
+              "/a/c/9"
+              "/a/c/10"])))))
diff --git a/test/compojure/api/swagger_test.clj b/test/compojure/api/swagger_test.clj
index 9269de93..8e9c73ff 100644
--- a/test/compojure/api/swagger_test.clj
+++ b/test/compojure/api/swagger_test.clj
@@ -4,14 +4,14 @@
             [compojure.api.swagger :as swagger]
             compojure.core
             [compojure.api.test-utils :refer :all]
-            [midje.sweet :refer :all]))
+            [clojure.test :refer [deftest is testing]]))
 
 (defmacro optional-routes [p & body] (when p `(routes ~@body)))
 (defmacro GET+ [p & body] `(GET ~(str "/xxx" p) ~@body))
 
-(fact "extracting compojure paths"
+(deftest extracting-compojure-paths-test
 
-  (fact "all compojure.api.core macros are interpreted"
+  (testing "all compojure.api.core macros are interpreted"
     (let [app (context "/a" []
                 (routes
                   (context "/b" a
@@ -25,91 +25,94 @@
                   (context "/:i/:j" []
                     (GET "/k/:l/m/:n" [] identity))))]
 
-      (extract-paths app)
-      #_#_
-      => {"/a/b/c" {:get {}}
-          "/a/b/d" {:post {}}
-          "/a/b/e" {:put {}}
-          "/a/b/f" {:delete {}}
-          "/a/b/g" {:options {}}
-          "/a/b/h" {:patch {}}
-          "/a/:i/:j/k/:l/m/:n" {:get {:parameters {:path {:i String
-                                                          :j String
-                                                          :l String
-                                                          :n String}}}}}))
-
-  (fact "runtime code in route is NOT ignored"
-    (extract-paths
-      (context "/api" []
-        (if false
-          (GET "/true" [] identity)
-          (PUT "/false" [] identity)))) => {"/api/false" {:put {}}})
-
-  (fact "route-macros are expanded"
-    (extract-paths
-      (context "/api" []
-        (optional-routes true (GET "/true" [] identity))
-        (optional-routes false (PUT "/false" [] identity)))) => {"/api/true" {:get {}}})
-
-  (fact "endpoint-macros are expanded"
-    (extract-paths
-      (context "/api" []
-        (GET+ "/true" [] identity))) => {"/api/xxx/true" {:get {}}})
-
-  (fact "Vanilla Compojure defroutes are NOT followed"
+      (is (= (extract-paths app)
+             {"/a/b/c" {:get {}}
+              "/a/b/d" {:post {}}
+              "/a/b/e" {:put {}}
+              "/a/b/f" {:delete {}}
+              "/a/b/g" {:options {}}
+              "/a/b/h" {:patch {}}
+              "/a/:i/:j/k/:l/m/:n" {:get {:parameters {:path {:i String
+                                                              :j String
+                                                              :l String
+                                                              :n String}}}}}))))
+
+  (testing "runtime code in route is NOT ignored"
+    (is (= (extract-paths
+             (context "/api" []
+                      (if false
+                        (GET "/true" [] identity)
+                        (PUT "/false" [] identity))))
+           {"/api/false" {:put {}}})))
+
+  (testing "route-macros are expanded"
+    (is (= (extract-paths
+             (context "/api" []
+                      (optional-routes true (GET "/true" [] identity))
+                      (optional-routes false (PUT "/false" [] identity))))
+           {"/api/true" {:get {}}})))
+
+  (testing "endpoint-macros are expanded"
+    (is (= (extract-paths
+             (context "/api" []
+                      (GET+ "/true" [] identity)))
+           {"/api/xxx/true" {:get {}}})))
+
+  (testing "Vanilla Compojure defroutes are NOT followed"
     (compojure.core/defroutes even-more-routes (GET "/even" [] identity))
     (compojure.core/defroutes more-routes (context "/more" [] even-more-routes))
-    (extract-paths
-      (context "/api" []
-        (GET "/true" [] identity)
-        more-routes)) => {"/api/true" {:get {}}})
+    (is (= (extract-paths
+             (context "/api" []
+                      (GET "/true" [] identity)
+                      more-routes))
+           {"/api/true" {:get {}}})))
 
-  (fact "Compojure Api defroutes and def routes are followed"
+  (testing "Compojure Api defroutes and def routes are followed"
     (def even-more-routes (GET "/even" [] identity))
     (defroutes more-routes (context "/more" [] even-more-routes))
-    (extract-paths
-      (context "/api" []
-        (GET "/true" [] identity)
-        more-routes)) => {"/api/true" {:get {}}
-                          "/api/more/even" {:get {}}})
-
-  (fact "Parameter regular expressions are discarded"
-    (extract-paths
-      (context "/api" []
-        (GET ["/:param" :param #"[a-z]+"] [] identity)))
-
-    => {"/api/:param" {:get {:parameters {:path {:param String}}}}}))
-
-(fact "context meta-data"
-  (extract-paths
-    (context "/api/:id" []
-      :summary "top-summary"
-      :path-params [id :- String]
-      :tags [:kiss]
-      (GET "/kikka" []
-        identity)
-      (context "/ipa" []
-        :summary "mid-summary"
-        :tags [:wasp]
-        (GET "/kukka/:kukka" []
-          :summary "bottom-summary"
-          :path-params [kukka :- String]
-          :tags [:venom])
-        (GET "/kakka" []
-          identity))))
-
-  => {"/api/:id/kikka" {:get {:summary "top-summary"
-                              :tags #{:kiss}
-                              :parameters {:path {:id String}}}}
-      "/api/:id/ipa/kukka/:kukka" {:get {:summary "bottom-summary"
-                                         :tags #{:venom}
-                                         :parameters {:path {:id String
-                                                             :kukka String}}}}
-      "/api/:id/ipa/kakka" {:get {:summary "mid-summary"
-                                  :tags #{:wasp}
-                                  :parameters {:path {:id String}}}}})
-
-(facts "duplicate context merge"
+    (is (= (extract-paths
+             (context "/api" []
+                      (GET "/true" [] identity)
+                      more-routes))
+           {"/api/true" {:get {}}
+            "/api/more/even" {:get {}}})))
+
+  (testing "Parameter regular expressions are discarded"
+    (is (= (extract-paths
+             (context "/api" []
+                      (GET ["/:param" :param #"[a-z]+"] [] identity)))
+           {"/api/:param" {:get {:parameters {:path {:param String}}}}}))))
+
+(deftest context-meta-data-test-1
+  (is (= (extract-paths
+           (context "/api/:id" []
+                    :summary "top-summary"
+                    :path-params [id :- String]
+                    :tags [:kiss]
+                    (GET "/kikka" []
+                         identity)
+                    (context "/ipa" []
+                             :summary "mid-summary"
+                             :tags [:wasp]
+                             (GET "/kukka/:kukka" []
+                                  :summary "bottom-summary"
+                                  :path-params [kukka :- String]
+                                  :tags [:venom])
+                             (GET "/kakka" []
+                                  identity))))
+
+         {"/api/:id/kikka" {:get {:summary "top-summary"
+                                  :tags #{:kiss}
+                                  :parameters {:path {:id String}}}}
+          "/api/:id/ipa/kukka/:kukka" {:get {:summary "bottom-summary"
+                                             :tags #{:venom}
+                                             :parameters {:path {:id String
+                                                                 :kukka String}}}}
+          "/api/:id/ipa/kakka" {:get {:summary "mid-summary"
+                                      :tags #{:wasp}
+                                      :parameters {:path {:id String}}}}})))
+
+(deftest duplicate-context-merge-test
   (let [app (routes
               (context "/api" []
                 :tags [:kiss]
@@ -119,9 +122,9 @@
                 :tags [:kiss]
                 (GET "/kukka" []
                   identity)))]
-    (extract-paths app)
-    => {"/api/kukka" {:get {:tags #{:kiss}}}
-        "/api/kakka" {:get {:tags #{:kiss}}}}))
+    (is (= (extract-paths app)
+           {"/api/kukka" {:get {:tags #{:kiss}}}
+            "/api/kakka" {:get {:tags #{:kiss}}}}))))
 
 (def r1
   (GET "/:id" []
@@ -132,64 +135,66 @@
     :path-params [id :- Long]
     identity))
 
-(facts "defined routes path-params"
-  (extract-paths (routes r1 r2))
-  => {"/:id" {:get {:parameters {:path {:id String}}}}
-      "/kukka/:id" {:get {:parameters {:path {:id Long}}}}})
-
-(fact "context meta-data"
-  (extract-paths
-    (context "/api/:id" []
-      :summary "top-summary"
-      :path-params [id :- String]
-      :tags [:kiss]
-      (GET "/kikka" []
-        identity)
-      (context "/ipa" []
-        :summary "mid-summary"
-        :tags [:wasp]
-        (GET "/kukka/:kukka" []
-          :summary "bottom-summary"
-          :path-params [kukka :- String]
-          :tags [:venom])
-        (GET "/kakka" []
-          identity))))
-
-  => {"/api/:id/kikka" {:get {:summary "top-summary"
-                              :tags #{:kiss}
-                              :parameters {:path {:id String}}}}
-      "/api/:id/ipa/kukka/:kukka" {:get {:summary "bottom-summary"
-                                         :tags #{:venom}
-                                         :parameters {:path {:id String
-                                                             :kukka String}}}}
-      "/api/:id/ipa/kakka" {:get {:summary "mid-summary"
-                                  :tags #{:wasp}
-                                  :parameters {:path {:id String}}}}})
-
-(fact "path params followed by an extension"
-  (extract-paths
-    (GET "/:foo.json" []
-      :path-params [foo :- String]
-      identity))
-  => {"/:foo.json" {:get {:parameters {:path {:foo String}}}}})
-
-(facts
-  (tabular
-    (fact "swagger-routes basePath can be changed"
-      (let [app (api (swagger-routes ?given-options))]
-        (->
-          (get* app "/swagger.json")
-          (nth 1)
-          :basePath)
-        => ?expected-base-path
-        (nth (raw-get* app "/conf.js") 1) => (str "window.API_CONF = {\"url\":\"" ?expected-swagger-docs-path "\"};")))
-    ?given-options ?expected-swagger-docs-path ?expected-base-path
-    {} "/swagger.json" "/"
-    {:data {:basePath "/app"}} "/app/swagger.json" "/app"
-    {:data {:basePath "/app"} :options {:ui {:swagger-docs "/imaginary.json"}}} "/imaginary.json" "/app"))
-
-(fact "change of contract in 1.2.0 with swagger-docs % swagger-ui"
-  (fact "swagger-ui"
-    (swagger/swagger-ui "/path") => (throws AssertionError))
-  (fact "swagger-docs"
-    (swagger/swagger-docs "/path") => (throws AssertionError)))
+(deftest defined-routes-path-params-test
+  (is (= (extract-paths (routes r1 r2))
+         {"/:id" {:get {:parameters {:path {:id String}}}}
+          "/kukka/:id" {:get {:parameters {:path {:id Long}}}}})))
+
+;;FIXME is this a duplicate of context-meta-data-test-1?
+(deftest context-meta-data-test-2
+  (is (= (extract-paths
+           (context "/api/:id" []
+                    :summary "top-summary"
+                    :path-params [id :- String]
+                    :tags [:kiss]
+                    (GET "/kikka" []
+                         identity)
+                    (context "/ipa" []
+                             :summary "mid-summary"
+                             :tags [:wasp]
+                             (GET "/kukka/:kukka" []
+                                  :summary "bottom-summary"
+                                  :path-params [kukka :- String]
+                                  :tags [:venom])
+                             (GET "/kakka" []
+                                  identity))))
+
+         {"/api/:id/kikka" {:get {:summary "top-summary"
+                                  :tags #{:kiss}
+                                  :parameters {:path {:id String}}}}
+          "/api/:id/ipa/kukka/:kukka" {:get {:summary "bottom-summary"
+                                             :tags #{:venom}
+                                             :parameters {:path {:id String
+                                                                 :kukka String}}}}
+          "/api/:id/ipa/kakka" {:get {:summary "mid-summary"
+                                      :tags #{:wasp}
+                                      :parameters {:path {:id String}}}}})))
+
+(deftest path-params-followed-by-an-extension-test
+  (is (= (extract-paths
+           (GET "/:foo.json" []
+                :path-params [foo :- String]
+                identity))
+         {"/:foo.json" {:get {:parameters {:path {:foo String}}}}})))
+
+(deftest swagger-routes-basePath-test
+  (testing "swagger-routes basePath can be changed"
+    (doseq [[?given-options ?expected-swagger-docs-path ?expected-base-path :as test-case]
+            [[{} "/swagger.json" "/" {:data {:basePath "/app"}} "/app/swagger.json" "/app"]
+             [{:data {:basePath "/app"} :options {:ui {:swagger-docs "/imaginary.json"}}} "/imaginary.json" "/app"]]]
+      (testing (pr-str test-case)
+        (let [app (api (swagger-routes ?given-options))]
+          (is (= (->
+                   (get* app "/swagger.json")
+                   (nth 1)
+                   :basePath)
+                 ?expected-base-path))
+          (is (= (nth (raw-get* app "/conf.js") 1)
+                 (str "window.API_CONF = {\"url\":\"" ?expected-swagger-docs-path "\"};"))))))))
+
+;;"change of contract in 1.2.0 with swagger-docs % swagger-ui"
+(deftest change-1-2-0-swagger-docs-ui-test
+  (testing "swagger-ui"
+    (is (thrown? AssertionError (swagger/swagger-ui "/path"))))
+  (testing "swagger-docs"
+    (is (thrown? AssertionError (swagger/swagger-docs "/path")))))
diff --git a/test/compojure/api/sweet_test.clj b/test/compojure/api/sweet_test.clj
index c2082772..c6079843 100644
--- a/test/compojure/api/sweet_test.clj
+++ b/test/compojure/api/sweet_test.clj
@@ -1,7 +1,7 @@
 (ns compojure.api.sweet-test
   (:require [compojure.api.sweet :refer :all]
             [compojure.api.test-utils :refer :all]
-            [midje.sweet :refer :all]
+            [clojure.test :refer [deftest is testing]]
             [ring.mock.request :refer :all]
             [schema.core :as s]
             [ring.swagger.validator :as v]))
@@ -65,124 +65,135 @@
         :return [String]
         identity))))
 
-(facts "api documentation"
-  (fact "details are generated"
+(deftest api-documentation-test
+  (testing "details are generated"
 
-    (extract-paths app)
+    (is (= (extract-paths app)
 
-    => {"/swagger.json" {:get {:x-name :compojure.api.swagger/swagger}}
-        "/ping" {:get {}}
-        "/api/ping" {:get {}}
-        "/api/bands" {:get {:x-name :bands
-                            :operationId "getBands"
-                            :description "bands bands bands"
-                            :responses {200 {:schema [Band]
-                                             :description ""}}
-                            :summary "Gets all Bands"}
-                      :post {:operationId "addBand"
-                             :parameters {:body [NewBand]}
-                             :responses {200 {:schema Band
-                                              :description ""}}
-                             :summary "Adds a Band"}}
-        "/api/bands/:id" {:get {:operationId "getBand"
-                                :responses {200 {:schema Band
+           {"/swagger.json" {:get {:x-name :compojure.api.swagger/swagger}}
+            "/ping" {:get {}}
+            "/api/ping" {:get {}}
+            "/api/bands" {:get {:x-name :bands
+                                :operationId "getBands"
+                                :description "bands bands bands"
+                                :responses {200 {:schema [Band]
                                                  :description ""}}
-                                :summary "Gets a Band"
-                                :parameters {:path {:id String}}}}
-        "/api/query" {:get {:parameters {:query {:qp Boolean
-                                                 s/Keyword s/Any}}}}
-        "/api/header" {:get {:parameters {:header {:hp Boolean
-                                                   s/Keyword s/Any}}}}
-        "/api/form" {:post {:parameters {:formData {:fp Boolean}}
-                            :consumes ["application/x-www-form-urlencoded"]}}
-        "/api/primitive" {:get {:responses {200 {:schema String
-                                                 :description ""}}}}
-        "/api/primitiveArray" {:get {:responses {200 {:schema [String]
-                                                      :description ""}}}}})
+                                :summary "Gets all Bands"}
+                          :post {:operationId "addBand"
+                                 :parameters {:body [NewBand]}
+                                 :responses {200 {:schema Band
+                                                  :description ""}}
+                                 :summary "Adds a Band"}}
+            "/api/bands/:id" {:get {:operationId "getBand"
+                                    :responses {200 {:schema Band
+                                                     :description ""}}
+                                    :summary "Gets a Band"
+                                    :parameters {:path {:id String}}}}
+            "/api/query" {:get {:parameters {:query {:qp Boolean
+                                                     s/Keyword s/Any}}}}
+            "/api/header" {:get {:parameters {:header {:hp Boolean
+                                                       s/Keyword s/Any}}}}
+            "/api/form" {:post {:parameters {:formData {:fp Boolean}}
+                                :consumes ["application/x-www-form-urlencoded"]}}
+            "/api/primitive" {:get {:responses {200 {:schema String
+                                                     :description ""}}}}
+            "/api/primitiveArray" {:get {:responses {200 {:schema [String]
+                                                          :description ""}}}}})))
 
-  (fact "api-listing works"
+  (testing "api-listing works"
     (let [spec (get-spec app)]
 
-      spec => (just
-                {:swagger "2.0"
-                 :info {:version "1.0.0"
-                        :title "Sausages"
-                        :description "Sausage description"
-                        :termsOfService "http://helloreverb.com/terms/"
-                        :contact {:name "My API Team"
-                                  :email "foo@example.com"
-                                  :url "http://www.metosin.fi"}
-                        :license {:name "Eclipse Public License"
-                                  :url "http://www.eclipse.org/legal/epl-v10.html"}}
-                 :basePath "/"
-                 :consumes (just
-                             ["application/json"
-                              "application/edn"
-                              "application/transit+json"
-                              "application/transit+msgpack"]
-                             :in-any-order),
-                 :produces (just
-                             ["application/json"
-                              "application/edn"
-                              "application/transit+json"
-                              "application/transit+msgpack"]
-                             :in-any-order)
-                 :paths {"/api/bands" {:get {:x-name "bands"
-                                             :operationId "getBands"
-                                             :description "bands bands bands"
-                                             :responses {:200 {:description ""
-                                                               :schema {:items {:$ref "#/definitions/Band"}
-                                                                        :type "array"}}}
-                                             :summary "Gets all Bands"}
-                                       :post {:operationId "addBand"
-                                              :parameters [{:description ""
-                                                            :in "body"
-                                                            :name "NewBand"
-                                                            :required true
-                                                            :schema {:items {:$ref "#/definitions/NewBand"}
-                                                                     :type "array"}}]
-                                              :responses {:200 {:description ""
-                                                                :schema {:$ref "#/definitions/Band"}}}
-                                              :summary "Adds a Band"}}
-                         "/api/bands/{id}" {:get {:operationId "getBand"
-                                                  :parameters [{:description ""
-                                                                :in "path"
-                                                                :name "id"
-                                                                :required true
-                                                                :type "string"}]
-                                                  :responses {:200 {:description ""
-                                                                    :schema {:$ref "#/definitions/Band"}}}
-                                                  :summary "Gets a Band"}}
-                         "/api/query" {:get {:parameters [{:in "query"
-                                                           :name "qp"
-                                                           :description ""
-                                                           :required true
-                                                           :type "boolean"}]
-                                             :responses {:default {:description ""}}}}
-                         "/api/header" {:get {:parameters [{:in "header"
-                                                            :name "hp"
-                                                            :description ""
-                                                            :required true
-                                                            :type "boolean"}]
-                                              :responses {:default {:description ""}}}}
-                         "/api/form" {:post {:parameters [{:in "formData"
-                                                           :name "fp"
-                                                           :description ""
-                                                           :required true
-                                                           :type "boolean"}]
-                                             :responses {:default {:description ""}}
-                                             :consumes ["application/x-www-form-urlencoded"]}}
-                         "/api/ping" {:get {:responses {:default {:description ""}}}}
-                         "/api/primitive" {:get {:responses {:200 {:description ""
-                                                                   :schema {:type "string"}}}}}
-                         "/api/primitiveArray" {:get {:responses {:200 {:description ""
-                                                                        :schema {:items {:type "string"}
-                                                                                 :type "array"}}}}}
-                         "/ping" {:get {:responses {:default {:description ""}}}}}
-                 :definitions {:Band {:type "object"
+      (is (= (-> spec
+                 (update :consumes sort)
+                 (update :produces sort))
+             {:swagger "2.0"
+              :info {:version "1.0.0"
+                     :title "Sausages"
+                     :description "Sausage description"
+                     :termsOfService "http://helloreverb.com/terms/"
+                     :contact {:name "My API Team"
+                               :email "foo@example.com"
+                               :url "http://www.metosin.fi"}
+                     :license {:name "Eclipse Public License"
+                               :url "http://www.eclipse.org/legal/epl-v10.html"}}
+              :basePath "/"
+              :consumes (sort ["application/json"
+                               "application/edn"
+                               "application/transit+json"
+                               "application/transit+msgpack"]),
+              :produces (sort ["application/json"
+                               "application/edn"
+                               "application/transit+json"
+                               "application/transit+msgpack"])
+              :paths {"/api/bands" {:get {:x-name "bands"
+                                          :operationId "getBands"
+                                          :description "bands bands bands"
+                                          :responses {:200 {:description ""
+                                                            :schema {:items {:$ref "#/definitions/Band"}
+                                                                     :type "array"}}}
+                                          :summary "Gets all Bands"}
+                                    :post {:operationId "addBand"
+                                           :parameters [{:description ""
+                                                         :in "body"
+                                                         :name "NewBand"
+                                                         :required true
+                                                         :schema {:items {:$ref "#/definitions/NewBand"}
+                                                                  :type "array"}}]
+                                           :responses {:200 {:description ""
+                                                             :schema {:$ref "#/definitions/Band"}}}
+                                           :summary "Adds a Band"}}
+                      "/api/bands/{id}" {:get {:operationId "getBand"
+                                               :parameters [{:description ""
+                                                             :in "path"
+                                                             :name "id"
+                                                             :required true
+                                                             :type "string"}]
+                                               :responses {:200 {:description ""
+                                                                 :schema {:$ref "#/definitions/Band"}}}
+                                               :summary "Gets a Band"}}
+                      "/api/query" {:get {:parameters [{:in "query"
+                                                        :name "qp"
+                                                        :description ""
+                                                        :required true
+                                                        :type "boolean"}]
+                                          :responses {:default {:description ""}}}}
+                      "/api/header" {:get {:parameters [{:in "header"
+                                                         :name "hp"
+                                                         :description ""
+                                                         :required true
+                                                         :type "boolean"}]
+                                           :responses {:default {:description ""}}}}
+                      "/api/form" {:post {:parameters [{:in "formData"
+                                                        :name "fp"
+                                                        :description ""
+                                                        :required true
+                                                        :type "boolean"}]
+                                          :responses {:default {:description ""}}
+                                          :consumes ["application/x-www-form-urlencoded"]}}
+                      "/api/ping" {:get {:responses {:default {:description ""}}}}
+                      "/api/primitive" {:get {:responses {:200 {:description ""
+                                                                :schema {:type "string"}}}}}
+                      "/api/primitiveArray" {:get {:responses {:200 {:description ""
+                                                                     :schema {:items {:type "string"}
+                                                                              :type "array"}}}}}
+                      "/ping" {:get {:responses {:default {:description ""}}}}}
+              :definitions {:Band {:type "object"
+                                   :properties {:description {:type "string"
+                                                              :x-nullable true}
+                                                :id {:format "int64", :type "integer"}
+                                                :name {:type "string"}
+                                                :toppings {:items {:enum ["olives"
+                                                                          "pepperoni"
+                                                                          "ham"
+                                                                          "cheese"
+                                                                          "habanero"]
+                                                                   :type "string"}
+                                                           :type "array"}}
+                                   :required ["id" "name" "toppings"]
+                                   :additionalProperties false}
+                            :NewBand {:type "object"
                                       :properties {:description {:type "string"
                                                                  :x-nullable true}
-                                                   :id {:format "int64", :type "integer"}
                                                    :name {:type "string"}
                                                    :toppings {:items {:enum ["olives"
                                                                              "pepperoni"
@@ -191,37 +202,25 @@
                                                                              "habanero"]
                                                                       :type "string"}
                                                               :type "array"}}
-                                      :required ["id" "name" "toppings"]
-                                      :additionalProperties false}
-                               :NewBand {:type "object"
-                                         :properties {:description {:type "string"
-                                                                    :x-nullable true}
-                                                      :name {:type "string"}
-                                                      :toppings {:items {:enum ["olives"
-                                                                                "pepperoni"
-                                                                                "ham"
-                                                                                "cheese"
-                                                                                "habanero"]
-                                                                         :type "string"}
-                                                                 :type "array"}}
-                                         :required ["name" "toppings"]
-                                         :additionalProperties false}}})
+                                      :required ["name" "toppings"]
+                                      :additionalProperties false}}}))
 
-      (fact "spec is valid"
-        (v/validate spec) => nil))))
+      (testing "spec is valid"
+        (is (= (v/validate spec) nil))))))
 
-(fact "produces & consumes"
+(deftest produces-and-consumes-test
   (let [app (api
               {:swagger {:spec "/swagger.json"
                          :data {:produces ["application/json" "application/edn"]
                                 :consumes ["application/json" "application/edn"]}}}
               ping-route)]
-    (get-spec app) => (contains
-                        {:consumes (just
-                                     ["application/json"
-                                      "application/edn"]
-                                     :in-any-order)
-                         :produces (just
-                                     ["application/json"
-                                      "application/edn"]
-                                     :in-any-order)})))
+    (is (= (-> (get-spec app)
+               (select-keys [:consumes :produces])
+               (update :consumes sort)
+               (update :produces sort))
+           {:consumes (sort
+                        ["application/json"
+                         "application/edn"])
+            :produces (sort
+                        ["application/json"
+                         "application/edn"])}))))
diff --git a/test19/compojure/api/coercion/issue336_test.clj b/test19/compojure/api/coercion/issue336_test.clj
index 07e390fc..32b6251b 100644
--- a/test19/compojure/api/coercion/issue336_test.clj
+++ b/test19/compojure/api/coercion/issue336_test.clj
@@ -1,5 +1,5 @@
 (ns compojure.api.coercion.issue336-test
-  (:require [midje.sweet :refer :all]
+  (:require [clojure.test :refer [deftest is testing]]
             [compojure.api.test-utils :refer :all]
             [ring.util.http-response :refer :all]
             [compojure.api.sweet :refer :all]
@@ -49,10 +49,10 @@
             :handler (fn [{:keys [query-params]}]
                        (ok query-params))}})))))
 
-(fact "coercion works with s/and"
+(deftest coercion-works-with-s-and-test
   (let [data {:endpoint "http://sushi.cambridge.org/GetReport"
               :customer-id "abc"
               :requestor-id "abc"}
         [status body] (get* app "/api/jr1" data)]
-    status => 200
-    body => data))
+    (is (= status 200))
+    (is (= body data))))
diff --git a/test19/compojure/api/coercion/spec_coercion_explain_test.clj b/test19/compojure/api/coercion/spec_coercion_explain_test.clj
index fc2d6f2a..680d40cd 100644
--- a/test19/compojure/api/coercion/spec_coercion_explain_test.clj
+++ b/test19/compojure/api/coercion/spec_coercion_explain_test.clj
@@ -1,5 +1,5 @@
 (ns compojure.api.coercion.spec-coercion-explain-test
-  (:require [midje.sweet :refer :all]
+  (:require [clojure.test :refer [deftest is testing]]
             [clojure.spec.alpha :as s]
             [spec-tools.spec :as spec]
             [compojure.api.test-utils :refer :all]
@@ -25,16 +25,18 @@
 (def coerced-value {:name "foo" :age "24" :languages #{:clj} :birthdate #inst "1968-01-02T15:04:05Z"})
 (def invalid-value {:name "foo" :age "24" :lanxguages ["clj"] :birthdate "1968-01-02T15:04:05Z"})
 
-(fact "request-coercion"
+(deftest request-coercion-test
   (let [c! #(coercion/coerce-request! ::spec :body-params :body false false %)]
 
-    (fact "default coercion"
-      (c! {:body-params valid-value
-           :muuntaja/request {:format "application/json"}
-           ::request/coercion :spec}) => coerced-value
-      (c! {:body-params invalid-value
-           :muuntaja/request {:format "application/json"}
-           ::request/coercion :spec}) => (throws)
+    (testing "default coercion"
+      (is (= (c! {:body-params valid-value
+                  :muuntaja/request {:format "application/json"}
+                  ::request/coercion :spec})
+             coerced-value))
+      (is (thrown? Exception
+                   (c! {:body-params invalid-value
+                        :muuntaja/request {:format "application/json"}
+                        ::request/coercion :spec})))
       (try
         (c! {:body-params invalid-value
              :muuntaja/request {:format "application/json"}
@@ -42,12 +44,12 @@
         (catch Exception e
           (let [data (ex-data e)
                 spec-problems (get-in data [:problems ::s/problems])]
-            (count spec-problems) => 1
-            (first spec-problems) => (contains {:in []
-                                                :path []
-                                                :val {:age "24"
-                                                      :birthdate #inst "1968-01-02T15:04:05Z"
-                                                      :name "foo"}
-                                                :via [::spec]})))))))
-
-
+            (is (= (count spec-problems) 1))
+            (is (= (select-keys (first spec-problems)
+                                [:in :path :val :via])
+                   {:in []
+                    :path []
+                    :val {:age "24"
+                          :birthdate #inst "1968-01-02T15:04:05Z"
+                          :name "foo"}
+                    :via [::spec]}))))))))
diff --git a/test19/compojure/api/coercion/spec_coercion_test.clj b/test19/compojure/api/coercion/spec_coercion_test.clj
index 2d982df1..d4961679 100644
--- a/test19/compojure/api/coercion/spec_coercion_test.clj
+++ b/test19/compojure/api/coercion/spec_coercion_test.clj
@@ -1,5 +1,6 @@
 (ns compojure.api.coercion.spec-coercion-test
-  (:require [midje.sweet :refer :all]
+  (:require [clojure.test :refer [deftest is testing]]
+            expound.alpha
             [clojure.spec.alpha :as s]
             [compojure.api.test-utils :refer :all]
             [compojure.api.sweet :refer :all]
@@ -42,62 +43,74 @@
 (def valid-value {:kikka :kukka})
 (def invalid-value {:kikka "kukka"})
 
-(fact "request-coercion"
+(deftest request-coercion-test
   (let [c! #(coercion/coerce-request! ::spec :body-params :body false false %)]
 
-    (fact "default coercion"
-      (c! {:body-params valid-value
-           ::request/coercion :spec}) => valid-value
-      (c! {:body-params invalid-value
-           ::request/coercion :spec}) => (throws)
+    (testing "default coercion"
+      (is (= (c! {:body-params valid-value
+                  ::request/coercion :spec})
+             valid-value))
+      (is (thrown? Exception
+                   (c! {:body-params invalid-value
+                        ::request/coercion :spec})))
       (try
         (c! {:body-params invalid-value
              ::request/coercion :spec})
         (catch Exception e
-          (ex-data e) => (contains
-                           {:type :compojure.api.exception/request-validation
-                            :coercion (coercion/resolve-coercion :spec)
-                            :in [:request :body-params]
-                            :spec st/spec?
-                            :value invalid-value
-                            :problems (just {::s/problems [{:in [:kikka]
-                                                            :path [:kikka]
-                                                            :pred `keyword?
-                                                            :val "kukka"
-                                                            :via [::spec ::kikka]}]
-                                             ::s/spec st/spec?
-                                             ::s/value invalid-value})
-                            :request (contains {:body-params {:kikka "kukka"}})}))))
-
-    (fact "coercion also unforms"
+          (is (= (-> (ex-data e)
+                     (select-keys [:type :coercion :in :spec :value :problems :request])
+                     (update :request select-keys [:body-params])
+                     (update :spec (comp boolean st/spec?))
+                     (update-in [:problems ::s/spec] (comp boolean st/spec?)))
+                 {:type :compojure.api.exception/request-validation
+                  :coercion (coercion/resolve-coercion :spec)
+                  :in [:request :body-params]
+                  :spec true
+                  :value invalid-value
+                  :problems {::s/problems [{:in [:kikka]
+                                            :path [:kikka]
+                                            :pred `keyword?
+                                            :val "kukka"
+                                            :via [::spec ::kikka]}]
+                             ::s/spec true
+                             ::s/value invalid-value}
+                  :request {:body-params {:kikka "kukka"}}})))))
+
+    (testing "coercion also unforms"
       (let [spec (s/or :int int? :keyword keyword?)
             c! #(coercion/coerce-request! spec :body-params :body false false %)]
-        (c! {:body-params 1
-             ::request/coercion :spec}) => 1
-        (c! {:body-params :kikka
-             ::request/coercion :spec}) => :kikka))
-
-    (fact "format-based coercion"
-      (c! {:body-params valid-value
-           ::request/coercion :spec
-           :muuntaja/request {:format "application/json"}}) => valid-value
-      (c! {:body-params invalid-value
-           ::request/coercion :spec
-           :muuntaja/request {:format "application/json"}}) => valid-value)
-
-    (fact "no coercion"
-      (c! {:body-params valid-value
-           ::request/coercion nil
-           :muuntaja/request {:format "application/json"}}) => valid-value
-      (c! {:body-params invalid-value
-           ::request/coercion nil
-           :muuntaja/request {:format "application/json"}}) => invalid-value)))
+        (is (= (c! {:body-params 1
+                    ::request/coercion :spec})
+               1))
+        (is (= (c! {:body-params :kikka
+                    ::request/coercion :spec})
+               :kikka))))
+
+    (testing "format-based coercion"
+      (is (= (c! {:body-params valid-value
+                  ::request/coercion :spec
+                  :muuntaja/request {:format "application/json"}})
+             valid-value))
+      (is (= (c! {:body-params invalid-value
+                  ::request/coercion :spec
+                  :muuntaja/request {:format "application/json"}}) 
+             valid-value)))
+
+    (testing "no coercion"
+      (is (= (c! {:body-params valid-value
+                  ::request/coercion nil
+                  :muuntaja/request {:format "application/json"}}) 
+             valid-value))
+      (is (= (c! {:body-params invalid-value
+                  ::request/coercion nil
+                  :muuntaja/request {:format "application/json"}})
+             invalid-value)))))
 
 (defn ok [body]
   {:status 200, :body body})
 
-(defn ok? [body]
-  (contains (ok body)))
+(defn is-ok? [expected value]
+  (is (= (ok expected) (select-keys value [:status :body]))))
 
 (def responses {200 {:schema ::spec}})
 
@@ -107,51 +120,61 @@
     (-> cs/default-options
         (assoc-in [:response :formats "application/json"] cs/json-transformer))))
 
-(fact "response-coercion"
+(deftest response-coercion-test
   (let [c! coercion/coerce-response!]
 
-    (fact "default coercion"
-      (c! {::request/coercion :spec}
-          (ok valid-value)
-          responses) => (ok? valid-value)
-      (c! {::request/coercion :spec}
-          (ok invalid-value)
-          responses) => (throws)
+    (testing "default coercion"
+      (is-ok? valid-value
+              (c! {::request/coercion :spec}
+                  (ok valid-value)
+                  responses))
+      (is (thrown? Exception
+                   (c! {::request/coercion :spec}
+                       (ok invalid-value)
+                       responses)))
       (try
         (c! {::request/coercion :spec} (ok invalid-value) responses)
         (catch Exception e
-          (ex-data e) => (contains {:type :compojure.api.exception/response-validation
-                                    :coercion (coercion/resolve-coercion :spec)
-                                    :in [:response :body]
-                                    :spec st/spec?
-                                    :value invalid-value
-                                    :problems anything
-                                    :request {::request/coercion :spec}}))))
-
-    (fact "format-based custom coercion"
-      (fact "request-negotiated response format"
-        (c! irrelevant
-            (ok invalid-value)
-            responses) => throws
-        (c! {:muuntaja/response {:format "application/json"}
-             ::request/coercion custom-coercion}
-            (ok invalid-value)
-            responses) => (ok? valid-value)))
-
-    (fact "no coercion"
-      (c! {::request/coercion nil}
-          (ok valid-value)
-          responses) => (ok? valid-value)
-      (c! {::request/coercion nil}
-          (ok invalid-value)
-          responses) => (ok? invalid-value))))
+          (is (= (-> (ex-data e)
+                     (select-keys [:type :coercion :in :spec :value :problems :request])
+                     (update :spec (comp boolean st/spec?))
+                     (update :problems some?))
+                 {:type :compojure.api.exception/response-validation
+                  :coercion (coercion/resolve-coercion :spec)
+                  :in [:response :body]
+                  :spec true
+                  :value invalid-value
+                  :problems true
+                  :request {::request/coercion :spec}})))))
+
+    (testing "format-based custom coercion"
+      (testing "request-negotiated response format"
+        (is (thrown? Exception
+                     (c! nil
+                         (ok invalid-value)
+                         responses)))
+        (is-ok? valid-value
+                (c! {:muuntaja/response {:format "application/json"}
+                     ::request/coercion custom-coercion}
+                    (ok invalid-value)
+                    responses))))
+
+    (testing "no coercion"
+      (is-ok? valid-value
+              (c! {::request/coercion nil}
+                  (ok valid-value)
+                  responses))
+      (is-ok? invalid-value
+              (c! {::request/coercion nil}
+                  (ok invalid-value)
+                  responses)))))
 
 (s/def ::x int?)
 (s/def ::y int?)
 (s/def ::xy (s/keys :req-un [::x ::y]))
 (s/def ::total pos-int?)
 
-(facts "apis"
+(deftest apis-test
   (let [app (api
               {:swagger {:spec "/swagger.json"}
                :coercion :spec}
@@ -214,111 +237,120 @@
                          :handler (fn [{body-params :body-params}]
                                     (ok body-params))}})))]
 
-    (fact "query"
+    (testing "query"
       (let [[status body] (get* app "/query" {:x "1", :y 2})]
-        status => 200
-        body => {:total 3})
+        (is (= status 200))
+        (is (= body {:total 3})))
       (let [[status body] (get* app "/query" {:x "1", :y "kaks"})]
-        status => 400
-        body => (contains
-                  {:coercion "spec"
-                   :in ["request" "query-params"]
-                   :problems (one-of anything)
-                   :spec string?
-                   :type "compojure.api.exception/request-validation"
-                   :value {:x "1", :y "kaks"}})))
-
-    (fact "body"
+        (is (= status 400))
+        (is (= (-> body
+                   (select-keys [:coercion :in :problems :spec :type :value])
+                   (update :problems count)
+                   (update :spec string?))
+               {:coercion "spec"
+                :in ["request" "query-params"]
+                :problems 1
+                :spec true
+                :type "compojure.api.exception/request-validation"
+                :value {:x "1", :y "kaks"}}))))
+
+    (testing "body"
       (let [[status body] (post* app "/body" (json-string {:x 1, :y 2, :z 3}))]
-        status => 200
-        body => {:total 3}))
+        (is (= status 200))
+        (is (= body {:total 3}))))
 
-    (fact "body-map"
+    (testing "body-map"
       (let [[status body] (post* app "/body-map" (json-string {:x 1, :y 2}))]
-        status => 200
-        body => {:total 3})
+        (is (= status 200))
+        (is (= body {:total 3})))
       (let [[status body] (post* app "/body-map" (json-string {:x 1}))]
-        status => 200
-        body => {:total 1}))
+        (is (= status 200))
+        (is (= body {:total 1}))))
 
-    (fact "body-string"
+    (testing "body-string"
       (let [[status body] (post* app "/body-string" (json-string "kikka"))]
-        status => 200
-        body => {:body "kikka"}))
+        (is (= status 200))
+        (is (= body {:body "kikka"}))))
 
-    (fact "query-params"
+    (testing "query-params"
       (let [[status body] (get* app "/query-params" {:x "1", :y 2})]
-        status => 200
-        body => {:total 3})
+        (is (= status 200))
+        (is (= body {:total 3})))
       (let [[status body] (get* app "/query-params" {:x "1", :y "a"})]
-        status => 400
-        body => (contains {:coercion "spec"
-                           :in ["request" "query-params"]})))
+        (is (= status 400))
+        (is (= (select-keys body [:coercion :in])
+               {:coercion "spec"
+                :in ["request" "query-params"]}))))
 
-    (fact "body-params"
+    (testing "body-params"
       (let [[status body] (post* app "/body-params" (json-string {:x 1, :y 2}))]
-        status => 200
-        body => {:total 3})
+        (is (= status 200))
+        (is (= body {:total 3})))
       (let [[status body] (post* app "/body-params" (json-string {:x 1}))]
-        status => 200
-        body => {:total 1})
+        (is (= status 200))
+        (is (= body {:total 1})))
       (let [[status body] (post* app "/body-params" (json-string {:x "1"}))]
-        status => 400
-        body => (contains {:coercion "spec"
-                           :in ["request" "body-params"]})))
+        (is (= status 400))
+        (is (= (select-keys body [:coercion :in])
+               {:coercion "spec"
+                :in ["request" "body-params"]}))))
 
-    (fact "response"
+    (testing "response"
       (let [[status body] (get* app "/response" {:x 1, :y 2})]
-        status => 200
-        body => {:total 3})
+        (is (= status 200))
+        (is (= body {:total 3})))
       (let [[status body] (get* app "/response" {:x -1, :y -2})]
-        status => 500
-        body => (contains {:coercion "spec"
-                           :in ["response" "body"]})))
+        (is (= status 500))
+        (is (= (select-keys body [:coercion :in])
+               {:coercion "spec"
+                :in ["response" "body"]}))))
 
-    (fact "customer coercion & custom predicate"
+    (testing "customer coercion & custom predicate"
       (let [[status body] (get* app "/date/pass")]
-        status => 200)
+        (is (= status 200)))
       (let [[status body] (get* app "/date/fail")]
-        status => 500
-        body => (contains {:coercion "custom"
-                           :in ["response" "body"]})))
-    (fact "resource"
-      (fact "parameters as specs"
+        (is (= status 500))
+        (is (= (select-keys body [:coercion :in])
+               {:coercion "custom"
+                :in ["response" "body"]}))))
+    (testing "resource"
+      (testing "parameters as specs"
         (let [[status body] (get* app "/resource" {:x 1, :y 2})]
-          status => 200
-          body => {:total 3})
+          (is (= status 200))
+          (is (= body {:total 3})))
         (let [[status body] (get* app "/resource" {:x -1, :y -2})]
-          status => 500
-          body => (contains {:coercion "spec"
-                             :in ["response" "body"]})))
+          (is (= status 500))
+          (is (= (select-keys body [:coercion :in])
+                 {:coercion "spec"
+                  :in ["response" "body"]}))))
 
-      (fact "parameters as data-specs"
+      (testing "parameters as data-specs"
         (let [[status body] (post* app "/resource" (json-string {:x 1, :y 2}))]
-          status => 200
-          body => {:total 3})
+          (is (= status 200))
+          (is (= body {:total 3})))
         (let [[status body] (post* app "/resource" (json-string {:x 1}))]
-          status => 200
-          body => {:total 1})
+          (is (= status 200))
+          (is (= body {:total 1})))
         (let [[status body] (post* app "/resource" (json-string {:x -1, :y -2}))]
-          status => 500
-          body => (contains {:coercion "spec"
-                             :in ["response" "body"]}))))
+          (is (= status 500))
+          (is (= (select-keys body [:coercion :in])
+                 {:coercion "spec"
+                  :in ["response" "body"]})))))
 
-    (fact "extra keys are stripped from body-params before validation"
-      (fact "for resources"
+    (testing "extra keys are stripped from body-params before validation"
+      (testing "for resources"
         (let [[status body] (put* app "/resource" (json-string {:x 1, :y 2 ::kikka "kakka"}))]
-          status => 200
-          body => {:x 1, :y 2}))
-      (fact "for endpoints"
+          (is (= status 200))
+          (is (= body {:x 1, :y 2}))))
+      (testing "for endpoints"
         (let [[status body] (put* app "/body" (json-string {:x 1, :y 2 ::kikka "kakka"}))]
-          status => 200
-          body => {:x 1, :y 2})))
+          (is (= status 200))
+          (is (= body {:x 1, :y 2})))))
 
-    (fact "generates valid swagger spec"
-      (validator/validate app) =not=> (throws))
+    (testing "generates valid swagger spec"
+      (is (do (validator/validate app) true)))
 
-    (fact "swagger spec has all things"
+    (testing "swagger spec has all things"
       (let [total-schema {:description "",
                           :schema {:properties
                                    {:total {:format "int64",
@@ -326,179 +358,178 @@
                                             :type "integer"}},
                                    :required ["total"],
                                    :type "object"}}]
-        (get-spec app)
-        => (contains
-             {:basePath "/"
-              :consumes ["application/json"
-                         "application/transit+msgpack"
-                         "application/transit+json"
-                         "application/edn"]
-              :definitions {}
-              :info {:title "Swagger API" :version "0.0.1"}
-              :paths {"/body" {:post {:parameters [{:description ""
-                                                    :in "body"
-                                                    :name "compojure.api.coercion.spec-coercion-test/xy"
-                                                    :required true
-                                                    :schema {:properties {:x {:format "int64"
-                                                                              :type "integer"}
-                                                                          :y {:format "int64"
-                                                                              :type "integer"}}
-                                                             :required ["x" "y"]
-                                                             :title "compojure.api.coercion.spec-coercion-test/xy"
-                                                             :type "object"}}]
-                                      :responses {:default {:description ""}}}
-                               :put {:parameters [{:description ""
-                                                   :in "body"
-                                                   :name "compojure.api.coercion.spec-coercion-test/xy"
-                                                   :required true
-                                                   :schema {:properties {:x {:format "int64"
-                                                                             :type "integer"}
-                                                                         :y {:format "int64"
-                                                                             :type "integer"}}
-                                                            :required ["x" "y"]
-                                                            :title "compojure.api.coercion.spec-coercion-test/xy"
-                                                            :type "object"}}]
-                                     :responses {:default {:description ""}}}}
-                      "/body-map" {:post {:parameters [{:description ""
-                                                        :in "body"
-                                                        :name ""
-                                                        :required true
-                                                        :schema {:properties {:x {:format "int64"
-                                                                                  :type "integer"}
-                                                                              :y {:format "int64"
-                                                                                  :type "integer"}}
-                                                                 :required ["x"]
-                                                                 :type "object"}}]
-                                          :responses {:default {:description ""}}}}
-                      "/body-params" {:post {:parameters [{:description ""
-                                                           :in "body"
-                                                           :name ""
-                                                           :required true
-                                                           :schema {:properties {:x {:format "int64"
-                                                                                     :type "integer"}
-                                                                                 :y {:format "int64"
-                                                                                     :type "integer"}}
-                                                                    :required ["x"]
-                                                                    :type "object"}}]
-                                             :responses {:default {:description ""}}}}
-                      "/body-string" {:post {:parameters [{:description ""
-                                                           :in "body"
-                                                           :name ""
-                                                           :required true
-                                                           :schema {:type "string"}}]
-                                             :responses {:default {:description ""}}}}
-                      "/date/fail" {:get {:responses {:200 {:description ""
-                                                            :schema {:properties {:date {:default "2017-10-12T05:04:57.585Z"}}
-                                                                     :required ["date"]
-                                                                     :type "object"}}
-                                                      :default {:description ""}}}}
-                      "/date/pass" {:get {:responses {:200 {:description ""
-                                                            :schema {:properties {:date {:default "2017-10-12T05:04:57.585Z"}}
-                                                                     :required ["date"]
-                                                                     :type "object"}}
-                                                      :default {:description ""}}}}
-                      "/query" {:get {:parameters [{:description ""
-                                                    :format "int64"
-                                                    :in "query"
-                                                    :name "x"
-                                                    :required true
-                                                    :type "integer"}
-                                                   {:description ""
-                                                    :format "int64"
-                                                    :in "query"
-                                                    :name "y"
-                                                    :required true
-                                                    :type "integer"}]
-                                      :responses {:default {:description ""}}}}
-                      "/query-params" {:get {:parameters [{:description ""
-                                                           :format "int64"
-                                                           :in "query"
-                                                           :name "x"
-                                                           :required true
-                                                           :type "integer"}
-                                                          {:description ""
-                                                           :format "int64"
-                                                           :in "query"
-                                                           :name "y"
-                                                           :required true
-                                                           :type "integer"}]
-                                             :responses {:default {:description ""}}}}
-                      "/resource" {:get {:parameters [{:description ""
-                                                       :format "int64"
-                                                       :in "query"
-                                                       :name "x"
-                                                       :required true
-                                                       :type "integer"}
-                                                      {:description ""
-                                                       :format "int64"
-                                                       :in "query"
-                                                       :name "y"
-                                                       :required true
-                                                       :type "integer"}]
-                                         :responses {:200 {:description ""
-                                                           :schema {:properties {:total {:format "int64"
-                                                                                         :minimum 1
-                                                                                         :type "integer"}}
-                                                                    :required ["total"]
-                                                                    :type "object"}}
-                                                     :default {:description ""}}}
-                                   :post {:parameters [{:description ""
-                                                        :in "body"
-                                                        :name ""
-                                                        :required true
-                                                        :schema {:properties {:x {:format "int64"
-                                                                                  :type "integer"}
-                                                                              :y {:format "int64"
-                                                                                  :type "integer"}}
-                                                                 :required ["x"]
-                                                                 :type "object"}}]
-                                          :responses {:200 {:description ""
-                                                            :schema {:properties {:total {:format "int64"
-                                                                                          :minimum 1
-                                                                                          :type "integer"}}
-                                                                     :required ["total"]
-                                                                     :type "object"}}
-                                                      :default {:description ""}}}
-                                   :put {:parameters [{:description ""
-                                                       :in "body"
-                                                       :name "compojure.api.coercion.spec-coercion-test/xy"
-                                                       :required true
-                                                       :schema {:properties {:x {:format "int64"
-                                                                                 :type "integer"}
-                                                                             :y {:format "int64"
-                                                                                 :type "integer"}}
-                                                                :required ["x" "y"]
-                                                                :title "compojure.api.coercion.spec-coercion-test/xy"
-                                                                :type "object"}}]
-                                         :responses {:default {:description ""}}}}
-                      "/response" {:get {:parameters [{:description ""
-                                                       :format "int64"
-                                                       :in "query"
-                                                       :name "x"
-                                                       :required true
-                                                       :type "integer"}
-                                                      {:description ""
-                                                       :format "int64"
-                                                       :in "query"
-                                                       :name "y"
-                                                       :required true
-                                                       :type "integer"}]
-                                         :responses {:200 {:description ""
-                                                           :schema {:properties {:total {:format "int64"
-                                                                                         :minimum 1
-                                                                                         :type "integer"}}
-                                                                    :required ["total"]
-                                                                    :type "object"}}
-                                                     :default {:description ""}}}}}
-              :produces ["application/json"
-                         "application/transit+msgpack"
-                         "application/transit+json"
-                         "application/edn"]
-              :swagger "2.0"})))))
+        (is (= (get-spec app)
+               {:basePath "/"
+                :consumes ["application/json"
+                           "application/transit+msgpack"
+                           "application/transit+json"
+                           "application/edn"]
+                :definitions {}
+                :info {:title "Swagger API" :version "0.0.1"}
+                :paths {"/body" {:post {:parameters [{:description ""
+                                                      :in "body"
+                                                      :name "compojure.api.coercion.spec-coercion-test/xy"
+                                                      :required true
+                                                      :schema {:properties {:x {:format "int64"
+                                                                                :type "integer"}
+                                                                            :y {:format "int64"
+                                                                                :type "integer"}}
+                                                               :required ["x" "y"]
+                                                               :title "compojure.api.coercion.spec-coercion-test/xy"
+                                                               :type "object"}}]
+                                        :responses {:default {:description ""}}}
+                                 :put {:parameters [{:description ""
+                                                     :in "body"
+                                                     :name "compojure.api.coercion.spec-coercion-test/xy"
+                                                     :required true
+                                                     :schema {:properties {:x {:format "int64"
+                                                                               :type "integer"}
+                                                                           :y {:format "int64"
+                                                                               :type "integer"}}
+                                                              :required ["x" "y"]
+                                                              :title "compojure.api.coercion.spec-coercion-test/xy"
+                                                              :type "object"}}]
+                                       :responses {:default {:description ""}}}}
+                        "/body-map" {:post {:parameters [{:description ""
+                                                          :in "body"
+                                                          :name ""
+                                                          :required true
+                                                          :schema {:properties {:x {:format "int64"
+                                                                                    :type "integer"}
+                                                                                :y {:format "int64"
+                                                                                    :type "integer"}}
+                                                                   :required ["x"]
+                                                                   :type "object"}}]
+                                            :responses {:default {:description ""}}}}
+                        "/body-params" {:post {:parameters [{:description ""
+                                                             :in "body"
+                                                             :name ""
+                                                             :required true
+                                                             :schema {:properties {:x {:format "int64"
+                                                                                       :type "integer"}
+                                                                                   :y {:format "int64"
+                                                                                       :type "integer"}}
+                                                                      :required ["x"]
+                                                                      :type "object"}}]
+                                               :responses {:default {:description ""}}}}
+                        "/body-string" {:post {:parameters [{:description ""
+                                                             :in "body"
+                                                             :name ""
+                                                             :required true
+                                                             :schema {:type "string"}}]
+                                               :responses {:default {:description ""}}}}
+                        "/date/fail" {:get {:responses {:200 {:description ""
+                                                              :schema {:properties {:date {:default "2017-10-12T05:04:57.585Z"}}
+                                                                       :required ["date"]
+                                                                       :type "object"}}
+                                                        :default {:description ""}}}}
+                        "/date/pass" {:get {:responses {:200 {:description ""
+                                                              :schema {:properties {:date {:default "2017-10-12T05:04:57.585Z"}}
+                                                                       :required ["date"]
+                                                                       :type "object"}}
+                                                        :default {:description ""}}}}
+                        "/query" {:get {:parameters [{:description ""
+                                                      :format "int64"
+                                                      :in "query"
+                                                      :name "x"
+                                                      :required true
+                                                      :type "integer"}
+                                                     {:description ""
+                                                      :format "int64"
+                                                      :in "query"
+                                                      :name "y"
+                                                      :required true
+                                                      :type "integer"}]
+                                        :responses {:default {:description ""}}}}
+                        "/query-params" {:get {:parameters [{:description ""
+                                                             :format "int64"
+                                                             :in "query"
+                                                             :name "x"
+                                                             :required true
+                                                             :type "integer"}
+                                                            {:description ""
+                                                             :format "int64"
+                                                             :in "query"
+                                                             :name "y"
+                                                             :required true
+                                                             :type "integer"}]
+                                               :responses {:default {:description ""}}}}
+                        "/resource" {:get {:parameters [{:description ""
+                                                         :format "int64"
+                                                         :in "query"
+                                                         :name "x"
+                                                         :required true
+                                                         :type "integer"}
+                                                        {:description ""
+                                                         :format "int64"
+                                                         :in "query"
+                                                         :name "y"
+                                                         :required true
+                                                         :type "integer"}]
+                                           :responses {:200 {:description ""
+                                                             :schema {:properties {:total {:format "int64"
+                                                                                           :minimum 1
+                                                                                           :type "integer"}}
+                                                                      :required ["total"]
+                                                                      :type "object"}}
+                                                       :default {:description ""}}}
+                                     :post {:parameters [{:description ""
+                                                          :in "body"
+                                                          :name ""
+                                                          :required true
+                                                          :schema {:properties {:x {:format "int64"
+                                                                                    :type "integer"}
+                                                                                :y {:format "int64"
+                                                                                    :type "integer"}}
+                                                                   :required ["x"]
+                                                                   :type "object"}}]
+                                            :responses {:200 {:description ""
+                                                              :schema {:properties {:total {:format "int64"
+                                                                                            :minimum 1
+                                                                                            :type "integer"}}
+                                                                       :required ["total"]
+                                                                       :type "object"}}
+                                                        :default {:description ""}}}
+                                     :put {:parameters [{:description ""
+                                                         :in "body"
+                                                         :name "compojure.api.coercion.spec-coercion-test/xy"
+                                                         :required true
+                                                         :schema {:properties {:x {:format "int64"
+                                                                                   :type "integer"}
+                                                                               :y {:format "int64"
+                                                                                   :type "integer"}}
+                                                                  :required ["x" "y"]
+                                                                  :title "compojure.api.coercion.spec-coercion-test/xy"
+                                                                  :type "object"}}]
+                                           :responses {:default {:description ""}}}}
+"/response" {:get {:parameters [{:description ""
+                                 :format "int64"
+                                 :in "query"
+                                 :name "x"
+                                 :required true
+                                 :type "integer"}
+                                {:description ""
+                                 :format "int64"
+                                 :in "query"
+                                 :name "y"
+                                 :required true
+                                 :type "integer"}]
+                   :responses {:200 {:description ""
+                                     :schema {:properties {:total {:format "int64"
+                                                                   :minimum 1
+                                                                   :type "integer"}}
+                                              :required ["total"]
+                                              :type "object"}}
+                               :default {:description ""}}}}}
+                   :produces ["application/json"
+                              "application/transit+msgpack"
+                              "application/transit+json"
+                              "application/edn"]
+                   :swagger "2.0"}))))))
 
 (s/def ::id pos-int?)
 
-(fact "spec coercion in context"
+(deftest spec-coercion-in-context-test
   (let [app (context "/product/:id" []
               :coercion :spec
               :path-params [id :- ::id]
@@ -506,13 +537,12 @@
                 :return ::id
                 (ok id)))
         [status body] (get* app "/product/1/foo")]
-    status => 200
-    body => 1))
+    (is (= status 200))
+    (is (= body 1))))
 
-(comment
-  (require '[expound.alpha])
+(deftest expound-test
 
-  (facts "custom spec printer"
+  (testing "custom spec printer"
     (let [printer (expound.alpha/custom-printer {:theme :figwheel-theme, :print-specs? false})
           app (api
                 {:coercion :spec
@@ -529,15 +559,15 @@
                   :body-params [x :- int?, y :- int?]
                   :return {:total pos-int?}
                   (ok {:total (+ x y)})))]
-      (fact "success"
+      (testing "success"
         (let [[status body] (post* app "/math" (json-string {:x 1, :y 2}))]
-          status => 200
-          body => {:total 3}))
+          (is (= status 200))
+          (is (= body {:total 3}))))
 
-      (fact "request failure"
+      (testing "request failure"
         (let [[status] (post* app "/math" (json-string {:x 1, :y "2"}))]
-          status => 400))
+          (is (= status 400))))
 
-      (fact "response failure"
+      (testing "response failure"
         (let [[status] (post* app "/math" (json-string {:x 1, :y -2}))]
-          status => 500)))))
+          (is (= status 500)))))))