Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Fetching contributors…
Cannot retrieve contributors at this time
117 lines (93 sloc) 3.45 KB
; Copyright (c) Rich Hickey. All rights reserved.
; The use and distribution terms for this software are covered by the
; Eclipse Public License 1.0 (
; which can be found in the file epl-v10.html at the root of this distribution.
; By using this software in any fashion, you are agreeing to be bound by
; the terms of this license.
; You must not remove this notice, or any other, from this software.
;;; test_is/tap.clj: Extension to test for TAP output
;; by Stuart Sierra
;; March 31, 2009
;; Inspired by ClojureCheck by Meikel Brandmeyer:
(ns ^{:doc "clojure.test extensions for the Test Anything Protocol (TAP)
TAP is a simple text-based syntax for reporting test results. TAP
was originally develped for Perl, and now has implementations in
several languages. For more information on TAP, see and
To use this library, wrap any calls to
clojure.test/run-tests in the with-tap-output macro,
like this:
(use 'clojure.test)
(use 'clojure.test.tap)
(run-tests '"
:author "Stuart Sierra"}
(:require [clojure.test :as t]
[clojure.stacktrace :as stack]))
(defn print-tap-plan
"Prints a TAP plan line like '1..n'. n is the number of tests"
{:added "1.1"}
(println (str "1.." n)))
(defn print-tap-diagnostic
"Prints a TAP diagnostic line. data is a (possibly multi-line)
{:added "1.1"}
(doseq [line (.split ^String data "\n")]
(println "#" line)))
(defn print-tap-pass
"Prints a TAP 'ok' line. msg is a string, with no line breaks"
{:added "1.1"}
(println "ok" msg))
(defn print-tap-fail
"Prints a TAP 'not ok' line. msg is a string, with no line breaks"
{:added "1.1"}
(println "not ok" msg))
;; This multimethod will override test/report
(defmulti ^:dynamic tap-report (fn [data] (:type data)))
(defmethod tap-report :default [data]
(print-tap-diagnostic (pr-str data))))
(defmethod tap-report :pass [data]
(t/inc-report-counter :pass)
(print-tap-pass (t/testing-vars-str))
(when (seq t/*testing-contexts*)
(print-tap-diagnostic (t/testing-contexts-str)))
(when (:message data)
(print-tap-diagnostic (:message data)))
(print-tap-diagnostic (str "expected:" (pr-str (:expected data))))
(print-tap-diagnostic (str " actual:" (pr-str (:actual data))))))
(defmethod tap-report :error [data]
(t/inc-report-counter :error)
(print-tap-fail (t/testing-vars-str))
(when (seq t/*testing-contexts*)
(print-tap-diagnostic (t/testing-contexts-str)))
(when (:message data)
(print-tap-diagnostic (:message data)))
(print-tap-diagnostic "expected:" (pr-str (:expected data)))
(print-tap-diagnostic " actual: ")
(if (instance? Throwable (:actual data))
(stack/print-cause-trace (:actual data) t/*stack-trace-depth*)
(prn (:actual data)))))))
(defmethod tap-report :summary [data]
(print-tap-plan (+ (:pass data) (:fail data) (:error data)))))
(defmacro with-tap-output
"Execute body with modified test reporting functions that produce
TAP output"
{:added "1.1"}
[& body]
`(binding [t/report tap-report]
Jump to Line
Something went wrong with that request. Please try again.