使用Practical Common Lisp的测试台代码

时间:2017-03-25 04:47:04

标签: format common-lisp

实践Common Lisp Ch。 9,Peter Seibel提供了一个基本的单元测试平台,用于比较评估S表达式的预期结果和实际结果。例如,将测试定义为(deftest plus-test () (check (= (+ 1 2) 3)))并评估(加测试)将打印结果pass ... (PLUS-TEST): (= (+ 1 2) 3)。但是,像(deftest cdr-test () (check (equal (cdr '(a |a| "a" #\a)) '(|a| "a" #\a)这样稍微复杂的示例会产生结果pass ... (CDR-TEST): (equal (cdr '(A a a a)) '(a a a))而不是pass ... (CDR-TEST): (equal (cdr '(a |a| "a" #\a)) '(|a| "a" #\a))。我无法成功修改他的代码以打印所需的结果,并希望得到一些帮助。这是他的代码来自Ch。 9:

(defmacro with-gensyms ((&rest names) &body body)
  `(let ,(loop for n in names collect `(,n (make-symbol ,(string n))))
     ,@body))

(defvar *test-name* nil)

(defmacro deftest (name parameters &body body)
  "Define a test function. Within a test function we can call other
   test functions or use `check' to run individual test cases."
  `(defun ,name ,parameters
    (let ((*test-name* (append *test-name* (list ',name))))
      ,@body)))

(defmacro check (&body forms)
  "Run each expression in `forms' as a test case."
  `(combine-results
    ,@(loop for f in forms collect `(report-result ,f ',f))))

(defmacro combine-results (&body forms)
  "Combine the results (as booleans) of evaluating `forms' in order."
  (with-gensyms (result)
    `(let ((,result t))
      ,@(loop for f in forms collect `(unless ,f (setf ,result nil)))
      ,result)))

(defun report-result (result form)
  "Report the results of a single test case. Called by `check'."
  (format t "~:[FAIL~;pass~] ... ~a: ~a~%" result *test-name* form)
  result)

1 个答案:

答案 0 :(得分:3)

这只是关于format控件的问题,因为函数format在您正在使用的代码中执行输出。

相应的Common Lisp Hyperspec文档位于FORMAT Printer Operations

* (format t "~a" ''(a #\a))
'(A a)
NIL

* (format t "~s" ''(a #\a))
'(A #\a)
NIL