最小化复现
`
(require 'clojure.test)
(clojure.test/deftest foo-test
(throw (ex-info "I fail" {})))
(clojure.test/deftest bar-test
(.println System/out "bar"))
(clojure.test/test-vars [#'foo-test #'bar-test])
`
结果
在 (foo-test) 中出现错误 (core.clj:4617) 未捕获的异常,不在断言中。期望:nil 实际:clojure.lang.ExceptionInfo: I fail at clojure.core$ex_info.invokeStatic (core.clj:4617)...
注意 "bar" 出现在错误报告中间的 {{foo-test}} 输出中。
分析
{{(clojure.test/report {:type :error, :actual some-exception})}} 调用 {{stack/print-cause-trace}}。与其他 {{clojure.test/report}} 调用路径不同,这不会在新行上刷新。因此,当测试失败并带有异常且有东西直接写入 Java 的 {{System.out}} 时,错误报告的第一部分和异常跟踪之间可能会有很大的差距。
(要解释为什么会让人烦恼:我们正在通过 {{clj-webdriver}} 运行 Selenium 测试,并且我们的测试系统通过 {{clojure.tools.logging}} 使用 log4j 进行记录。我们总是看到 "expected: ..." 和随后的 "actual: ..." 异常跟踪之间的数十行甚至数百行。这使得得出关于何时发生失败与其他出现在日志中的事件的结论变得非常容易错误)。
(在我看来,如果 {{clojure.test/report}} 总是构造每个单独调用的输出为单个字符串,然后一次性写入到 {{* }} 中,那就更好了——这样就能保证输出不会被其他线程的输出干扰。如果不是这样,那么至少如果 {{:error}} 实现调用 {{(flush)}},将会大有裨益。)