RCT turns rich comment forms into tests.
^:rct/test
(comment
(+ 1 1) ;=> 2
(+ 1 1) ;=> 3
)
(com.mjdowney.rich-comment-tests/run-ns-tests! *ns*)
; Testing com.mjdowney.rich-comment-tests.example
;
; FAIL in () (example.clj:4)
; expected: (= (+ 1 1) 3)
; actual: (not (= 2 3))
;
; Ran 1 tests containing 2 assertions.
; 1 failures, 0 errors.
;=> {:test 1, :pass 1, :fail 1, :error 0}
CHANGELOG | Uses Break Versioning
io.github.matthewdowney/rich-comment-tests {:git/tag "v1.0.2" :git/sha "4501366"}
RCT is a version of the excellent hyperfiddle/rcf
that uses rewrite-clj
to evaluate comment
blocks and match the result of each sexpr against
;=> result
comments.
It was inspired by the discussion in hyperfiddle/rcf/issues/49. Further discussion / feature requests welcome.
Its goals are to encourage writing rich comment forms in the most natural
way possible, using normal (comment ...)
forms and Clojure comments, and to
integrate nicely with both REPL and clojure.test workflows.
Non-goals include providing advanced unit test features and syntax (the
original hyperfiddle/rcf is much better for this!) or completely replacing
clojure.test. I see this as a complementary tool to aid in REPL development,
help keep examples from comment
forms up to date with CI, and encourage
writing small tests alongside the function under test.
comment
forms as you normally would, and tag some of them with
{:rct/test true}
.run-ns-tests!
to the REPL (I
have an editor shortcut that reloads the namespace and then does this).RCT supports two kinds of assertions:
=>
asserts literal equality=>>
asserts a matcho pattern
(and allows ... to indicate a partial pattern)Assertions are either part of the comment or follow it directly.
^:rct/test
(comment
;; Literal assertions with =>
(range 3) ;=> (0 1 2)
(+ 5 5) ;; => 10
(System/getProperty "java.version.date") ;=> "2022-09-20"
;; Pattern matching assertions with =>>
(range 3) ;=>> '(0 1 ...)
(+ 5 5) ;=>> int?
(into {} (System/getProperties))
;=>> {"java.version.date" #"\d{4}-\d{2}-\d{2}"}
(def response {:status 200 :body "ok"})
response
;=>> {:status #(< % 300)
; :body not-empty}
;; Or with spec
(require '[clojure.spec.alpha :as s])
(into {} (System/getProperties)) ;=>> (s/map-of string? string?)
;; Or using a blank ;=> line to match against the next form
response
;=>
{:status 200
:body "ok"}
)
RCT is designed to hook in nicely with clojure.test
reporting / assertion
counting, and to be easy to run from an idiomatic Clojure CI workflow.
deftest
to run all rich comment tests in the source treeThis works well for the following scenario:
test/
directory with source files that use clojure.test
+ deftest
,src
directory with rich comment tests sprinkled throughout,(ns some-test-ns
(:require [clojure.test :refer :all]
[com.mjdowney.rich-comment-tests.test-runner :as test-runner]))
(deftest rct-tests
(test-runner/run-tests-in-file-tree! :dirs #{"src"}))
Now when you run clojure.test
, rich comment tests are also included.
This is what happens when you run this project with:
clj -X:test
For a project that only uses rich comment tests, you can add an alias to
deps.edn
:
{:aliases
{:test {:exec-fn com.mjdowney.rich-comment-tests.test-runner/run-tests-in-file-tree!
:exec-args {:dirs #{"src"}}}}}
Sample bb.edn file to run RCTs via bb test
:
{:paths ["src"]
:deps {}
:tasks {test
{:docs "Run unit tests."
:extra-deps {io.github.matthewdowney/rich-comment-tests {...}}
:requires ([com.mjdowney.rich-comment-tests.test-runner :as rct])
:task (rct/run-tests-in-file-tree! {:dirs #{"src"}})}}}
See also: Running tests from the Babashka book.
v1.0.2 (2023-02-09)
v1.0.1 (2023-02-07)
v1.0.0 — no breaking changes, API is now stable 🎉 (2023-01-21)
v0.0.4 (2023-01-04)
v0.0.3 (2022-12-11)
;=>>
#2v0.0.2 (2022-12-07)
clojure.test
reporting + way to run RCT alongside itv0.0.1 (2022-12-06)
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close