diff --git a/src/greenlight/test.clj b/src/greenlight/test.clj index 393f29a..076052b 100644 --- a/src/greenlight/test.clj +++ b/src/greenlight/test.clj @@ -3,6 +3,7 @@ specific usage scenario." (:require [clojure.spec.alpha :as s] + [clojure.test :as ctest] [clojure.string :as str] [greenlight.step :as step]) (:import @@ -152,27 +153,33 @@ "Executes a sequence of test steps by running them in order until one fails. Returns a tuple with the enriched vector of steps run and the final context map." - [system options ctx steps] - (loop [history [] - ctx ctx - steps steps] - (if-let [step (first steps)] - ; Run next step to advance the test. - (let [step (step/initialize step ctx) - _ (*report* {:type :step-start - :step step}) - [step' ctx'] (step/advance! system step ctx) - history' (conj history step')] - (*report* {:type :step-end - :step step'}) - ; Continue while steps pass. - (if (= :pass (::step/outcome step')) - (recur history' ctx' (next steps)) - (if (retry-step? options step') - (recur history ctx steps) - [(vec (concat history' (rest steps))) ctx']))) - ; No more steps. - [history ctx]))) + [system options ctx test-case] + (let [each-fixture-fn (ctest/join-fixtures (::each test-case))] + (loop [history [] + ctx ctx + steps (::steps test-case)] + (if-let [step (first steps)] + ;; Run next step to advance the test. + (let [step (-> step + (step/initialize ctx) + (update ::step/test + (fn [test-fn] + (fn [inputs] + (each-fixture-fn #(test-fn inputs)))))) + _ (*report* {:type :step-start + :step step}) + [step' ctx'] (step/advance! system step ctx) + history' (conj history step')] + (*report* {:type :step-end + :step step'}) + ;; Continue while steps pass. + (if (= :pass (::step/outcome step')) + (recur history' ctx' (next steps)) + (if (retry-step? options step') + (recur history ctx steps) + [(vec (concat history' (rest steps))) ctx']))) + ;; No more steps. + [history ctx])))) (defn- run-cleanup! @@ -203,7 +210,14 @@ :test test-case}) (let [started-at (Instant/now) ctx (::context test-case {}) - [history ctx] (run-steps! system options ctx (::steps test-case)) + each-fixture-fn (-> test-case + ::ns + the-ns + meta + ::ctest/each + ctest/join-fixtures) + [history ctx] (each-fixture-fn + #(run-steps! system options ctx test-case)) _ (run-cleanup! system history) ended-at (Instant/now) test-case (assoc test-case diff --git a/test/greenlight/test_suite/blue.clj b/test/greenlight/test_suite/blue.clj index a257e5f..986ab18 100644 --- a/test/greenlight/test_suite/blue.clj +++ b/test/greenlight/test_suite/blue.clj @@ -1,6 +1,6 @@ (ns greenlight.test-suite.blue (:require - [clojure.test :refer [is]] + [clojure.test :refer [is use-fixtures]] [com.stuartsierra.component :as component] [greenlight.step :as step :refer [defstep]] [greenlight.test :as test :refer [deftest]])) @@ -51,6 +51,31 @@ :test (fn [_] (is (= 1 1)))}) +(def counter + (atom 0)) + +(use-fixtures :each + (fn [f] + (reset! counter 0) + (f))) + +(deftest with-fixtures + #::test{:description "foobar" + :context {:foo :bar} + :each [(fn [f] + (swap! counter inc) + (f)) + (fn [f] + (swap! counter inc) + (f))]} + #::step{:name 'step-1 + :title "step-1" + :test (fn [_] + (is (= 1 1)))} + #::step{:name 'step-2 + :title "step-2" + :test (fn [_] + (is (= 1 1)))}) (deftest sample-test "A sample greenlight test in the blue test suite" diff --git a/test/greenlight/test_test.clj b/test/greenlight/test_test.clj index ecc7b87..88ddc9b 100644 --- a/test/greenlight/test_test.clj +++ b/test/greenlight/test_test.clj @@ -57,6 +57,17 @@ (mapv ::step/title (::test/steps test-result)))) (is (= 1 (count (::test/steps test-result)))))) +(deftest fixtures-test + (let [system (component/system-map :greenlight.test-test/component 6) + attr-test (blue/with-fixtures) + test-result (test/run-test! system attr-test)] + (is (= (::test/description test-result) "foobar")) + (is (= (::test/context test-result) {:foo :bar})) + (is (= :pass (::test/outcome test-result))) + (is (= 4 @blue/counter)) + (is (= ["step-1" "step-2"] + (mapv ::step/title (::test/steps test-result)))) + (is (= 2 (count (::test/steps test-result)))))) (defmacro with-io [input & forms]