test-framework.lisp 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. (in-package :trivial-gray-streams-test)
  2. ;;; test framework
  3. #|
  4. Used like this:
  5. (list (test (add) (assert (= 5 (+ 2 2))))
  6. (test (mul) (assert (= 4 (* 2 2))))
  7. (test (subst) (assert (= 3 (- 4 2)))))
  8. => ;; list of test results, 2 failed 1 passed
  9. (#<TEST-RESULT ADD :FAIL The assertion (= 5 (+ 2 2)) failed.>
  10. #<TEST-RESULT MUL :OK>
  11. #<TEST-RESULT SUBST :FAIL The assertion (= 3 (- 4 2)) failed.>)
  12. |#
  13. (defclass test-result ()
  14. ((name :type symbol
  15. :initarg :name
  16. :initform (error ":name is requierd")
  17. :accessor name)
  18. (status :type (or (eql :ok) (eql :fail))
  19. :initform :ok
  20. :initarg :status
  21. :accessor status)
  22. (cause :type (or null condition)
  23. :initform nil
  24. :initarg :cause
  25. :accessor cause)))
  26. (defun failed-p (test-result)
  27. (eq (status test-result) :fail))
  28. (defmethod print-object ((r test-result) stream)
  29. (print-unreadable-object (r stream :type t)
  30. (format stream "~S ~S~@[ ~A~]" (name r) (status r) (cause r))))
  31. (defparameter *allow-debugger* nil)
  32. (defun test-impl (name body-fn)
  33. (flet ((make-result (status &optional cause)
  34. (make-instance 'test-result :name name :status status :cause cause)))
  35. (handler-bind ((serious-condition
  36. (lambda (c)
  37. (unless *allow-debugger*
  38. (format t "FAIL: ~A~%" c)
  39. (return-from test-impl
  40. (make-result :fail c))))))
  41. (format t "Running test ~S... " name)
  42. (funcall body-fn)
  43. (format t "OK~%")
  44. (make-result :ok))))
  45. (defmacro test ((name) &body body)
  46. "If the BODY signals a SERIOUS-CONDITION
  47. this macro returns a failed TEST-RESULT; otherwise
  48. returns a successfull TEST-RESULT."
  49. `(test-impl (quote ,name) (lambda () ,@body)))