lazytest

seancorfield 2024-11-16T20:33:20.549449Z

A Q about options. I see that the CLI has --output, so there's an :output key in the options map, but in the running entry points, :reporter is set to output and the lower-level machinery uses :reporter to control the "output". As I'm working on integration with test-runner and the Polylith external test runner, I can map most of the options (`:include`/`:exclude` work the same, :namespace => :ns-filter, :var => :var-filter), but it looks like I'll have to add processing for :output, duplicating lazytest.cli's logic (which is fine), and then rename :output => :reporter for the low-level calls (which is also fine). Is there anything in the low-level machinery in LazyTest that depends on both :output and*` :reporter, or can I safely just pass :reporter (with the cleaned up value of :output)? I think I can, looking at the code, but I'm curious why it is the way it is (since -r --reporter is *not a CLI option)?

2024-11-16T21:09:48.171109Z

great question

2024-11-16T21:11:13.102959Z

I went with --output because reporter felt too low level. Output could also mean "prints json", whereas reporter feels specifically like "displayed presentation"

seancorfield 2024-11-16T21:11:25.149169Z

$ clojure -M:test -m cognitect.test-runner --output dots -e :broken

Running tests in #{"test"}
(..)
Ran 2 test cases in 0.00461 seconds.
0 failures.
(excludes tests marked ^:broken, uses dots output/reporter)

2024-11-16T21:11:46.380179Z

that's sick

2024-11-16T21:12:10.623669Z

I can expose or API-fy the internal functions if that would help you

seancorfield 2024-11-16T21:12:47.171619Z

And this runs both clojure.test and LazyTest tests marked ^:broken:

$ clojure -M:test -m cognitect.test-runner --output dots -i :broken

Running tests in #{"test"}

Testing lazy.lib.lazy.lib-test

FAIL in (old-test) (lib_test.clj:8)
FIXME, I fail.
expected: (= 0 1)
  actual: (not (= 0 1))

Ran 1 tests containing 1 assertions.
1 failures, 0 errors.
=== FOCUSED TESTS ONLY ===

(F)
lazy.lib.lazy.lib-test
  broken
    needs fixing:

Expectation failed
Expected: (= 0 1)
Actual: false
Evaluated arguments:
 * 0
 * 1
Only in first argument:
0
Only in second argument:
1

in lazy/lib/lazy/lib_test.clj:12

Ran 1 test cases in 0.00328 seconds.
1 failure.

seancorfield 2024-11-16T21:13:30.973389Z

(I was a bit surprised to see FOCUSED TESTS ONLY since I wasn't using :focus anywhere, but I gather it does that in other situations?)

2024-11-16T21:13:34.565129Z

that's very cool

2024-11-16T21:14:03.963889Z

you're narrowing with -i

seancorfield 2024-11-16T21:14:50.308629Z

Ah, got it...

$ clojure -M:test -m cognitect.test-runner --output dots -i :working

Running tests in #{"test"}
=== FOCUSED TESTS ONLY ===

(..)
Ran 2 test cases in 0.00353 seconds.
0 failures.

2024-11-16T21:14:57.553439Z

i wanted it to be obvious that any narrowing is focusing on a subset, not the whole test suite

2024-11-16T21:15:35.482479Z

but i can be convinced away from that too lol

2024-11-16T21:16:28.353889Z

i don't remember why I went with :output converted to :reporter. i bet using the :id option in tools.cli would be a simple fix to make it all consistently :reporter or whatever

2024-11-16T21:16:39.440909Z

i'll need to look at the code again

seancorfield 2024-11-16T21:21:48.463769Z

I have the -X version of test-runner partly working too (the handling of :output is a bit wonky):

$ clojure -X:test cognitect.test-runner.api/test :output dots :includes '[:working]'

Running tests in #{"test"}
=== FOCUSED TESTS ONLY ===

(..)
Ran 2 test cases in 0.00369 seconds.
0 failures.

seancorfield 2024-11-16T21:29:30.378409Z

(based on how the other -X options work, it probably should be :outputs but that's a bit unwieldy since you mostly just want one; pushed a reasonably fixed up version of it now)

2024-11-16T21:29:49.872149Z

I don't like -X so i completely forgot to support it lol. Thanks for the reminder to set something up

seancorfield 2024-11-16T21:30:21.744459Z

Well, test-runner already has it so I only needed to make :output work 🙂

2024-11-16T21:32:04.910629Z

Most of the time, you supply a single reporter that bundles smaller reporters together: "dots" is [focused dots* results summary], so it felt wrong to use outputs

seancorfield 2024-11-16T21:32:58.741859Z

No, I meant in the context of test-runner: all the -X options are plural and take collections, but the underlying -M / CLI options are all singular (but can be provided multiple times).

seancorfield 2024-11-16T21:33:31.571589Z

--include :a --include :b but :includes '[:a :b]'

2024-11-16T21:34:13.798999Z

oh interesting

2024-11-16T21:34:30.558759Z

i trust your judgment in this area

seancorfield 2024-11-16T21:34:55.127989Z

I think test-runner's approach is a bit weird but...

2024-11-16T21:35:06.357059Z

internally, --output returns a vector regardless of how many are provided

seancorfield 2024-11-16T21:35:53.473129Z

Yes, same in the -M options of test-runner. It's only the -X options that are plurals and require vectors...

seancorfield 2024-11-16T21:36:24.118919Z

(I don't think many folks use the options with -X, just "go run all the tests" 🙂 )

😂 1
2024-11-16T21:36:35.350279Z

that's fine by me if that's how the other options are

2024-11-16T21:36:55.980409Z

i took direct inspiration from c.tr when building the lazytest cli, as you probably noticed

seancorfield 2024-11-16T21:39:19.262259Z

Made it consistent:

$ clojure -X:test cognitect.test-runner.api/test :includes '[:working]' :outputs '[dots]'

Running tests in #{"test"}
=== FOCUSED TESTS ONLY ===

(..)
Ran 2 test cases in 0.00382 seconds.
0 failures.

😍 1
seancorfield 2024-11-16T21:42:02.884839Z

I will say that the reporters don't seem to compose very well:

$ clojure -X:test cognitect.test-runner.api/test :includes '[:working]' :outputs '[dots clojure-test]'

Running tests in #{"test"}
=== FOCUSED TESTS ONLY ===

(
Testing lazy.lib.lazy.lib-test
..)
Ran 2 test cases in 0.00684 seconds.
0 failures.


Ran 1 tests containing 2 test cases.
0 failures, 0 errors.

seancorfield 2024-11-16T21:43:02.053699Z

Ah, it works better if I swap the order...

seancorfield 2024-11-16T21:44:08.185329Z

And, I can use dots* to suppress the regular summary, so '[clojure-test dots*]' works pretty well.

seancorfield 2024-11-16T21:44:41.801529Z

(although maybe that wouldn't work with multiple nses?)

👍 1
2024-11-16T21:50:01.361369Z

The reporters are... fairly simple

2024-11-16T21:50:38.978339Z

so there's nothing to prevent what you've seen

2024-11-16T21:51:12.995879Z

the precomposed reporters have pieces that don't step on each others toes

2024-11-16T21:51:48.342249Z

clojure-test isn't really composable like that because it's operating on all of levels instead just one level

2024-11-16T21:53:36.193499Z

i could split it into discrete pieces and make it composable too, just didn't think of it

2024-11-16T21:56:16.742839Z

dots* merely prints periods and Fs and parentheses, nothing else. so if you use it along with another reporter that operates on the same suite result types, then they'll clash as you saw

2024-11-16T21:58:29.204679Z

i'll write up some documentation/a spec for how the suite results and reporters works

2024-11-16T22:03:12.241569Z

there are some tracking issues so i don't forget any of this when i'm on my computer next week

2024-11-16T22:05:21.122609Z

if you've written modular code, you're welcome to open a PR to add -X or whatever other changes you've worked on for your test runner

seancorfield 2024-11-16T22:18:13.333369Z

The -X stuff was already in Cognitect's runner: cognitect.test-runner.api just wraps the main test function that takes an options map, that is also called from -main after CLI option processing.

seancorfield 2024-11-16T22:23:15.406109Z

All I did was add the mapping for :outputs to :output to pass through 🙂

👍 1
2024-11-19T03:26:20.128819Z

okay, having looked at the code and thought about it a bit, i think my intention with :output vs :reporter was that :output is the raw "input" from the cli, and :reporter is the resolved&combined function(s)

seancorfield 2024-11-19T03:27:08.182049Z

I'm okay with the status quo at this point. I was just curious about the thinking behind it 🙂

👍 1
2024-11-19T03:33:16.343439Z

let me know if that might break your code

seancorfield 2024-11-19T03:34:39.842019Z

As I said in the ticket related to that, if you change it in any way, it'll break both of my test runners 🙂

🥲 1
2024-11-19T03:34:57.216619Z

now ->config consumes :output and produces :reporter. i can open a PR to either/both

2024-11-19T03:35:00.307239Z

i don't mind doing that work

2024-11-19T03:35:19.549429Z

better to fix this inconsistency before more people rely on it

seancorfield 2024-11-19T03:36:48.951339Z

I get the desire for consistency -- either :output all the way through or :reporter all the way through. The current swapping is the problematic thing that each test runner has to handle -- so not having the swapping is a good thing.

seancorfield 2024-11-19T03:37:06.933479Z

Make the change, and I'll just update my runners...

2024-11-19T03:37:30.935319Z

"all the way through" as in, internal to lazytest?

seancorfield 2024-11-19T03:39:08.475549Z

The problem as it stands is that you have "internal" machinery that switches between :output -- which all test runners would have to handle -- and :reporter which your internal code uses, and which the test runners probably have to interact with?

2024-11-19T03:41:16.844569Z

"the test runners"? lazytest is the test runner. or do you mean something else?

2024-11-19T03:42:15.490059Z

i guess another library could (kaocha-style) write their own test running logic operating on the data structures that lazytest creates.

seancorfield 2024-11-19T03:42:18.201549Z

My fork of Cognitect's test-runner and my Polylith test runner.

seancorfield 2024-11-19T03:42:52.052189Z

For consistency with your public API, those need to accept :output or --output and interact with your lazytest.repl API

2024-11-19T03:44:07.372619Z

those call into lazytest, which performs the running and printing/reporting. ideally, they wouldn't have to know about :reporters, they would give lazytest a list of strings or symbols in :output , it would transform those strings/symbols into functions references and then use them to perform the reporting.

2024-11-19T03:44:44.530579Z

having discussed this, i see that the logic in --output is not ideal and should live somewhere else, as you've had to duplicate it in your test-runner

seancorfield 2024-11-19T03:45:51.771319Z

If lazytest.repl/* accept {:output ...} and all the processing is done internally, that cleans up stuff for any runners that call into you.

👍 1
2024-11-19T03:47:17.799859Z

cool, I'll move that logic over so :output is merely a list of symbols

seancorfield 2024-11-19T03:48:58.636009Z

:output dots and :output lazytest.reporters/dots -- or passing a vector of symbols -- should both be acceptable. All the transformation to :reporter functions should happen internally, i.e., inside the lazytest.repl/* functions or any other public API pieces.

2024-11-19T03:49:33.584559Z

yep, agreed

seancorfield 2024-11-19T03:50:09.751009Z

But, like I say, the status quo "works" -- it's just more work for runners to call into your code. And changing it means breaking my two "prerelease" runners but that's okay. We're all in prerelease right now 🙂

❤️ 1
2024-11-19T03:50:38.257539Z

a generous perspective!

seancorfield 2024-11-19T03:52:34.879849Z

Keep me posted...

seancorfield 2024-11-19T03:53:15.902039Z

I have a branch at work with all this speculative LazyTest work on it... I'm looking forward to merging that so I can start using LazyTest on master there 🙂

😍 1
seancorfield 2024-11-19T04:21:11.688719Z

To get a sense of what I'm talking about, here's the Polylith runner, dealing with LazyTest options: https://github.com/seancorfield/polylith-external-test-runner/blob/main/bases/external-test-runner-cli/src/org/corfield/external_test_runner_cli/main.clj#L102-L125

seancorfield 2024-11-19T04:22:47.129959Z

And here's the Cognitect runner, doing the same thing: https://github.com/seancorfield/test-runner/blob/master/src/cognitect/test_runner.clj#L78-L91

seancorfield 2024-11-19T04:24:55.472019Z

This reflects your use of :id in the CLI and the output/reporter mapping.

2024-11-19T04:43:34.152229Z

lazy-is-test? is funny

seancorfield 2024-11-19T04:45:51.537509Z

You think it should be is-lazy-test? 🙂 All the vars are lazy-* 🙂

2024-11-19T04:46:37.111549Z

hah no, it's genuinely a funny turn of phrase

2024-11-19T04:47:01.052609Z

sounds like how it feels to speak another language

2024-11-19T04:47:20.829739Z

i didn't go as fast as i hoped so finishing this will have to wait until tomorrow

👍🏻 1