clojure.test
Clojureの標準ライブラリ.
- deftest: テスト定義.
- is: アサーション.
- are: isをテンプレに従って複数書くマクロ.
- testing: 引数を取り連続したアサーションを入れる. グルーピングやドキュメント用.
- BDDのように期待するべき仕様をかける.
- use-fixtures: setup/teardownの制御.
テストフィクスチャ(Setup/Teardown/use-fixtures)
テストの前処理(Setup), 後処理(Teardown)はFIXTURESとしてClojuredocに方法が記載されている. 基本的にはfixture関数を自前で関数を書いて呼び出す.
https://clojuredocs.org/clojure.test
そして, 自作のfixtureを順番に呼び出す関数がuse-fixturesとして提供されている. :once/:eachのオプション引数によって, 呼び出しの挙動が変わる.
https://clojuredocs.org/clojure.test/use-fixtures
(defn my-test-fixture [f]
(create-db)
(f)
(destroy-db))
;; namespaceのtest実行で一度呼ばれる.
(use-fixtures :once my-test-fixture)
;; namespaceのtest実行で毎回呼ばれる.
(use-fixtures :each my-test-fixture)
ポイントはnamespace単位であるところ(!= testing単位). いちおう改善の提案はされているようで, 将来はdeftest単位でfixtureが設定できるようになるかもしれないが, 現時点では外部ライブラリを利用する.
References
Clojureテストランナー
一連のテストケースを実行する仕組み.
- Emacs CIDER: Emacsをつかっているならばファーストチョイス.
- kaocha: モダンなテストランナー.
Clojure テストライブラリ
モックやスタブをサポートしているもの.
- midge:
- yet another clojure.test. 古くからある.
- fudje: https://github.com/jimpil/fudje
- shrubbery: https://github.com/bguthrie/shrubbery
- プロトコルのためのspying & mocking ライブラリ.
🔧nubank/mockfn
📝Nubankの開発したMocking用フレームワーク.
- url: https://github.com/nubank/mockfn
- doc: https://github.com/nubank/mockfn/blob/master/doc/documentation.md
- refs. 最近Clojureでテストを書くときに使っているライブラリをふたつ紹介します - Uzabase for Engineers
Build a bank: Nubank with Edward Wibleでの, I/O部分にしか副作用させないように書けるファンクショナルなClojureは超良かったよというのはこのライブラリのことか???
verifying
モックが呼ばれた回数をチェックする. 以下の例は1回だけ呼ばれたことをチェック.
(testing "verifying"
(verifying [(one-fn :argument) :result (exactly 1)]
(is (= :result (one-fn :argument)))))
spying
スタブの機能にmatterを組み合わせてテストスパイ的に振る舞う.
ポイントはassertに失敗すると例外が上がる. prividingを使えばいい. 無名関数は(pred (fn.. ))のシンタックスシュガー.
(deftest update-order-test
(providing
[(sut/handle-order (any)
(any)
(fn [m] (= (:side m) :buy))
(any)) :mocked]
(is (= :mocked
(sut/update-order! {:ex ex} {:side-id :buy})))))
mockfn/matchers
`mockfn.matchers`に含まれるもので, 仮引数や戻り値の検証につかう. mockfnに組み込みのマッチャーと外部マッチャーがある.
外部マッチャーは pred の引数に関数を渡す. スタブの引数に関数を渡すとそれは(pred f)のシンタックスシュガーになる. または, 🔧nubank/matcher-combinatorsをつかうと高度な比較ができる.
https://github.com/nubank/mockfn/blob/master/doc/documentation.md#built-in-matchers
tips: 高階関数でわたした関数のmockができない
調査中… たぶんできない.
tips: プロトコルに実装した関数のmockはthisを渡すと失敗する
ちょっとした注意点かもしれない. mockfnでProtocolのmockはできるが, プロトコルの実装の関数にthisをわたすとモックが効かないでthisの関数実装を呼び出すので, 適当なオブジェクトを渡さないといけない.
最近Clojureでテストを書くときに使っているライブラリをふたつ紹介します - Uzabase for Engineers
🔧nubank/matcher-combinators
複雑なデータ構造を比較する. 🔧nubank/mockfnのmatcherとコンボで使える.
Clojure: TDD
ClojureテストTopics
テストファイルは (hogehoge-test.clj)の慣習に従う
テストファイルはtestディレクトリ配下に置く. そして階層はsrcと同じにして, ファイル名をhogehoge-test.cljにする.
Name your ns yourproject.something-test, a file which usually lives in test/yourproject/something_test.clj (or .cljc, cljs).
deftestでテストを定義して, テスト名はhogehoge-testというsuffixにする.
ものすごくハマった記憶として, ソースファイルとテストファイルを同じ名前とnamespaceで宣言した結果, あるソースファイルからテストファイルをrequireしてエラーして2時間が経過した. 悲しみを忘れない.
The Clojure Style Guide - testing
CIDERのtesting補助機能
Emacs CIDERのテスト補助機能.
- C-c C-t l: ロードされたすべてのテスト実行.
- C-c C-t n: namespaceのテスト実行.
- C-c C-t t: 特定のテスト実行(at-point).
- projectile-toggle-between-implementation-and-test, テストと実装をtoggle
- projectile-find-implementation-or-test-other-window, テストと実装をtoggle
ref. https://docs.cider.mx/cider/testing/running_tests.html
ClojureにTDDは必要なのか?
Clojureは動的型付け言語であることを忘れてはいけない…
Clojure並列テスト(Parallelising testing)
わたしはこの意味するところをまだ理解していない. いちおうTopicのエントリポイントのみ作成.
- A Study in Parallelising Clojure Tests | by Mourjo Sen | helpshift-engineering | Medium
- Clojureで実践的なテストの書き方 - ayato-p