Skip to content

Commit 9187893

Browse files
benedekfazekasbbatsov
authored andcommitted
Add test selector support
Test all and test ns understand leiningen style test selectors, eg metadata markers on `deftest`s. No support for namespace level metada markers for now. If test selector is specified only the test(s) run that have that selector in their metadata. If all loaded tests or project tests are invoked with prefix, ask for test selector in the minibuffer. A command is available to run ns tests with a selector.
1 parent 8987e77 commit 9187893

File tree

4 files changed

+107
-60
lines changed

4 files changed

+107
-60
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* Add support for shadow-cljs to `cider-jack-in`.
2121
* [#2244](https://github.com/clojure-emacs/cider/issues/2244): Display the REPL type in the modeline.
2222
* [#2238](https://github.com/clojure-emacs/cider/pull/2238): Allow specifying predicates for entries in `cider-jack-in-lein-plugins` and `cider-jack-in-nrepl-middlewares`.
23+
* Add support for test selectors. If test all or all loaded is called with a prefix ask for a selector in the minibuffer and only run those tests in the project which are marked with the selector. Add variation of test namespace which asks for a selector the same way and only runs a subset of the namespace tests.
2324

2425
### Bugs Fixed
2526

cider-repl.el

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,6 +1409,8 @@ constructs."
14091409
(declare-function cider-run "cider-interaction")
14101410
(declare-function cider-refresh "cider-interaction")
14111411
(declare-function cider-version "cider")
1412+
(declare-function cider-test-run-loaded-tests "cider-test")
1413+
(declare-function cider-test-run-project-tests "cider-test")
14121414
(cider-repl-add-shortcut "clear-output" #'cider-repl-clear-output)
14131415
(cider-repl-add-shortcut "clear" #'cider-repl-clear-buffer)
14141416
(cider-repl-add-shortcut "clear-banners" #'cider-repl-clear-banners)
@@ -1425,6 +1427,9 @@ constructs."
14251427
(cider-repl-add-shortcut "test-ns" #'cider-test-run-ns-tests)
14261428
(cider-repl-add-shortcut "test-all" #'cider-test-run-loaded-tests)
14271429
(cider-repl-add-shortcut "test-project" #'cider-test-run-project-tests)
1430+
(cider-repl-add-shortcut "test-ns-with-selector" #'cider-test-run-ns-tests-with-selector)
1431+
(cider-repl-add-shortcut "test-all-with-selector" (lambda () (cider-test-run-loaded-tests 'prompt-for-selector)))
1432+
(cider-repl-add-shortcut "test-project-with-selector" (lambda () (cider-test-run-project-tests 'prompt-for-selector)))
14281433
(cider-repl-add-shortcut "test-report" #'cider-test-show-report)
14291434
(cider-repl-add-shortcut "run" #'cider-run)
14301435
(cider-repl-add-shortcut "conn-info" #'cider-display-connection-info)

cider-test.el

Lines changed: 86 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ Add to this list to have CIDER recognize additional test defining macros."
141141
(define-key map (kbd "C-t") #'cider-test-run-test)
142142
(define-key map (kbd "C-g") #'cider-test-rerun-test)
143143
(define-key map (kbd "C-n") #'cider-test-run-ns-tests)
144+
(define-key map (kbd "C-s") #'cider-test-run-ns-tests-with-selector)
144145
(define-key map (kbd "C-l") #'cider-test-run-loaded-tests)
145146
(define-key map (kbd "C-p") #'cider-test-run-project-tests)
146147
(define-key map (kbd "C-b") #'cider-test-show-report)
@@ -149,6 +150,7 @@ Add to this list to have CIDER recognize additional test defining macros."
149150
(define-key map (kbd "t") #'cider-test-run-test)
150151
(define-key map (kbd "g") #'cider-test-rerun-test)
151152
(define-key map (kbd "n") #'cider-test-run-ns-tests)
153+
(define-key map (kbd "s") #'cider-test-run-ns-tests-with-selector)
152154
(define-key map (kbd "l") #'cider-test-run-loaded-tests)
153155
(define-key map (kbd "p") #'cider-test-run-project-tests)
154156
(define-key map (kbd "b") #'cider-test-show-report)
@@ -158,8 +160,11 @@ Add to this list to have CIDER recognize additional test defining macros."
158160
'("Test"
159161
["Run test" cider-test-run-test]
160162
["Run namespace tests" cider-test-run-ns-tests]
163+
["Run namespace tests with selector" cider-test-run-ns-tests-with-selector]
161164
["Run all loaded tests" cider-test-run-loaded-tests]
165+
["Run all loaded tests with selector" (apply-partially cider-test-run-loaded-tests 'prompt-for-selector)]
162166
["Run all project tests" cider-test-run-project-tests]
167+
["Run all project tests with selector" (apply-partially cider-test-run-project-tests 'prompt-for-selector)]
163168
["Run tests after load-file" cider-auto-test-mode
164169
:style toggle :selected cider-auto-test-mode]
165170
"--"
@@ -186,6 +191,7 @@ Add to this list to have CIDER recognize additional test defining macros."
186191
;; `f' for "run failed".
187192
(define-key map "f" #'cider-test-rerun-failed-tests)
188193
(define-key map "n" #'cider-test-run-ns-tests)
194+
(define-key map "s" #'cider-test-run-ns-tests-with-selector)
189195
(define-key map "l" #'cider-test-run-loaded-tests)
190196
(define-key map "p" #'cider-test-run-project-tests)
191197
;; `g' generally reloads the buffer. The closest thing we have to that is
@@ -202,8 +208,11 @@ Add to this list to have CIDER recognize additional test defining macros."
202208
["Rerun current test" cider-test-run-test]
203209
["Rerun failed/erring tests" cider-test-rerun-failed-tests]
204210
["Run all ns tests" cider-test-run-ns-tests]
211+
["Run all ns tests with selector" cider-test-run-ns-tests-with-selector]
205212
["Run all loaded tests" cider-test-run-loaded-tests]
213+
["Run all loaded tests with selector" (apply-partially cider-test-run-loaded-tests 'prompt-for-selector)]
206214
["Run all project tests" cider-test-run-project-tests]
215+
["Run all project tests with selector" (apply-partially cider-test-run-project-tests 'prompt-for-selector)]
207216
"--"
208217
["Jump to test definition" cider-test-jump]
209218
["Display test error" cider-test-stacktrace]
@@ -611,61 +620,67 @@ This uses the Leiningen convention of appending '-test' to the namespace name."
611620
(declare-function cider-emit-interactive-eval-output "cider-interaction")
612621
(declare-function cider-emit-interactive-eval-err-output "cider-interaction")
613622

614-
(defun cider-test-execute (ns &optional tests silent)
623+
(defun cider-test-execute (ns &optional tests silent prompt-for-selector)
615624
"Run tests for NS, which may be a keyword, optionally specifying TESTS.
616625
617626
This tests a single NS, or multiple namespaces when using keywords `:project',
618627
`:loaded' or `:non-passing'. Optional TESTS are only honored when a single
619628
namespace is specified. Upon test completion, results are echoed and a test
620629
report is optionally displayed. When test failures/errors occur, their sources
621630
are highlighted.
622-
If SILENT is non-nil, suppress all messages other then test results."
631+
If SILENT is non-nil, suppress all messages other then test results.
632+
If PROMPT-FOR-SELECTOR is non-nil, prompt the user for a test selector.
633+
The selector will be used to filter the tests before running them."
623634
(cider-test-clear-highlights)
624-
(cider-map-connections
625-
(lambda (conn)
626-
(unless silent
627-
(if (and tests (= (length tests) 1))
628-
;; we generate a different message when running individual tests
629-
(cider-test-echo-running ns (car tests))
630-
(cider-test-echo-running ns)))
631-
(cider-nrepl-send-request
632-
`("op" ,(cond ((stringp ns) "test")
633-
((eq :project ns) "test-all")
634-
((eq :loaded ns) "test-all")
635-
((eq :non-passing ns) "retest"))
636-
"ns" ,(when (stringp ns) ns)
637-
"tests" ,(when (stringp ns) tests)
638-
"load?" ,(when (or (stringp ns)
639-
(eq :project ns))
640-
"true"))
641-
(lambda (response)
642-
(nrepl-dbind-response response (summary results status out err)
643-
(cond ((member "namespace-not-found" status)
644-
(unless silent
645-
(message "No test namespace: %s" (cider-propertize ns 'ns))))
646-
(out (cider-emit-interactive-eval-output out))
647-
(err (cider-emit-interactive-eval-err-output err))
648-
(results
649-
(nrepl-dbind-response summary (error fail)
650-
(setq cider-test-last-summary summary)
651-
(setq cider-test-last-results results)
652-
(cider-test-highlight-problems results)
653-
(cider-test-echo-summary summary results)
654-
(if (or (not (zerop (+ error fail)))
655-
cider-test-show-report-on-success)
656-
(cider-test-render-report
657-
(cider-popup-buffer cider-test-report-buffer
658-
cider-auto-select-test-report-buffer)
659-
summary results)
660-
(when (get-buffer cider-test-report-buffer)
661-
(with-current-buffer cider-test-report-buffer
662-
(let ((inhibit-read-only t))
663-
(erase-buffer)))
664-
(cider-test-render-report
665-
cider-test-report-buffer
666-
summary results))))))))
667-
conn))
668-
:clj))
635+
(let ((selector (when prompt-for-selector (cider-read-from-minibuffer "Test selector (as string): "))))
636+
(cider-map-connections
637+
(lambda (conn)
638+
(unless silent
639+
(if (and tests (= (length tests) 1))
640+
;; we generate a different message when running individual tests
641+
(cider-test-echo-running ns (car tests))
642+
(cider-test-echo-running ns)))
643+
(cider-nrepl-send-request
644+
`("op" ,(cond ((stringp ns) "test")
645+
((eq :project ns) "test-all")
646+
((eq :loaded ns) "test-all")
647+
((eq :non-passing ns) "retest"))
648+
"selector" ,(when (stringp selector) selector)
649+
"ns" ,(when (stringp ns) ns)
650+
"tests" ,(when (stringp ns) tests)
651+
"load?" ,(when (or (stringp ns)
652+
(eq :project ns))
653+
"true"))
654+
(lambda (response)
655+
(nrepl-dbind-response response (summary results status out err)
656+
(cond ((member "namespace-not-found" status)
657+
(unless silent
658+
(message "No test namespace: %s" (cider-propertize ns 'ns))))
659+
(out (cider-emit-interactive-eval-output out))
660+
(err (cider-emit-interactive-eval-err-output err))
661+
(results
662+
(nrepl-dbind-response summary (error fail)
663+
(setq cider-test-last-summary summary)
664+
(setq cider-test-last-results results)
665+
(cider-test-highlight-problems results)
666+
(cider-test-echo-summary summary results)
667+
(if (or (not (zerop (+ error fail)))
668+
cider-test-show-report-on-success)
669+
(cider-test-render-report
670+
(cider-popup-buffer
671+
cider-test-report-buffer
672+
cider-auto-select-test-report-buffer)
673+
summary
674+
results)
675+
(when (get-buffer cider-test-report-buffer)
676+
(with-current-buffer cider-test-report-buffer
677+
(let ((inhibit-read-only t))
678+
(erase-buffer)))
679+
(cider-test-render-report
680+
cider-test-report-buffer
681+
summary results))))))))
682+
conn))
683+
:clj)))
669684

670685
(defun cider-test-rerun-failed-tests ()
671686
"Rerun failed and erring tests from the last test run."
@@ -677,27 +692,40 @@ If SILENT is non-nil, suppress all messages other then test results."
677692
(message "No prior failures to retest")))
678693
(message "No prior results to retest")))
679694

680-
(defun cider-test-run-loaded-tests ()
681-
"Run all tests defined in currently loaded namespaces."
682-
(interactive)
683-
(cider-test-execute :loaded))
695+
(defun cider-test-run-loaded-tests (prompt-for-selector)
696+
"Run all tests defined in currently loaded namespaces.
684697
685-
(defun cider-test-run-project-tests ()
686-
"Run all tests defined in all project namespaces, loading these as needed."
687-
(interactive)
688-
(cider-test-execute :project))
698+
If PROMPT-FOR-SELECTOR is non-nil, prompt the user for a test selector to filter the tests with."
699+
(interactive "P")
700+
(cider-test-execute :loaded nil nil prompt-for-selector))
701+
702+
(defun cider-test-run-project-tests (prompt-for-selector)
703+
"Run all tests defined in all project namespaces, loading these as needed.
704+
705+
If PROMPT-FOR-SELECTOR is non-nil, prompt the user for a test selector to filter the tests with."
706+
(interactive "P")
707+
(cider-test-execute :project nil nil prompt-for-selector))
689708

690-
(defun cider-test-run-ns-tests (suppress-inference &optional silent)
709+
(defun cider-test-run-ns-tests-with-selector (suppress-inference)
710+
"Run tests filtered by a selector for the current Clojure namespace context.
711+
712+
With a prefix arg SUPPRESS-INFERENCE it will try to run the tests in the
713+
current ns."
714+
(interactive "P")
715+
(cider-test-run-ns-tests suppress-inference nil 't))
716+
717+
(defun cider-test-run-ns-tests (suppress-inference &optional silent prompt-for-selector)
691718
"Run all tests for the current Clojure namespace context.
692719
693720
If SILENT is non-nil, suppress all messages other then test results.
694721
With a prefix arg SUPPRESS-INFERENCE it will try to run the tests in the
695-
current ns."
722+
current ns. If PROMPT-FOR-SELECTOR is non-nil, prompt the user for
723+
a test selector to filter the tests with."
696724
(interactive "P")
697725
(if-let* ((ns (if suppress-inference
698726
(cider-current-ns t)
699727
(funcall cider-test-infer-test-ns (cider-current-ns t)))))
700-
(cider-test-execute ns nil silent)
728+
(cider-test-execute ns nil silent prompt-for-selector)
701729
(if (eq major-mode 'cider-test-report-mode)
702730
(when (y-or-n-p (concat "Test report does not define a namespace. "
703731
"Rerun failed/erring tests?"))

doc/running_tests.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,24 @@ test namespace inference logic (e.g. you have some tests in the implementation
1313
namespace that were defined with `clojure.test/with-test`)
1414
- in such cases you should use <kbd>C-u C-c C-t C-n</kbd>, which will simply run
1515
whatever tests are present in the currently visited/active namespace.
16+
You can also press <kbd>C-c C-t C-s</kbd> to run a subset of the tests defined in
17+
the namespace prefiltered by a test selector. CIDER will ask you for this selector
18+
in the minibuffer. If you call this command with a prefix (<kbd>C-u C-c C-t C-s</kbd>)
19+
you can suppress the inference logic as for run tests for the namespace.
1620

1721
You can also run all loaded tests with <kbd>C-c C-t l</kbd> or <kbd>C-c C-t
1822
C-l</kbd> and all tests within a project with <kbd>C-c C-t p</kbd> or <kbd>C-c
1923
C-t C-p</kbd> (note that this will load **all** namespaces in your
20-
project). Using <kbd>C-c C-t t</kbd> or <kbd>C-c C-t C-t</kbd>, you can execute
21-
only the test at point.
24+
project). If you call these two with a prefix CIDER will ask for a test selector
25+
and only run those tests in the project which are marked with that selector. Using
26+
<kbd>C-c C-t t</kbd> or <kbd>C-c C-t C-t</kbd>, you can execute only the
27+
test at point.
28+
29+
Test selector is originally a `leiningen` feature see `lein help test` for some explanation.
30+
People use them to define subsets of tests usually run together for different purposes. For
31+
example you can mark some of your tests with the `^:smoke` metadata marker others with
32+
`^:integration`. This enables you to run these tests separately in your build pipeline.
33+
This feature in CIDER helps you to run these subsets in your development environment.
2234

2335
All test commands are available in REPL buffers as well. There you can also use
2436
<kbd>,</kbd> to invoke some of the testing commands.
@@ -30,6 +42,7 @@ Keyboard shortcut | Description
3042
--------------------------------|-------------------------------
3143
<kbd>g</kbd> | Run test at point.
3244
<kbd>n</kbd> | Run tests for current namespace.
45+
<kbd>s</kbd> | Run tests for current namespace prefiltered with a selector.
3346
<kbd>l</kbd> | Run tests for all loaded namespaces.
3447
<kbd>p</kbd> | Run tests for all project namespaces. This loads the additional namespaces.
3548
<kbd>f</kbd> | Re-run test failures/errors.

0 commit comments

Comments
 (0)