Clornichon = Clojure + cornichon, the French gherkin. Write your specifications in plain Gherkin (Given/When/Then), bind each step to a Clojure function, run them with clojure.test or Kaocha.
io.cucumber/gherkin, the reference implementation -- ~70 languages, Rule, Background, Scenario Outline, tags, datatables and doc strings."I add {int} items to the {string} cart", or a plain regex when you need one. A missing step prints the glue skeleton to paste.--dry-run that catches undefined steps before anything runs.important
Performance is a first-class concern. Clornichon runs the acceptance suites of a large production codebase: 250+ features, 500+ scenarios and 3,400 steps bound to 440 step definitions. At that scale every millisecond spent per step shows, so the library does its work up front -- the glue of each step is resolved once, at parse time, not on every execution -- and a slower run is treated as a regression.
tip
Coming from scenari? The migration is mostly a dependency swap: the namespaces, the macros, the deffeature options and the :kaocha.type/scenari test type are unchanged. Under the hood the Gherkin parser and the step matching are now Cucumber's own, which makes feature files and step sentences a little stricter. A handful of glues and sentences may need a touch; --dry-run finds them without running anything. See Migrating from scenari.
;; deps.edn
io.github.hiram-madelaine/clornichon {:mvn/version "0.1.2"}
;; or project.clj
[io.github.hiram-madelaine/clornichon "0.1.2"]
# test/features/cart.feature
Feature: shopping cart
Scenario: adding items
Given a cart with 2 items
When I add 3 items
Then the cart holds 5 items
(ns cart-test
(:require [clojure.test :refer [is]]
[scenari.v2.core :refer [defgiven defwhen defthen deffeature]]))
(defgiven "a cart with {int} items" [_ n] {:cart n})
(defwhen "I add {int} items" [state n] (update state :cart + n))
(defthen "the cart holds {int} items" [state n] (is (= n (:cart state))))
(deffeature shopping-cart "test/features/cart.feature") ; a deftest
Run it like any test: clojure.test/run-tests, your editor, or Kaocha.
Also on cljdoc.
--tags, --dry-run, --doc-htmlClornichon started as a fork of scenari, written by Jérémie Grodziski at DefSquare, and has since diverged far enough to go its own way: the Gherkin parser, the step expressions, the Kaocha integration and the reporting have been rewritten. The namespaces still carry the scenari name. Thanks to the original authors for the foundations.
In the words of scenari's original author:
I'm used to JBehave and I wanted a BDD framework with an external DSL following the gherkin grammar but also with an easy and fast setup and with steps written in Clojure. The previous BDD attempt I known in Clojure were all with an internal DSL. I prefer an external one because I think it's easier to share the scenarios with a domain expert. I you prefer an internal DSL BDD Framework, have a look at Speclj.
Jérémie presented the internals of the original library at the Clojure Paris User Group and the slides are here: "Anatomy of a BDD Execution Library in Clojure".
Clornichon is released under the terms of the MIT License.
Copyright © 2024 DefSquare defsquare.io
Copyright © 2026 Hiram Madelaine
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Can you improve this documentation? These fine people already did:
jeremiegrodziski, Jérémie Grodziski, Hiram MADELAINE, davidpanza, Zenmodeler & Jan MonterrubioEdit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |