Lepší testování v Clojure: Midje

Dneska navážu na unit testování v Clojure, nicméně dostanu se k tomu oklikou. Minulé léto se celkem hojně psalo o desátém výročí deklarace Manifesto for Agile Software Development. Internetem (a mojí čtečkou) tehdy protekly nějaké rozhovory s někdejšími účastníky/signatáři. Jedním z nich byl i Brian Marick, autor Midje, testovacího frameworku pro Clojure (ano, to je to Midje, které jsem zmiňoval ve svém postu o ThoughtWorks Radar).
Instalace/zprovoznění
Midje je nejjednodušší začít používat pomocí Leiningenu (určitě jeden z příštích zápisků). Definice projektu může vypadat třeba takto:
(defproject blog-midje "1.0.0-SNAPSHOT"
:description "Midje for Sometimes Clojure"
:dependencies [[org.clojure/clojure "1.3.0"]]
:dev-dependencies [[midje "1.3.2-SNAPSHOT"]])
REPL se pak spustí příkazem lein repl
.
Fakta
Základem testování v Midje jsou fakta. Fakta o budoucím kódu (test first):
(ns blog-midje (:use midje.sweet))
; nil
(fact (+ 1 1) => 2)
; true
(fact 1 => odd?)
; true
(fact "truth about one" 1 => even?)
; FAIL at (NO_SOURCE_FILE:11)
; Actual result did not agree with the checking function.
; Actual result: 1
; Checking function: even?
; false
Fakt může mít více klauzulí. Dá se použít makro fact
nebo facts
:
(facts "about42"
(+ 21 21) => 42
(* 6 7) => 42)
; true
Pokud je potřeba fakt prezentovat pomocí sady hodnot, nabízí Midje tzv. tabulková fakta:
(defn xor [x y]
(if (= x y) false true))
; #'blog-midje/xor
(tabular
(fact "The rules of XOR"
(xor ?x ?y) => ?expected)
?x ?y ?expected
0 0 false
0 1 true
1 0 true
1 1 false
false false false
false true true
true false true
true true false)
; true
Vyhození výjimky se dá otestovat pomocí funkce (checkeru) throws
:
(fact (/ 42 0) => (throws ArithmeticException))
; true
Spuštění testů
Midje předpokládá pro spuštění (všech) testů nějaký nástroj, jako např. Leiningen nebo Cake. Pojďme se podívat, jak by vypadalo rozchození projektu a testů pomocí Leiningenu. Nový projekt vytvoříme příkazem: lein new blog-midje
Struktura projektu by měla vypadat takto:

Layout projektu
Do definice projektu (project.clj
) je potřeba přidat závislosti. Kromě těch obligátních je to hlavně knihovna lein-midje
:
(defproject blog-midje "1.0.0-SNAPSHOT"
:description "Midje for Sometimes Clojure"
:dependencies [[org.clojure/clojure "1.3.0"]]
:dev-dependencies [[midje "1.3.2-SNAPSHOT"]
[lein-midje "1.0.8"]])
Prvně napíšeme test (soubor test/blog_midje/test/core.clj
):
(ns blog-midje.test.core
(:use [blog-midje.core])
(:use [midje.sweet]))
(tabular
(fact "The rules of XOR"
(xor ?x ?y) => ?expected)
?x ?y ?expected
0 0 false
0 1 true
1 0 true
1 1 false
false false false
false true true
true false true
true true false)
Potom napíšeme testovanou funkci (src/blog_midje/core.clj
):
(ns blog-midje.core)
(defn xor
"Returns true if x and y are mutually exclusive."
[x y]
(if (= x y) false true))
Testy potom spustíme příkazem lein test
, nebo lépe lein midje
:

Spuštění testů
Celý projekt je ke stažení zde: blog-midje.zip.
[Update] Celý projekt je dispozici na Bitbucketu:
[/Update]
To je pro dnešek vše. Pokud se chcete podívat na úvod do Midje od samotného Briany Maricka, zkuste videa uvedená na wiki stránce Midje.