Note: The author PhilHagelberg has marked this extension deprecated and suggests using ERT UnitTesting instead.
ElUnit is a unit testing framework for Emacs Lisp code.
It has undergone several revisions, and I’m preparing a rewrite for it. I’d like to gather ideas about what the most convenient syntax and features to include would be.
Here’s a first shot at some example syntax. I like the idea of working backwards from examples while implementing it.
;; Meta suite (defsuite elunit-suite nil ; nil means it's not part of a larger suite. Suites can be nested. ;; put something here if needed... ;; :setup-hook (lambda () ) :teardown-hook (lambda () (message "done testing"))) (deftest passing-tests elunit-suite ;; Optional docstring "Passing tests should leave fail counter, open ElUnit buffer, and display results" (save-buffer-excursion ; execute body and return to the current buffer configuration (load "passing-sample-tests") (elunit "passing-tests") (assert (equal 0 elunit-fail-count)) (assert (string= (buffer-name (current-buffer)) "*elunit*")) (assert (search-forward-regexp "0 failures")))) (deftest failing-tests elunit-suite (save-buffer-excursion (load "failing-sample-tests") (elunit "failing-tests") (assert (equal 4 elunit-fail-count)) (assert (string= (buffer-name (current-buffer)) "*elunit*")) (search-forward-regexp "(cl-assertion-failed (equal 5 (+ 2 2)))") (search-forward-regexp "4 failures")))
To see tests for ElUnit itself, see https://github.com/technomancy/dotfiles/blob/68873ca76922f73bdc51f954236459c0ba653dd0/.emacs.d/old/test/elunit-test.el
Nesting suites vs. explicit suites: earlier incarnations of ElUnit wrapped tests in a defsuite form so that the suite name did not have to be repeated for each test definition. This may be preferrable as it visually groups the tests, but some have argued against it.
Storing tests vs. immediately executing them: most unit testing frameworks run the tests when the code is evaled. I think an Elisp framework would be better of storing the tests as closures and executing them with another command.
Output: currently just uses with-output-to-temp-buffer. Should have an option to do other stuff with the output; not sure what would be useful. Storing it in variables, maybe?
Buffer-locality: should tests and suites be global, or should there just be a list of suites stored in a buffer-local variable?
save-buffer-excursion
: perhaps this should be implicit in deftest? (Would be like save-excursion, but for buffer configuration.)
Please add. I’d like to get as much input here as I can so this can be useful to many people.
Thanks. – PhilHagelberg
In my own Elisp unit tests, I use assert
in the code, thus making sure they disappear from the compiled code. Having them in the source code makes sure that I, as a developer, will run them always, whenever I load the file. – AlexSchroeder
save-buffer-excursion
. I think it just boils down to different development styles. – PhilHagelbergHere is a nice thing to put in your unit-testing scripts. I think it’s self-explanatory.
(set (make-local-variable 'elunit-default-suite) "the-suite-defined-in-this-script")