読者です 読者をやめる 読者になる 読者になる

test-more.el進捗 2012/JAN/15

emacs test

test-more.elの進捗と各機能の説明。

テスト関数

test-more:plan($num)

$num個テストすることを宣言する。最終的に $num個のテストを実施していない
場合、警告がなされる。テストファイルの先頭で呼び出す。

test-more:finalize()

テストの終了処理を行う。テストファイルの末尾で呼び出す。

test-more:ok($got [$desc])

第一引数が真であるかどうかをテストする。

test-more:is($got $expected [$desc])

第一引数が第二引数に等しいかテストする(比較関数は equalを使う。以下の関数も同じ)。

test-more:isnt($got $expected [$desc])

第一引数が第二引数と等しくないかテストする。

test-more:diag($diag)

メッセージ $diagを出力する。

test-more:is-type($got $type [$desc])

第一引数の型が第二引数の型であるかをテストする。

test-more:like($got $regexp [$desc])

第一引数が第二引数の正規表現にマッチするかテストする。

test-more:skip($why $how-many)

$how-many個のテストを skipする。

test-more:pass($desc)

常に Pass。

test-more:fail($desc)

常に Fail。

test-more:import()

上記の関数を test-more:prefixなしで呼び出すことができる。

テストマクロ

test-more:is-print($form $expected [$desc])

第一引数の標準出力への出力が第二引数に等しいかテストする。

test-more:is-error($form [$desc])

第一引数が例外を投げるかをテストする。

test-more:todo($desc $forms)

Perlの Test::Moreの TODOブロックに相当。
実装予定機能の目印的な扱い。

test-more:subtest(desc $forms)

Perlの Test::Moreの subtestに相当。
$formsを一つのテストとして扱う。


test-more:subtestのサンプル

(require 'test-more)
(test-more:import)

(defun add (a b)
  (if (or (null a) (null b))
      (error "argument is nil"))
  (+ a b))

(plan 1)

(test-more:subtest "test `add' function"
                   (is (add 1 2) 3 "normal case1")
                   (is (add 0 0) 0 "normal case2")
                   (test-more:is-error (add 1 nil) "invalid argument"))

(finalize)


結果

1..1
    ok 1 - normal case1
    ok 2 - normal case2
    ok 3 - invalid argument
    1..3
ok 1 - test `add' function
ok
test-more:done-testing($forms)

Perlの Test::Moreの done_testingに相当。
このマクロ内にテストをかけば、plansと finalizeの呼び出しが不要。
(いきなり done-testingで囲うのは見た目的に変ですが・・・)


test-more:done-testingのサンプル

(require 'test-more)
(test-more:import)

(test-more:done-testing
 (ok t)
 (is 1 1)
 (isnt 1 0)
 (like "123" "[0-9]"))


結果

ok 1
ok 2
ok 3
ok 4
1..4
ok

proveで実行

"--script"オプションより, "--batch"オプションの方が "-l"とか他のオプションが
指定できてよいと思います。test-more.elをどこかに置いてそれを明示的に指定する
だけで利用可能になります。

    prove -v \
         --exec='emacs -Q --batch -l ~/.emacs.d/elisp/test-more.el -l' \
         example/subtest.el

サンプルコード

(require 'test-more)
(test-more:import) ;; use test functions(not macros) without 'test-more:' prefix

(plan 14)

(ok (typep "This is String" 'string) "first argument is true")

(is '(a b) '(a b) "first argument equals to second argument")
(isnt (length '(a b)) 1 "first argument does not equal to second argument")

(diag "Prints a diagnostic message")

(is-type 10 'integer "type of first argument is second argument")

(like "987" "^[0-9]+$" "first argument matchs second argument which is regexp")

(if (not (string= system-type 'gnu/linux))
    (test-more:skip "skips tests if system is not Linux" 2)
  (progn
    (test-more:ok (executable-find "emacs") "has emacs")
    (test-more:isnt (symbol-name system-type) "macosx" "not mac")))

(test-more:todo "Like Test::More TODO block"
                (test-more:ok nil "todo1")
                (test-more:is 1 2 "todo2"))

(test-more:subtest "subtest"
                   (ok 1 "subtest 1")
                   (ok nil "subtest 2"))

(test-more:is-print (princ "hello") "hello"
                    "first argument outputs string of second argument to stdout")

(test-more:is-error (error "error") "first argument throws exception")

(pass "always pass")
(fail "always fail")

(finalize)
上記のサンプルコードの proveでの結果
% prove -v --exec='emacs -Q --batch -l test-more.el -l' example/sample.el
example/sample.el ..
1..14
ok 1 - first argument is true
ok 2 - first argument equals to second argument
ok 3 - first argument does not equal to second argument
# Prints a diagnostic message
ok 4 - type of first argument is second argument
ok 5 - first argument matchs second argument which is regexp
ok 6 - has emacs
ok 7 - not mac
not ok 8 - todo1 # TODO Like Test::More TODO block
#  Failed (TODO) test 'Like Test::More TODO block'
not ok 9 - todo2 # TODO Like Test::More TODO block
#  Failed (TODO) test 'Like Test::More TODO block'
#    got: 1   expected: 2
    ok 1 - subtest 1
    not ok 2 - subtest 2
    1..2
    #  Looks like you failed 1 tests of 2 run
not ok 10 - subtest
ok 11 - first argument outputs string of second argument to stdout
ok 12 - first argument throws exception
ok 13 - always pass
not ok 14 - always fail
#  Looks like you failed 4 tests of 14 run
Failed 2/14 subtests

Test Summary Report
-------------------
example/sample.el (Wstat: 0 Tests: 14 Failed: 2)
  Failed tests:  10, 14
Files=1, Tests=14,  0 wallclock secs ( 0.02 usr  0.00 sys +  0.03 cusr  0.01 csys =  0.06 CPU)
Result: FAIL

終わりに

あとはもう少し見なおして, その後 Marmalade, EmacsWikiへの登録をしようと思います.
何か問題, 新機能の提案等ございましたら, githubの方までお願いします.