Emacs Lisp Expectations is the simplest unit testing framework by rubikitch. It is very easy to use/read.
The new generation of EmacsLispExpectations is available, Lisp:ert-expectations.el , using ErtTestLibrary. Lisp:el-expectations.el is obsolete.
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.‘M-x next-error’
(C-x `
) and ‘M-x previous-error’
to go to the expectations S-exp.‘expectations’
defines a expectations test case. Use ‘expect’
and ‘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 BODY
is ‘equal’
to EXPECTED-VALUE
.
(desc DESCRIPTION)
Description of a test. It is treated only as a delimiter comment.
(buffer BUFFER-NAME)
Body should eq buffer object of BUFFER-NAME
.
(regexp REGEXP)
Body should match REGEXP
.
(type TYPE-SYMBOL)
Body should be a TYPE-SYMBOL
. TYPE-SYMBOL
must be one of symbols returned by ‘type-of’
function:
`symbol', `integer', `float', `string', `cons', `vector', `char-table', `bool-vector', `subr', `compiled-function', `marker', `overlay', `window', `buffer', `frame', `process', `window-configuration'
(error)
Body should raise any error.
(error ERROR-SYMBOL)
Body should raise ERROR-SYMBOL
error.
(error ERROR-SYMBOL ERROR-DATA)
Body should raise ERROR-SYMBOL
error with ERROR-DATA
. ERROR-DATA
is 2nd argument of ‘signal’
function. Example:
(expect (error wrong-number-of-arguments '(= 3)) (= 1 2 3 ))
(error-message ERROR-MESSAGE)
Body should raise any error with ERROR-MESSAGE
. Example:
(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.
Synopsis of MOCK-FUNCTION-SPEC
:
(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.
Example:
(expect (mock (foo * 3) => nil) (foo 9 3))
SEXP
Body should equal (eval SEXP).
If you prefer batch mode, use this script (el-expectations
):
#!/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"))