Language, Expression and Design



April 2016

fudje - a sweeter test framework

by Chris Zheng,

I'm been one of the biggest fans of midje ever since I laid eyes on the beautiful syntax and watched the amazing TDD videos by Brian Marick. The library changed my perception of testing to be THE means of development as opposed to being relegated to just "part" of the development cycle.

Having the => input/output forms meant that midje tests were as readable as documentation. It led to my own explorations in how design and testing should be done and I am so thankful for the initial inspiration.

However, midje has been a victim of it's own success and the initial flurry of code, pull-requests, and commits has resulted in bloat and features that may have needed more 'hammock time' to mature. I'm not exactly sure what the deal is with the currently state of development but progress has slowed down significantly ever since the 1.5 release.

A look at the current midje 1.6.3 library shows such a list of dependencies:

(coordinate-dependencies '[[midje "1.6.3"]])
 > [[ordered "1.2.0"] 
    [colorize "0.1.1"]
    [org.clojure/core.unify "0.5.2"] 
    [utilize "0.2.3"]
    [net.cgrand/regex "1.1.0"] 
    [gui-diff "0.5.0"]
    [joda-time "2.0"] 
    [clj-time "0.6.0"]
    [org.clojars.trptcolin/sjacket "0.1.3"]
    [commons-codec "1.6"] 
    [slingshot "0.10.3"]
    [net.cgrand/parsley "0.9.1"] 
    [dynapath "0.2.0"]
    [org.clojure/tools.namespace "0.2.4"]
    [org.clojure/math.combinatorics "0.0.7"]
    [org.clojure/tools.macro "0.1.1"] 
    [swiss-arrows "1.0.0"]]

As many engineers that I have worked with have told me time and time again:

that's a lot of dependencies for =>

Well... I didn't really care. For me, I would rather have a bloated framework that allows expression rather than something faster but results in less readable code (this is the same losing battle I've been fighting with angular vs react). Also, I have so much documentation that has been automatically generated out of test files using the midje syntax that I could not go and change the >2000 tests on the projects that I have accumulated over the years.

Anyways, I've stayed on the 1.6.3 version of midje for the longest time and watched utilities built on top of clojure.test mature and gain traction. Two frameworks leveraging clojure.test have resulted in its rapid adoption at the expense of midje are:

I have been very vocal in terms of letting everyone whom I work with where my alligence lies: Expressivity. As far as I was concerned, midje's fact's offered much more over deftest's. However, I knew that it was inevitable that clojure.test was going to win, because of an aversion to dependencies that we developers naturally develop over time.

Well, 3 months ago a dark horse suddenly appeared out of the blue: fudje - a library that compiles midje forms to clojure.test forms in order to be able to run all midje-style tests using lein test. My first instinct was:

why didn't I think about doing that?

Well... I actually did for clojurescript, but because midje was already there for clojure, it never occured for me to do anything different. But looking at the fudje source code, I'm really glad Dimitrios did, because the library is an awesome piece of work, requiring a deep understanding of both frameworks in order to inplement

Now, the important question in order to sell it to all the CTOs:

What about it's dependencies?

(coordinate-dependencies '[[fudje "0.9.3"]])
> [[org.clojure/math.combinatorics "0.1.1"]]

Just one dependency. ONE. I'm switching. ALL my projects.

There's still teething issues because even though I use roughly 3% of midje's actual features, the switch to fudje is still a little bit trickier than doing a global replace from midje to fudje. However on new projects, the library is flawless. And now when someone asks about cloverage, there is no need for that moment's hesitation anymore.

Yes we can.

comments powered by Disqus