test-simple 20170117.411(in MELPA)
Simple Unit Test Framework for Emacs Lisp

概要

test-simple.el はものすごいシンプルなテスティングフレームワークです。
僕もかつてel-expectations.elやERT対応版ert-expectations.elを作っていましたが、それをも上回るシンプルさです。
なんとトップレベルでassert関数群が定義されています。
そのため、C-M-xやC-x C-eで即座に1つのテストを評価できる手軽さです。

インストール

パッケージシステムを初めて使う人は
以下の設定を ~/.emacs.d/init.el の
先頭に加えてください。

(package-initialize)
(setq package-archives
      '(("gnu" . "http://elpa.gnu.org/packages/")
        ("melpa" . "http://melpa.org/packages/")
        ("org" . "http://orgmode.org/elpa/")))

初めてtest-simpleを使う方は
以下のコマンドを実行します。

M-x package-install test-simple

アップグレードする方は、
以下のコマンドでアップグレードしてください。
そのためにはpackage-utilsパッケージが必要です。

M-x package-install package-utils (初めてアップグレードする場合のみ)
M-x package-utils-upgrade-by-name test-simple

使用例:最大公約数GCD

まず、gcd.elを用意します。

(defun gcd(a b)
  "Greatest Common Divisor of A and B"
  ;; Make a < b
  (if (> a b)
      (let ((c a))
        (setq a b)
        (setq b c)))
  (cond
   ((< a 0) nil)
   ((or (= 0 (- b a)) (= a 1)) a)
   (t (gcd (- b a) a))))

そして、それに対応するテストtest-gcd.elを書きます。

(require 'test-simple)
(test-simple-start) ;; テスト開始!カウンターとタイマーをリセット

;; .elを確実に読み込ませるためにrequireの代わりにload-fileを使う
(assert-t (load-file "./gcd.el")
          "gcd.elがないよ!" )

(note "負数とエラーの例")

(assert-nil (gcd 5 -1) "正数")
(assert-nil (gcd -4 1) "正数、逆順")
(assert-raises error (gcd "a" 32)
               "文字列を指定したらエラー")

(note "計算")
(assert-equal 1 (gcd 3 5) "gcd(3,5)")
(assert-equal 8 (gcd 8 32) "gcd(8,32)")

(end-tests) ;; 計時終了、結果をレポート

M-x eval-bufferでテストを実行すると、 test-simple バッファに結果が表示されます。

test-gcd.el
......
0 failures in 6 assertions (0.0205035 seconds)

コマンドラインからテストを実行できます。

$ emacs -batch -f package-initialize -l test-gcd.el
Loading /r/sync/memo/wp/rubikitch/gcd.el (source)...
*scratch*
......
0 failures in 6 assertions (0.000390617 seconds)

package-initializeが重いならば、 test-simple.el のあるディレクトリを指定してもいいです。

$ emacs -batch -L ~/.emacs.d/quelpa/build/test-simple/ -l test-gcd.el

失敗するテスト

テストをわざと失敗させましょう。

(require 'test-simple)
(test-simple-start)

(assert-nil t "assert-nil")
(assert-t nil "assert-t")
(assert-equal 1 (+ 1 1) "(+ 1 1) == 2")

(end-tests)

すると、assert-*の最後の引数で指定されたメッセージとともに失敗が報告されます。

test-simple-fail.el
F
Description: none set, type assert-nil

	Message: assert-nil
F
Description: none set, type assert-nil

	Message: assert-t
F
Description: none set, type assert-equal
Message: (+ 1 1) == 2
  Expected: 1
  Got: 2

3 failures in 3 assertions (0.0190111 seconds)

assert関数群

用意されているassert関数群です。
C-M-xやC-x C-eで個別に評価したとき、assertを満たすならばtを、満たさないならばnilを返します。

(defmacro assert-raises (error-condition body &optional fail-message)
(defun assert-equal (expected actual &optional fail-message)
(defun assert-eq (expected actual &optional fail-message)
(defun assert-eql (expected actual &optional fail-message)
(defun assert-matches (expected-regexp actual &optional fail-message)
(defun assert-t (actual &optional fail-message)
(defun assert-nil (actual &optional fail-message)

もはや説明不要でしょう。


本日もお読みいただき、ありがとうございました。参考になれば嬉しいです。