diff --git a/asdf.lisp b/asdf.lisp
index f28fbd0..875db10 100644
--- a/asdf.lisp
+++ b/asdf.lisp
@@ -57,10 +57,11 @@
            #:system-definition-pathname #:find-component ; miscellaneous
 	   #:compile-system #:load-system #:test-system
            #:compile-op #:load-op #:load-source-op
-           #:test-op
+           #:test-op #:test #:rt-test-op
            #:operation		 ; operations
            #:feature		 ; sort-of operation
            #:version		 ; metaphorically sort-of an operation
+           #:log-entry
 
            #:input-files #:output-files #:perform ; operation methods
            #:operation-done-p #:explain
@@ -1230,10 +1231,75 @@ to `~a` which is not a directory.~@:>"
 (defmethod component-depends-on :around ((o test-op) (c system))
   (cons `(load-op ,(component-name c)) (call-next-method)))
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; testing with the RT library
+;;;
+
+(defvar +rt-to-be-saved-variables+
+  (copy-tree '(("*TEST*" . NIL)
+	       ("*DO-TESTS-WHEN-DEFINED*" . NIL)
+	       ("*ENTRIES*" . (list NIL))
+	       ("*IN-TEST*" . NIL)
+	       ("*DEBUG*" . NIL)
+	       ("*CATCH-ERRORS*" . T)
+	       ("*PRINT-CIRCLE-ON-FAILURE*" . NIL)
+	       ("*COMPILE-TESTS*" . NIL)
+	       ("*OPTIMIZATION-SETTINGS*" . NIL)
+	       ("*EXPECTED-FAILURES*" . NIL))))
+
+(defun restore-variables (package-designator values &optional (failure-p t))
+  (let ((package (find-package package-designator)))
+    (cond (package
+	   (loop for pair in values
+		 for name = (car pair)
+		 for value = (eval (cdr pair))
+		 for symbol = (find-symbol name package)
+		 do (setf (symbol-value symbol) value)))
+	  (failure-p
+	   (error "Unable to find package ~A" package-designator)))))
+
+(defmacro with-saved-variables ((package-designator constant) &rest body)
+  (let ((symbols (gensym))
+	(values (gensym)))
+  `(multiple-value-prog1
+      (progn (restore-variables ,package-designator ,constant nil)
+	     ,@body)
+      (restore-variables ,package-designator ,constant))))	     
+
+(defclass rt-test-op (test-op) ())
+
+(defmethod perform ((op rt-test-op) (c component))
+  (with-saved-variables ("RT" +rt-to-be-saved-variables+)
+    (asdf:operate 'load-op c :force t)
+    (let* ((rt-package (find-package "RT"))
+	   (success (funcall (intern "DO-TESTS" rt-package)))
+	   (failed-tests (funcall (intern "PENDING-TESTS" rt-package))))
+      (print failed-tests *error-output*)
+      (values success failed-tests))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; invoking operations
 
+(defclass log-entry ()
+  ((component :initarg :component :reader log-entry-component)
+   (operation :initarg :operation :reader log-entry-operation)
+   (failed-p :initform t :accessor log-entry-failed-p)
+   (return-values :initform nil :accessor log-entry-return-values)))
+
+(defmethod print-log-entry ((entry log-entry) &optional (stream t))
+  (format stream "~&;;; Log entry:")
+  (let ((*verbose-out* stream))
+    (explain (log-entry-operation entry)
+             (log-entry-component entry)))
+  (cond ((log-entry-failed-p entry)
+         (format stream "~&;;; Operation failed"))
+        ((null (log-entry-return-values entry))
+         (format stream "~&;;; No return values"))
+        (t
+         (loop for v in (log-entry-return-values entry)
+            for n from 0
+            do (format stream "~&;;; Value[~D]: ~A" n v)))))
+
 (defun operate (operation-class system &rest args &key (verbose t) version force
                 &allow-other-keys)
   (declare (ignore force))
@@ -1243,16 +1309,22 @@ to `~a` which is not a directory.~@:>"
                     :original-initargs args
                     args))
          (*verbose-out* (if verbose *standard-output* (make-broadcast-stream)))
-         (system (if (typep system 'component) system (find-system system))))
+         (system (if (typep system 'component) system (find-system system)))
+         (asdf-log '()))
     (unless (version-satisfies system version)
       (error 'missing-component-of-version :requires system :version version))
     (let ((steps (traverse op system)))
       (with-compilation-unit ()
-        (loop for (op . component) in steps do
-                 (loop
-                   (restart-case
-                       (progn (perform op component)
-                              (return))
+        (loop for (op . component) in steps
+           for log-entry = (make-instance 'log-entry
+                                          :component component
+                                          :operation op)
+           do (loop (restart-case
+                        (progn (setf (log-entry-return-values log-entry)
+                                     (multiple-value-list (perform op component))
+                                     (log-entry-failed-p log-entry) nil)
+			       (print-log-entry log-entry)
+                               (return))
                      (retry ()
                        :report
                        (lambda (s)
@@ -1267,13 +1339,31 @@ to `~a` which is not a directory.~@:>"
                        (setf (gethash (type-of op)
                                       (component-operation-times component))
                              (get-universal-time))
-                       (return)))))))
-    op))
+                       (return))))
+           do (push log-entry asdf-log))))
+    (values op asdf-log)))
 
 (defun oos (operation-class system &rest args &key force (verbose t) version
 	    &allow-other-keys)
   (declare (ignore force verbose version))
-  (apply #'operate operation-class system args))
+  (values (apply #'operate operation-class system args)))
+
+(defun test (test-class system &rest args &key force (verbose t) version
+             &allow-other-keys)
+  (multiple-value-bind (op log)
+      (apply #'operate test-class system args)
+    (loop with output = '()
+       with all-ok = t
+       for entry in log
+       for failed-p = (log-entry-failed-p entry)
+       for op = (log-entry-operation entry)
+       for values = (log-entry-return-values entry)
+       when (and (not failed-p) (typep op test-class))
+       do (multiple-value-bind (test-ok failed-test-sequence)
+	      (values-list values)
+            (setf output (concatenate 'list output failed-test-sequence)
+                  all-ok (and all-ok test-ok)))
+       finally (return (values all-ok output)))))
 
 (let ((operate-docstring
   "Operate does three things:
