http://rubikitch.com/に移転しました このページをアンテナに追加 RSSフィード

2008-04-09

[][]Emacs Lisp Expectationsで超簡単ユニットテスト in elisp

elispにもRubyのexpectationsのような美しく記述できるテスティングフレームワークが欲しい - http://rubikitch.com/に移転しました

expectationsに激萌えの俺がさくっと作ったよ、expectations for elispexpectations.elじゃ検索しづらいと思ってel-expectations.elにしといた。

こんな文法でテストが書ける。本体の評価結果が期待値とマッチすればテストが通る。本家expectationsにない機能として「desc」でコメントが書けること。ただし、たんなるデリミタなのでテスト名ではないw

(expectations
  (desc コメント)
  (expect 期待値
    本体)
  (expect ...)
  ...
  )

具体的なコードはこんなの。

(expectations
   (desc "simple expectation")
   (expect 3           ; (+ 1 2) が 3 になるべき。
     (+ 1 2))
   (expect "hoge"      ; (concat "ho" "ge") が "hoge" になるべき。
     (concat "ho" "ge"))
   (expect "fuga"      ; 〜の評価結果が "fuga" になるべき。
     (set-buffer (get-buffer-create "tmp"))
     (erase-buffer)
     (insert "fuga")
     (buffer-string))

   (desc "extended expectation")
   (expect (buffer "*scratch*")  ; #<buffer *scratch*> になるべき。
     (with-current-buffer "*scratch*"
       (current-buffer)))
   (expect (regexp "o")          ; "hoge" =~ /o/ であるべき。
     "hoge")
   (expect (type integer)        ; 3 は整数であるべき。
     3)

   (desc "error expectation")
   (expect (error arith-error)   ; 0除算はarith-errorが起きるべき。
     (/ 1 0))
   (expect (error)               ; 0除算は何でもいいからエラーであるべき。
     (/ 1 0)))

どう、簡単でしょ?

elispテスト書くのめんどくせえと思ってる人も試してみる価値はある、断言しよう。

インストール

M-x install-elisp-from-emacswiki el-expectations.el

EmacsWikiからもってけ!ブラウザで見るには↓へどうぞ。

http://www.emacswiki.org/cgi-bin/wiki/download/el-expectations.el

使い方

ただ、現時点ではひとつのファイルにふたつ以上のexpectationsS式は書けない制限がある。ふたつ以上書いてしまうとC-x `でコケてしまう。この制限はなくすべきだな…

成功時の実行結果

↑の例を実行した結果は *expectations result* バッファにこんな風に出る。

Executing expectations in nil...
1  :============ simple expectation ============
2  :OK
3  :OK
4  :OK
5  :=========== extended expectation ===========
6  :OK
7  :OK
8  :OK
9  :============ error expectation ============
10 :OK
11 :OK

失敗時の実行結果

成功時じゃつまらんので失敗時の結果も貼っとく。

(expectations
  (desc "error test")
  (expect 4
    (error "hoge")
    4)

  (desc "eval")
  (expect 5 4)
  (expect "hoge" "hage")
  (expect '(1) '(2))
  (expect (get-buffer-create "buf1") (get-buffer-create "buf2"))

  (desc "buffer")
  (expect (buffer "*scratch*")
    (get-buffer-create "*fail*"))

  (desc "regexp")
  (expect (regexp "o")
    "hage")

  (desc "type")
  (expect (type string)
    1)
  (desc "error")
  (expect (error arith-error)
    (/ 1 1))
  (expect (error end-of-file)
    (/ 1 0))
  (expect (error)
    (/ 1 1))
  )

これを実行してみるとこうなる。

Executing expectations in /m/home/rubikitch/emacs/lisp/el-expectations-failure-sample.el...
1  :================ error test ================
2  :ERROR: (error hoge)
3  :=================== eval ===================
4  :FAIL: Expected <5> but was <4>
5  :FAIL: Expected <"hoge"> but was <"hage">
6  :FAIL: Expected <(1)> but was <(2)>
7  :FAIL: Expected <#<buffer buf1>> but was <#<buffer buf2>>
8  :================== buffer ==================
9  :FAIL: Expected <#<buffer *scratch*>> but was <#<buffer *fail*>>
10 :================== regexp ==================
11 :FAIL: "hage" should match /o/
12 :=================== type ===================
13 :FAIL: 1 is not a string
14 :================== error ==================
15 :FAIL: should raise <arith-error>, but no error was raised
16 :FAIL: should raise <end-of-file>, but raised <arith-error>
17 :FAIL: should raise any error, but no error was raised

追記:バッチモード

言語のテスティングフレームワークのようにコマンドラインからも実行できるようにしといた。

以下のシェルスクリプトをel-expectationsという名前で保存する。

バッチモードで実行することで、ライブラリrequire忘れとかのミスを未然に防ぐことができる。Emacsの中だとrequireされている状態なのでついついrequireを入れるのを忘れてしまうので。それと、.emacsに影響されないので設定依存になっていないことも確かめられる。

#!/bin/sh
EMACS=emacs
OPTIONS="-L . -L $HOME/emacs/lisp"
OUTPUT=/tmp/.el-expectations

$EMACS -q --no-site-file --batch $OPTIONS -l el-expectations -f batch-expectations $1 $OUTPUT
ret=$?
cat $OUTPUT
rm $OUTPUT
exit $ret

でもって、おもむろに

$ el-expectations el-expectations-success-sample.el
Loading subst-ksc...
Loading subst-gb2312...
Loading subst-big5...
Loading subst-jis...
Executing expectations in /m/home/rubikitch/emacs/lisp/el-expectations-success-sample.el...
1  :========== run-hook-with-args-until-success ==========
2  :OK
3  :OK
4  :OK
5  :======================= buffer =======================
6  :OK
7  :OK
8  :======================= regexp =======================
9  :OK
10 :======================== type ========================
11 :OK
12 :OK
13 :======================= error =======================
14 :OK
15 :OK
16 :======================== eval ========================
17 :OK
18 :OK

12 expectations, 0 failures, 0 errors
$ el-expectations el-expectations-failure-sample.el
Loading subst-ksc...
Loading subst-gb2312...
Loading subst-big5...
Loading subst-jis...
Executing expectations in /m/home/rubikitch/emacs/lisp/el-expectations-failure-sample.el...
1  :===================== error test =====================
2  :ERROR: (error hoge)
3  :======================== eval ========================
4  :FAIL: Expected <5> but was <4>
5  :FAIL: Expected <"hoge"> but was <"hage">
6  :FAIL: Expected <(1)> but was <(2)>
7  :FAIL: Expected <#<buffer buf1>> but was <#<buffer buf2>>
8  :======================= buffer =======================
9  :FAIL: Expected <#<buffer *scratch*>> but was <#<buffer *fail*>>
10 :======================= regexp =======================
11 :FAIL: "hage" should match /o/
12 :======================== type ========================
13 :FAIL: 1 is not a string
14 :======================= error =======================
15 :FAIL: should raise <arith-error>, but no error was raised
16 :FAIL: should raise <end-of-file>, but raised <arith-error>
17 :FAIL: should raise any error, but no error was raised

11 expectations, 10 failures, 1 errors
zsh: exit 11    el-expectations el-expectations-failure-sample.el

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証