Emacs Lisp Expectations is the simplest unit testing framework by rubikitch. It is very easy to use/read.
Mocking is done utilizing EmacsLispMock. You should download it, too:
Emacs Lisp Expectations is modeled after Ruby's expectations by Jay Fields. It inherits testing policy, designed to encourage unit testing best practices such as:
‘M-x expectations-execute’to execute a test.
C-x `) and
‘M-x previous-error’to go to the expectations S-exp.
‘expectations’ defines a expectations test case. Use
‘desc’ to verify the code. Note that these are neither functions nor macros. These are keywords in expectations Domain Specific Language (DSL).
(expect EXPECTED-VALUE BODY ...)
Assert that the evaluation result of
Description of a test. It is treated only as a delimiter comment.
Body should eq buffer object of
Body should match
Body should be a
TYPE-SYMBOL must be one of symbols returned by
`symbol', `integer', `float', `string', `cons', `vector', `char-table', `bool-vector', `subr', `compiled-function', `marker', `overlay', `window', `buffer', `frame', `process', `window-configuration'
Body should raise any error.
Body should raise
(error ERROR-SYMBOL ERROR-DATA)
Body should raise
ERROR-SYMBOL error with
ERROR-DATA is 2nd argument of
‘signal’ function. Example:
(expect (error wrong-number-of-arguments '(= 3)) (= 1 2 3 ))
Body should raise any error with
(expect (error-message \"ERROR!!\") (error \"ERROR!!\"))
(mock MOCK-FUNCTION-SPEC => MOCK-RETURN-VALUE)
Body should call
MOCK-FUNCTION-SPEC and returns
MOCK-RETURN-VALUE. Mock assertion depends on
‘el-mock’ library. If available, you do not have to require it:
el-expectations detects it.
(FUNCTION ARGUMENT ...) MOCK-FUNCTION-SPEC is almost same as normal function call. If you should specify `*' as ARGUMENT, any value is accepted. Otherwise, body should call FUNCTION with specified ARGUMENTs.
(expect (mock (foo * 3) => nil) (foo 9 3))
Body should equal (eval SEXP).
If you prefer batch mode, use this script (
#!/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 $OUTPUT "$@" ret=$? cat $OUTPUT rm $OUTPUT exit $ret
$ el-expectations el-expectations-failure-sample.el
(expectations (desc "simple expectation") (expect 3 (+ 1 2)) (expect "hoge" (concat "ho" "ge")) (expect "fuga" (set-buffer (get-buffer-create "tmp")) (erase-buffer) (insert "fuga") (buffer-string))
(desc "extended expectation") (expect (buffer "*scratch*") (with-current-buffer "*scratch*" (current-buffer))) (expect (regexp "o") "hoge") (expect (type integer) 3)
(desc "error expectation") (expect (error arith-error) (/ 1 0)) (expect (error) (/ 1 0)))
(expectations ;; State based expectation where a value equals another value (expect 2 (+ 1 1))
;; State based expectation where an error is expected ;; Simply expect error symbol of the intended exception (expect (error void-function '(no-function)) (no-function))
;; Behavior based test using a traditional mock ;; TODO implement times. (expect (mock (dial * "2125551212") => nil) (dial 'phone "2125551212") (dial 'phone "2125551212"))
;; Behavior based test on a concrete mock (expect (mock (deal *)) (deal 'object))
;; State based test utilizing a stub (expect 2 (stub two => 2) (two))
;; State based test utilizing a concrete mock (expect 2 (mock (bar *) => 2) (bar 'object))
;; Behavior based test utilizing a stub and a concrete mock (expect 1 (mock (give-me-three 3) => 1) (stub three => 3) (give-me-three (three)))
;; State based test matching a Regexp (expect (regexp "string") "a string")
;; State based test to determine if the object is an instance of sequence (expect (type sequence) ())
;; State based test to determine if the object is an instance of the class (expect (type string) "a string"))