Add shadow test runner that provides most test-runner like options

pull/4383/head
Gabriel Horner 2022-02-23 16:23:45 -05:00 committed by Tienson Qin
parent db7d1cde09
commit 35d2023e24
5 changed files with 98 additions and 6 deletions

View File

@ -65,4 +65,5 @@ frontend.util.pool/terminate-pool!
;; Repl fn
frontend.util.property/add-page-properties
;; Used by shadow
frontend.worker.parser/init
frontend.test-runner/main

View File

@ -43,7 +43,6 @@
:test {:extra-paths ["src/test/"]
:extra-deps {org.clojure/clojurescript {:mvn/version "1.10.879"}
org.clojure/test.check {:mvn/version "1.1.1"}
org.clojars.lucywang000/shadow-test-utils {:mvn/version "0.0.2"}
org.clojars.knubie/cljs-run-test {:mvn/version "1.0.1"}}
:main-opts ["-m" "shadow.cljs.devtools.cli"]}

View File

@ -86,8 +86,13 @@ shadow-cljs watch test --config-merge '{:autorun true :ns-regexp
#### Focus Tests
Tests can be automatically compiled and then selectively run on the commandline
using https://github.com/lucywang000/shadow-test-utils. For this workflow:
using our own test runner which emulates most of the options of [cognitect-labs/test
runner](https://github.com/cognitect-labs/test-runner#invoke-with-clojure--m-clojuremain).
For this workflow:
1. Run `clj -M:test watch test` in one shell
2. Focus a test by adding a `^:focus` metadata flag
3. In another shell, run `node node static/tests.js`
2. Focus tests or namespaces:
1. To focus test(s), add `^:focus` metadata flags. In another shell, run `node static/tests.js -i focus`
2. Alternatively, focus namespaces by using the regex option e.g. `node static/tests.js -r text` which runs tests for `frontend.text-test`.
For help on more focusing options, run `node static/tests.js -h`

View File

@ -61,7 +61,8 @@
:test {:target :node-test
:output-to "static/tests.js"
:closure-defines {frontend.util/NODETEST true}
:devtools {:enabled false}}
:devtools {:enabled false}
:main frontend.test-runner/main}
:publishing {:target :browser
:module-loader true

View File

@ -0,0 +1,86 @@
(ns frontend.test-runner
"shadow-cljs test runner for :node-test that provides most of the same options
as
https://github.com/cognitect-labs/test-runner#invoke-with-clojure--m-clojuremain.
This gives the user a fair amount of control over which tests and namespaces
to call from the commandline. Once this test runner is stable enough we should
contribute it upstream"
(:require [shadow.test.env :as env]
[clojure.tools.cli :as cli]
[shadow.test.node :as node]
[clojure.string :as str]
["util" :as util]))
(defn- print-summary
"Print help summary given args and opts strings"
[options-summary additional-msg]
(println (util/format "Usage: %s [OPTIONS]\nOptions:\n%s%s"
"$0"
options-summary
additional-msg)))
(defn- parse-options
"Processes a command's functionality given a cli options definition, arguments
and primary command fn. This handles option parsing, handles any errors with
parsing and then returns options"
[args cli-opts & parse-opts-options]
(let [{:keys [errors] :as parsed-input}
(apply cli/parse-opts args cli-opts parse-opts-options)]
(if (seq errors)
(do (println (str/join "\n" (into ["Options failed to parse:"] errors)))
(js/process.exit 1))
parsed-input)))
(defn- run-test-options
"Given available tests namespaces as symbols, test vars and options,
returns run options for selected tests to run"
[namespaces
vars
{:keys [include exclude namespace namespace-regex]}]
(let [focused-tests (cond
(seq include)
(map symbol (filter (fn [v]
(let [metadata (meta v)]
(some metadata include)))
vars))
exclude
(map symbol (remove (comp exclude meta) vars)))
test-syms (cond (some? focused-tests)
focused-tests
namespace
[namespace]
namespace-regex
(filter #(re-find namespace-regex (str %)) namespaces))]
;; NOTE: If include points to a nonexistent metadata flag, this results in test-syms being '().
;; We would expect no tests to run but instead the node test runner runs all tests.
;; We may want to workaround this
(cond-> {}
(some? test-syms)
(assoc :test-syms test-syms))))
(def cli-options
[["-h" "--help"]
["-i" "--include INCLUDE"
:default #{}
:parse-fn keyword
:multi true :update-fn conj
:desc "Run only tests with this metadata keyword. Can be specified more than once"]
;; TODO: Fix and enable once it's determined if this is an internal or shadow bug
#_["-e" "--exclude EXCLUDE" :parse-fn keyword]
["-n" "--namespace NAMESPACE"
:parse-fn symbol :desc "Specific namespace to test"]
["-r" "--namespace-regex REGEX"
:parse-fn re-pattern :desc "Regex for namespaces to test"]])
(defn main [& args]
;; Load test data as is done with shadow.test.node/main
(node/reset-test-data!)
(let [{:keys [options summary]} (parse-options args cli-options)]
(if (:help options)
(do
(print-summary summary
"\n\nNone of these options can be composed. Defaults to running all tests")
(js/process.exit 0))
(node/execute-cli
(run-test-options (keys (env/get-tests)) (env/get-test-vars) options)))))