二 月
20
火曜日

cljs.test/async使用上の注意

ClojureScriptの非同期処理テストケースで使用するcljs.test/asyncは一つのdeftest内で一度しか使えないという制約がある。


まずは普通のOKケース。

(deftest async-test
  (testing "test1"
    (async done
      (go
        (is (= 1 1))
        (done)))))

制約を破って同一deftest内にテストケース(NG)を追加してみる。

(deftest async-test
  (testing "test1"
    (async done
      (go
        (is (= 1 1))
        (done))))
  (testing "test2"
    (async done
      (go
        (is (= 1 2))
        (done)))))

結果はNG。一見正しく動いている様に見える。

さらにテストケース(OK)を追加する。

(deftest async-test
  (testing "test1"
    (async done
      (go
        (is (= 1 1))
        (done))))
  (testing "test2"
    (async done
      (go
        (is (= 1 2))
        (done))))
  (testing "test3"
    (async done
      (go
        (is (= 1 1))
        (done)))))

結果はOKになってしまう!

ClojureScript公式ドキュメント Async Testingに以下の注意書きがある。

NOTE: You cannot have more than one async test per deftest form or only the first one will run.

asyncを利用したテストはdeftest内に2つ以上書いてはならないとのこと。
複数定義した場合、テスト自体は全て実行され最後に定義したテストの結果が有効となるようだ。


最後のテストのみが有効になるあたりが実に厄介でうっかり既存の非同期テストの末尾に新たなテストを追加すると前のテストは人知れずひっそりと無効になってしまう。
自分はまんまとこれにハマってしまったのでこのメモを残し1deftest 1asyncを心に刻みたいと思う。