Andrea
Andrea

Reputation: 20493

Testing in Lisp

I am new to Lisp, and I am learning Scheme through the SICP videos. One thing that seems not to be covered (at least at the point where I am) is how to do testing in Lisp.

In usual object oriented programs there is a kind of horizontal separation of concerns: methods are tied to the object they act upon, and to decompose a problem you need to fragment it in the construction of several objects that can be used side by side.

In Lisp (at least in Scheme), a different kind of abstraction seems prevalent: in order to attack a problem you design a hierarchy of domain specific languages, each of which is buil upon the previous one and acts at a coarser level of detail and higher level of abstraction.

(Of course this is a very rough description, and objects can be used vertically, or even as building blocks of DSLs.)

I was wondering whether this has some effect on testing best practices. So the quetsion is two-fold:

  1. What are the best practices while testing in Lisp? Are unit tests as fundamental as in other languages?
  2. What are the main test frameworks (if any) for Lisp? Are there mocking frameworks as well? Of course this will depend on the dialect, but I'd be interested in answers for Scheme, CL, Clojure or other Lisps.

Upvotes: 3

Views: 1693

Answers (3)

Svante
Svante

Reputation: 51501

Two testing frameworks that I am aware of for Common Lisp are Stefil (in two flavours, hu.dwim.stefil and the older stefil), FiveAM, and lisp-unit. Searching in the quicklisp library list also turned up "unit-test", "xlunit", and monkeylib-test-framework.

I think that Stefil and FiveAM are most commonly used.

You can get all from quicklisp.

Update: Just seen on Vladimir Sedach's blog: Eos, which is claimed to be a drop-in replacement for FiveAM without external dependencies.

Upvotes: 2

Rörd
Rörd

Reputation: 6681

RackUnit is the unit-testing framework that's part of Racket, a language and implementation that grew out of Scheme. Its documentation contains a chapter about its philosophy: http://docs.racket-lang.org/rackunit/index.html.

Upvotes: 2

mikera
mikera

Reputation: 106351

Here's a Clojure specific answer, but I expect most of it would be equally applicable to other Lisps as well.

Clojure has its own testing framework called clojure.test. This lets you simply define assertions with the "is" macro:

(deftest addition
  (is (= 4 (+ 2 2)))
  (is (= 7 (+ 3 4))))

In general I find that unit testing in Clojure/Lisp follows very similar best practices to testing for other languages. It's the sample principle: you want to write focused tests that confirm your assumptions about a specific piece of code behaviour.

The main differences / features I've noticed in Clojure testing are:

  • Since Clojure encourages functional programming, it tends to be the case that tests are simpler to write because you don't have to worry as much about mutable state - you only need to confirm that the output is correct for a given input, and not worry about lots of setup code etc.
  • Macros can be handy for testing - e.g. if you want to generate a large number of tests that follow a similar pattern programatically
  • It's often handy to test at the REPL to get a quick check of expected behaviour. You can then copy the test code into a proper unit test if you like.
  • Since Clojure is a dynamic language you may need to write some extra tests that check the type of returned objects. This would be unnecessary in a statically typed language where the compiler could provide such checks.

Upvotes: 3

Related Questions