As a first step, you can make a small change to report-result so it returns the result of the test case it’s reporting.

    Now that report-result returns the result of its test case, it might seem you could just change the **PROGN** to an **AND** to combine the results. Unfortunately, **AND** doesn’t do quite what you want in this case because of its short-circuiting behavior: as soon as one test case fails, **AND** will skip the rest. On the other hand, if you had a construct that worked like **AND** without the short-circuiting, you could use it in the place of **PROGN**, and you’d be done. Common Lisp doesn’t provide such a construct, but that’s no reason you can’t use it: it’s a trivial matter to write a macro to provide it yourself.

    1. (foo)
    2. (bar)
    3. (baz))

    and have it mean something like this:

    The only tricky bit to writing this macro is that you need to introduce a variable—result in the previous code—in the expansion. As you saw in the previous chapter, using a literal name for variables in macro expansions can introduce a leak in your macro abstraction, so you’ll need to create a unique name. This is a job for with-gensyms. You can define combine-results like this:

    1. (with-gensyms (result)
    2. `(let ((,result t))
    3. ,@(loop for f in forms collect `(unless ,f (setf ,result nil)))

    With that version of check, test-+ should emit the results of its three test expressions and then return **T** to indicate that everything passed.4

    1. pass ... (= (+ 1 2) 3)
    2. pass ... (= (+ 1 2 3) 6)
    3. pass ... (= (+ -1 -3) -4)

    And if you change one of the test cases so it fails,5 the final return value changes to **NIL**.