(defpackage :testiere.examples (:use #:cl #:testiere)) (defpackage :dummy (:use #:cl)) (in-package :testiere.examples) ;;; Turn Testiere On. (eval-when (:compile-toplevel :load-toplevel :execute) (testiere:on)) ;;; BASIC TESTS (defun add3 (x y z) "Adds three numbers" #+testiere (:tests (= 6 (add3 1 2 3)) (:is (evenp (add3 2 2 2))) (:fails (add3)) (:fails (add3 1 2 "oh no"))) (+ x y z)) ;;; Using external tests (defun dummy::test-add10 (n) "Tests add10 in the same way N times. Obviously useless. We define this in a separate package to give you an idea that you can embed tests that aren't part of the package you're testing." (loop :repeat n :do (assert (= 13 (add10 3))))) (defun add10 (x) "Adds 10 to X" #+testiere (:tests (:funcall 'dummy::test-add10 1)) (+ x 10)) ;;; Adding some context to tests with :LET (defvar *count*) (defun increment-count (&optional (amount 1)) "Increments *COUNT* by AMOUNT" #+testiere (:tests (:let ((*count* 5)) (:do (increment-count)) (= *count* 6) (:do (increment-count 4)) (= *count* 10)) (:let ((*count* -10)) (= (increment-count) -9))) (incf *count* amount)) ;;; Stubbing functions with :WITH-DEFUNS (defun test-count-words-in-response () (assert (= 3 (count-words-in-response "blah")))) (defun count-words-in-response (url) "Fetches a url and counts the words in the response." #+testiere (:tests ;; here we stub a fictitious make-drakma-request function (:with-defuns ((dummy::make-drakma-request (url) (declare (ignore url)) "Hello there dudes")) (= 3 (count-words-in-response "dummy-url")) (:funcall 'test-count-words-in-response))) (loop :with resp := (dummy::make-drakma-request url) :with in-word? := nil :for char :across resp :when (and in-word? (not (alphanumericp char))) :count 1 :into wc :and :do (setf in-word? nil) :when (alphanumericp char) :do (setf in-word? t) :finally (return (if (alphanumericp char) (1+ wc) wc)))) ;;; Testing Classes (defclass point () ((x :accessor px :initform 0 :initarg :x) (y :accessor py :initform 0 :initarg :y)) #+testiere (:tests (:let ((pt (make-instance 'point :x 10 :y 20))) (= 20 (py pt)) (= 10 (px pt)) (:is (< (px pt) (py pt)))))) ;;; Testing Structs (defstruct pt x y #+testiere (:tests (:let ((pt (make-pt :x 10 :y 20))) (= 20 (pt-y pt)) (:is (< (pt-x pt) (pt-y pt)))))) ;;; Testing Types (deftype optional-int () #+testiere (:tests (:is (typep nil 'optional-int)) (:is (typep 10 'optional-int)) (:is (not (typep "foo" 'optional-int)))) '(or integer null))