-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
427 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
*/target | ||
pom.xml | ||
pom.xml.asc | ||
*.jar | ||
*.class | ||
.lein-* | ||
.nrepl-port | ||
**/test/.output |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,24 @@ | ||
# test-report-sonar | ||
|
||
Renders test reports results in [Sonar Generic Execution format](https://docs.sonarqube.org/latest/analysis/generic-test/#header-2). | ||
|
||
To run the plugin add the following to the `:test` profile | ||
|
||
```clojure | ||
:profiles {:test {:plugins [[org.clojars.konstan/lein-test-report-sonar "0.0.2"]] | ||
:test-report-sonar {:output-dir "test-reports"}} | ||
} | ||
``` | ||
|
||
The reports will be generated in `test-reports/sonar/testExecutions.xml`. | ||
|
||
The plugin can generate JUnit XML results as well (internally uses . To do so, add | ||
`:emit-junit-xml true` under `:test-report-sonar` map. | ||
|
||
```clojure | ||
:profiles {:test {:plugins [[org.clojars.konstan/lein-test-report-sonar "0.0.2"]] | ||
:test-report-sonar {:output-dir "test-reports" | ||
:emit-junit-xml true}} | ||
} | ||
``` | ||
The JUnit XML reports will be generated under `test-reports/xml/`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
(defproject org.clojars.konstan/lein-test-report-sonar "0.0.3" | ||
:description "Leiningen plugin providing Sonar Generic execution output for clojure.test" | ||
:url "https://github.com/konstan/test-report-sonar" | ||
:scm {:dir ".."} | ||
:license {:name "Eclipse Public License", :url "http://www.eclipse.org/legal/epl-v10.html"} | ||
:dependencies [[lein-test-report "0.2.0"]] | ||
:deploy-repositories [["clojars" {:sign-releases false | ||
:url "https://clojars.org/repo" | ||
:username :env/clojars_username | ||
:password :env/clojars_password | ||
;;:signing {:gpg-key "release manager key"} | ||
}] | ||
["releases" {:sign-releases false | ||
:url "https://clojars.org/repo"}] | ||
["snapshots" {:sign-releases false | ||
:url "https://clojars.org/repo"}]] | ||
:aliases {"deploy" ["deploy" "clojars"]} | ||
:eval-in-leiningen true) |
36 changes: 36 additions & 0 deletions
36
lein-test-report-sonar/src/lein_test_report_sonar/plugin.clj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
(ns lein-test-report-sonar.plugin | ||
(:require [lein-test-report.utils :refer [add-profile]])) | ||
|
||
(def ^:const ver-test-report-junit-xml "0.2.0") | ||
(def ^:const ver-test-report-sonar "0.0.3") | ||
(def ^:const ver-test-report "0.2.0") | ||
|
||
|
||
(defn middleware [project] | ||
(let [output-dir (or (System/getenv "TEST_REPORT_SONAR_OUTPUT_DIR") | ||
(-> project :test-report-sonar :output-dir) | ||
"target/test-reports") | ||
options (-> project | ||
(:test-report-sonar {}) | ||
(dissoc :output-dir :emit-junit-xml)) | ||
emit-junit-xml (-> project :test-report-sonar :emit-junit-xml) | ||
dependencies (if emit-junit-xml | ||
[['org.clojars.konstan/test-report-sonar ver-test-report-sonar] | ||
['test-report-junit-xml ver-test-report-junit-xml]] | ||
[['org.clojars.konstan/test-report-sonar ver-test-report-sonar]]) | ||
summarizers (if emit-junit-xml | ||
`[#(test-report-sonar.core/write (str ~output-dir "/sonar") % ~options) | ||
#(test-report-junit-xml.core/write (str ~output-dir "/xml") % ~options)] | ||
`[#(test-report-sonar.core/write (str ~output-dir "/sonar") % ~options)]) | ||
injections (if emit-junit-xml | ||
`[(require 'test-report-sonar.core) | ||
(require 'test-report-junit-xml.core) | ||
(require 'clojure.java.io)] | ||
`[(require 'test-report-sonar.core) | ||
(require 'clojure.java.io)])] | ||
(add-profile project {:dependencies dependencies | ||
:plugins [['lein-test-report ver-test-report]] | ||
:injections injections | ||
:test-report {:summarizers summarizers}}))) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
(defproject org.clojars.konstan/test-report-sonar "0.0.3" | ||
:description "Library providing Sonar Generic execution output for clojure.test" | ||
:url "https://github.com/konstan/test-report-sonar" | ||
:scm {:dir ".."} | ||
:license {:name "Eclipse Public License", :url "http://www.eclipse.org/legal/epl-v10.html"} | ||
:plugins [[lein-shade "0.4.0"]] | ||
:dependencies [[test-report-junit-xml "0.2.0"]] | ||
:profiles {:test {:resource-paths ["test/resources"]} | ||
:uberjar {:aot :all} | ||
:provided {:dependencies [[org.clojure/clojure "1.10.3"]]} | ||
:shaded {:dependencies [[org.clojure/data.xml "0.2.0-alpha2" :exclusions [org.clojure/clojure]]] | ||
:shade {:namespaces [clojure.data.xml]}} | ||
:unshaded ^:leaky {:dependencies [[test-report "0.2.0"]]} | ||
:default [:leiningen/default :shaded :unshaded]} | ||
:deploy-repositories [["clojars" {:sign-releases false | ||
:url "https://clojars.org/repo" | ||
:username :env/clojars_username | ||
:password :env/clojars_password | ||
;;:signing {:gpg-key "konstan release manager key"} | ||
}] | ||
["releases" {:sign-releases false | ||
:url "https://clojars.org/repo"}] | ||
["snapshots" {:sign-releases false | ||
:url "https://clojars.org/repo"}]] | ||
:aliases {"deploy" ["deploy-shaded-jar" "clojars"] | ||
"install" ["install-shaded-jar"]}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
(ns test-report-sonar.core | ||
(:require | ||
[test-report.options :refer [with-options]] | ||
[test-report.summary :refer [summarize]] | ||
[clojure.data.xml :as xml] | ||
[clojure.java.io :as io] | ||
[clojure.stacktrace :as stacktrace] | ||
[clojure.string :as string] | ||
[test-report-sonar.utils :refer :all])) | ||
|
||
|
||
(defmulti ^:private format-result :type) | ||
|
||
|
||
(defn- format-stacktrace [error] | ||
(with-out-str (stacktrace/print-cause-trace error))) | ||
|
||
|
||
(def ^:dynamic *format-result* format-result) | ||
(def ^:dynamic *format-stacktrace* format-stacktrace) | ||
|
||
|
||
(defn- join-non-blanks [delimiter & strings] | ||
(->> strings (remove string/blank?) (string/join delimiter))) | ||
|
||
|
||
(defn- context [result] | ||
(->> result :context reverse (string/join " "))) | ||
|
||
|
||
(defn- error-message [error] | ||
(when (instance? Throwable error) | ||
(.getMessage error))) | ||
|
||
|
||
(defn- error-cause [error] | ||
(if (instance? Throwable error) | ||
(*format-stacktrace* error) | ||
(prn-str error))) | ||
|
||
|
||
(defmethod format-result :fail | ||
[result] | ||
(let [message (join-non-blanks ": " (context result) (or (:message result) "failure"))] | ||
{:tag :failure | ||
:attrs {:message message} | ||
:content (join-non-blanks "\n" | ||
message | ||
(str "expected: " (-> result :expected prn-str) | ||
" actual: " (-> result :actual prn-str) | ||
" at: " (:file result) ":" (:line result)))})) | ||
|
||
|
||
(defmethod format-result :error | ||
[result] | ||
(let [message (join-non-blanks ": " (context result) (or (:message result) "error") (-> result :actual error-message))] | ||
{:tag :error | ||
:attrs {:message message} | ||
:content (join-non-blanks "\n" | ||
message | ||
(str "expected: " (-> result :expected prn-str) | ||
" actual: " (-> result :actual error-cause)))})) | ||
|
||
|
||
(defmethod format-result :default [result]) | ||
|
||
|
||
(defn- test-case | ||
[test-var] | ||
{:tag :testCase | ||
:attrs {:name (-> test-var :var meta :name) | ||
:duration (-> test-var :time nanos->millis)} | ||
:content (keep *format-result* (:results test-var))}) | ||
|
||
|
||
(defn- file | ||
[test-ns] | ||
{:tag :file | ||
:attrs {:path (-> test-ns :ns ns->path)} | ||
:content (map test-case (:tests test-ns))}) | ||
|
||
|
||
(defn- test-executions | ||
[tested-namespaces] | ||
{:tag :testExecutions | ||
:attrs {:version "1"} | ||
:content (map file tested-namespaces)}) | ||
|
||
|
||
(defn- output-file | ||
[output-dir file-name] | ||
(io/file output-dir file-name)) | ||
|
||
|
||
(defn- write-reports-xml | ||
[output-dir testexecutions] | ||
(.mkdirs (io/file output-dir)) | ||
(with-open [writer (io/writer (output-file output-dir "testExecutions.xml"))] | ||
(xml/emit testexecutions writer))) | ||
|
||
|
||
(defn write | ||
"Writes a Sonar Generic Execution formatted | ||
(https://docs.sonarqube.org/latest/analysis/generic-test/) summary of the | ||
given clojure.test/report messages to the given output directory. | ||
Output may be configured by supplying the following options (or by binding the | ||
corresponding dynamic vars): | ||
:format-result - a function that converts a test result message into an | ||
XML element (a map with keys [:tag :attrs :content]), or | ||
nil if no element should be output (e.g. if the message | ||
:type is :pass) | ||
(default test-report-junit-xml.core/format-result) | ||
:format-stacktrace - a function that takes a Throwable and returns a string | ||
containing the formatted stacktrace (may not be used if | ||
:format-result is configured) | ||
(default test-report-sonar.core/format-stacktrace, | ||
uses clojure.stacktrace/print-cause-trace)" | ||
([output-dir messages] | ||
(write output-dir messages {})) | ||
([output-dir messages options] | ||
(with-options options | ||
(->> messages | ||
summarize | ||
:namespaces | ||
test-executions | ||
(write-reports-xml output-dir))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
(ns test-report-sonar.utils | ||
(:require | ||
[clojure.string :as string])) | ||
|
||
|
||
(defn nanos->millis [nanos] | ||
(->> nanos (* 1e-6) int)) | ||
|
||
|
||
(defn guess-ns-ext | ||
[nsname] | ||
(cond | ||
(string/starts-with? nsname "clj.") ".clj" | ||
(string/starts-with? nsname "cljc.") ".cljc" | ||
(string/starts-with? nsname "cljs.") ".cljs" | ||
(string/starts-with? nsname "cljr.") ".cljr" | ||
:else ".clj")) | ||
|
||
|
||
(defn ns->path | ||
[ns] | ||
(let [nsname (-> ns ns-name)] | ||
(-> nsname | ||
(string/replace #"-" "_") | ||
(string/replace #"\." "/") | ||
(str (guess-ns-ext nsname))))) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
[{:type :begin-test-ns | ||
:ns (find-ns 'example.first-test) | ||
:time 51705939435917} | ||
{:type :begin-test-var | ||
:var #'example.first-test/nested | ||
:time 51705941156806} | ||
{:type :pass | ||
:expected '(= 0 0) | ||
:actual (list = 0 0) | ||
:message nil | ||
:time 51705942160982 | ||
:context (list "inner" "outer")} | ||
{:type :end-test-var | ||
:var #'example.first-test/nested | ||
:time 51705942255394} | ||
{:type :begin-test-var | ||
:var #'example.first-test/passing | ||
:time 51705942304461} | ||
{:type :pass | ||
:expected '(= 0 0) | ||
:actual (list = 0 0) | ||
:message nil | ||
:time 51705942641504 | ||
:context ()} | ||
{:type :pass | ||
:expected '(= 0 0) | ||
:actual (list = 0 0) | ||
:message nil | ||
:time 51705942719891 | ||
:context ()} | ||
{:type :end-test-var | ||
:var #'example.first-test/passing | ||
:time 51705942761235} | ||
{:type :begin-test-var | ||
:var #'example.first-test/erroring | ||
:time 51705942804163} | ||
{:file "Numbers.java" | ||
:line 158 | ||
:type :error | ||
:expected '(= 0 (/ 0 0)) | ||
:actual (doto (ArithmeticException. "Divide by zero") | ||
(.setStackTrace (into-array [(StackTraceElement. "clojure.lang.Numbers" "divide" "Numbers.java" 158) | ||
(StackTraceElement. "clojure.lang.Numbers" "divide" "Numbers.java" 3808) | ||
(StackTraceElement. "example.first_test$fn__1305" "invokeStatic" "first_test.clj" 17) | ||
(StackTraceElement. "example.first_test$fn__1305" "invoke" "first_test.clj" 16)]))) | ||
|
||
:message nil | ||
:time 51705943130574 | ||
:context ()} | ||
{:type :end-test-var | ||
:var #'example.first-test/erroring | ||
:time 51705943173760} | ||
{:type :begin-test-var | ||
:var #'example.first-test/failing | ||
:time 51705943223768} | ||
{:file "first_test.clj" | ||
:line 14 | ||
:type :fail | ||
:expected '(= 0 1) | ||
:actual '(not (= 0 1)) | ||
:message nil | ||
:time 51705943734108 | ||
:context ()} | ||
{:type :end-test-var | ||
:var #'example.first-test/failing | ||
:time 51705943780352} | ||
{:type :end-test-ns | ||
:ns (find-ns 'example.first-test) | ||
:time 51705943839193} | ||
{:type :begin-test-ns | ||
:ns (find-ns 'example.second-test) | ||
:time 51705943913222} | ||
{:type :begin-test-var | ||
:var #'example.second-test/passing | ||
:time 51705944232368} | ||
{:type :pass | ||
:expected '(= 0 0) | ||
:actual (list = 0 0) | ||
:message nil | ||
:time 51705944438664 | ||
:context ()} | ||
{:type :end-test-var | ||
:var #'example.second-test/passing | ||
:time 51705944538554} | ||
{:type :end-test-ns | ||
:ns (find-ns 'example.second-test) | ||
:time 51705944585988} | ||
{:test 5 | ||
:pass 0 | ||
:fail 0 | ||
:error 0 | ||
:type :summary | ||
:time 51705944686193}] |
11 changes: 11 additions & 0 deletions
11
test-report-sonar/test/resources/output/testExecutions.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?xml version="1.0" encoding="UTF-8"?><testExecutions version="1"><file path="example/first_test.clj"><testCase name="nested" duration="1"></testCase><testCase name="passing" duration="0"></testCase><testCase name="erroring" duration="0"><error message="error: Divide by zero">error: Divide by zero | ||
expected: (= 0 (/ 0 0)) | ||
actual: java.lang.ArithmeticException: Divide by zero | ||
at clojure.lang.Numbers.divide (Numbers.java:158) | ||
clojure.lang.Numbers.divide (Numbers.java:3808) | ||
example.first_test$fn__1305.invokeStatic (first_test.clj:17) | ||
example.first_test/fn (first_test.clj:16) | ||
</error></testCase><testCase name="failing" duration="0"><failure message="failure">failure | ||
expected: (= 0 1) | ||
actual: (not (= 0 1)) | ||
at: first_test.clj:14</failure></testCase></file><file path="example/second_test.clj"><testCase name="passing" duration="0"></testCase></file></testExecutions> |
Oops, something went wrong.