mount

onetom 2016-06-13T13:53:10.000038Z

is there any good example how to use mount (or mount-lite too, i guess) with some test framework? im actually trying to figure out how intellij's repl based testing is supposed to work and how to make it a smooth experience with mount-lite.

tolitius 2016-06-13T14:10:07.000039Z

@onetom: are you looking for something specific? Usually these are used when testing: https://github.com/tolitius/mount#composing-states mostly swap and only. The idea is you would start a portion of an app that you want to test, and swap the real external resources with a mocked ones (whether it is a function or another state..)

onetom 2016-06-13T14:55:45.000041Z

im looking for an example of how is it done. via some fixtures, or macros like with-components in https://github.com/stuartsierra/component/issues/6? what would i do with a datomic db for example? create a new one in every test namesapce and transact the schema into it? how does it play together with intellij's "Run test under caret in REPL" & "Run tests in current NS in REPL" features?

onetom 2016-06-13T14:57:43.000043Z

or there is eftest (https://github.com/weavejester/eftest) which is also used by https://github.com/metosin/boot-alt-test which allows parallel test runs. is there a way to use them with mount/mount-lite, since they only allow one active state at a time?

onetom 2016-06-13T15:08:01.000047Z

but where do i put this within a test name space?

onetom 2016-06-13T15:08:30.000048Z

what happens if there is an exception in the ;; testing.. checking "sms-ch" channel part? the (mount/stop) bit wouldn't run, then, no?

onetom 2016-06-13T15:10:04.000050Z

if i wrap my tests into try forms, then the tests start to be really verbose/noisy

onetom 2016-06-13T15:18:14.000051Z

if i start a REPL, then i would have a real system running in it by default. but if im running tests with intellij via REPL and those tests would have (mount/start-with {...some-mocks...}), then how am i supposed to get back my real system afterwards?

tolitius 2016-06-13T17:22:47.000054Z

let's start from the last question and work backwards, to make sure I follow

onetom 2016-06-13T17:23:07.000055Z

ok, thanks

tolitius 2016-06-13T17:23:12.000056Z

> how am i supposed to get back my real system afterwards? what do you mean get back to the real system?

tolitius 2016-06-13T17:23:30.000057Z

usually: "you ran the test, you done"

tolitius 2016-06-13T17:24:01.000058Z

the real system / app exists independently from the tests

onetom 2016-06-13T17:24:23.000059Z

nope

tolitius 2016-06-13T17:24:33.000060Z

i.e. I usually develop an app in one REPL, and run tests continuously in another

onetom 2016-06-13T17:24:45.000061Z

i have this at the moment:

(deftask dev
  "Backend in development mode"
  []
  (comp
    (repl :server true)
    (watch)
    (system.boot/system
      :sys #'sys/dev
      :auto true
      :files ["sys.clj" "core.clj"])))

onetom 2016-06-13T17:25:24.000062Z

so i can have access to the running real system via an nREPL client

onetom 2016-06-13T17:25:40.000063Z

by real system, i mean nothing is mocked out

onetom 2016-06-13T17:26:04.000064Z

my nREPL client is running from intellij

tolitius 2016-06-13T17:26:12.000065Z

right, so here in dev you have nothing mocked out

onetom 2016-06-13T17:26:18.000066Z

yes

tolitius 2016-06-13T17:26:31.000067Z

are you trying to run the real app and the tests within the same REPL?

onetom 2016-06-13T17:26:37.000068Z

yes

onetom 2016-06-13T17:27:00.000069Z

since intellij supports this "Run test under caret in REPL"

onetom 2016-06-13T17:27:11.000070Z

which suggests that's a normal thing to do...

onetom 2016-06-13T17:27:23.000071Z

sounds very clojure-y indeed

tolitius 2016-06-13T17:28:20.000072Z

I usually run tests in the separate REPL: i.e. boot watch speak test. I like it better, since things / components / app pieces are decoupled from compilation differences / configs

onetom 2016-06-13T17:28:59.000073Z

that's how i was doing it in the past with midje too

onetom 2016-06-13T17:29:15.000074Z

but it has no interop with intellij 😞

onetom 2016-06-13T17:30:23.000075Z

which does have a quite nice clojure.test integration and it's super fast to just run specific tests and it automatically reloads the necessary changed files too

tolitius 2016-06-13T17:31:09.000076Z

I never liked running tests and dev within the same REPL. at the times I used leinigen it was a no brainer, since it just works the best in two separate REPLs, "lein does not clean well" especially if new things are added in project.clj. with boot clean is no longer the problem, but boot watch speak test is just really niice, since it just works for you in a different REPL with no dev cluttering.

tolitius 2016-06-13T17:32:21.000077Z

I only use IntelliJ for Java and Scala (I use VIM for Clojure), so I would appreciate if someone with Cursive knowledge jump in, but.. "you can't start two REPLs with Cursive"?

onetom 2016-06-13T17:33:16.000079Z

i was also trying to run boot watch test in a terminal within intellij, but if i close the project window, boot keeps running in the background and i can't access it anymore (have to kill it manually)

onetom 2016-06-13T17:34:12.000080Z

well, you can't start 2 nREPLs because there is only one .nrepl-port file....

onetom 2016-06-13T17:34:36.000081Z

plus not sure how would i tell intellij which repls should it send the tests to...

onetom 2016-06-13T17:35:19.000082Z

and let's not forget that most people are not RAM millionaires either. running 2 repls is not nice at all...

tolitius 2016-06-13T17:35:41.000083Z

I just did start two REPLs in Cursive, and when I did "File => Close Project" it asked me twice whether I wanted to stop the REPL, you don't have the same behavior?

tolitius 2016-06-13T17:36:08.000084Z

> not sure how would i tell intellij which repls should it send the tests to you don't, it is in your boot test src

onetom 2016-06-13T17:36:14.000085Z

we already have a datomic transactor, a frontend project with cljs compiler & cljs-repl aaaand a backend process

tolitius 2016-06-13T17:36:21.000086Z

you only have one REPL that runs all the tests

tolitius 2016-06-13T17:36:56.000087Z

> a datomic transactor, a frontend project with cljs compiler & cljs-repl aaaand a backend process is this the same project?

onetom 2016-06-13T17:37:15.000088Z

closing the repls is not the problem. closing the terminals which run boot watch test are the problem

onetom 2016-06-13T17:38:09.000089Z

no. these are 3 JVMs. i was just mentioning it, regarding you advice to run an extra one just for the tests

onetom 2016-06-13T17:38:33.000090Z

and no, frontend and backend are 2 different boot processes already (in separate source repos too)

tolitius 2016-06-13T17:38:57.000091Z

so you have 3 REPLs opened at the same time, or how do you work with it?

onetom 2016-06-13T17:39:20.000093Z

the datomic transactor doesnt have a repl

onetom 2016-06-13T17:40:07.000094Z

so i have 2 intellij projects open 1. frontend (hoplon) 2. backend (ring app via boot-jetty)

onetom 2016-06-13T17:40:35.000095Z

i run a boot dev like i showed above to have a REPL server for the backend

onetom 2016-06-13T17:40:53.000096Z

i run it from iTerm

onetom 2016-06-13T17:41:04.000097Z

then i run an nREPL client from intellij which connects to this backend REPL

onetom 2016-06-13T17:41:37.000099Z

for the frontend i dont really use a repl much yet

onetom 2016-06-13T17:42:30.000100Z

then in a test namespace i can just say cmd-shift-a "run tests in current NS in REPL"

onetom 2016-06-13T17:43:21.000101Z

and it sends the tests to the boot dev process via the nREPL client but 1st reloads the modified files also via the REPL

onetom 2016-06-13T17:43:54.000102Z

as documented here: https://cursive-ide.com/userguide/testing.html

onetom 2016-06-13T17:45:16.000104Z

(im working on a green field project, that's why im trying to revise my workflow and get away from component and try use mount or mount-lite instead)

tolitius 2016-06-13T17:45:51.000105Z

I see, but then why not just run tests continuously vs. say cmd-shift-a "run tests in current NS in REPL"?

tolitius 2016-06-13T17:46:12.000106Z

(in the separate REPL)

onetom 2016-06-13T17:46:48.000107Z

because clojure.test doesn't support 1. re-running only the last failing tests 2. running only specific tests (so i can get immediate feedback)

onetom 2016-06-13T17:48:30.000108Z

3. how would i run the separate REPL? start another boot nREPL server process? and open an nREPL client to it which I would setup as a second Run configuration in IntelliJ on some hardwired port?

dm3 2016-06-13T17:52:36.000109Z

so you have an app running in REPL

dm3 2016-06-13T17:53:10.000110Z

and also want to run tests which redef the states?

onetom 2016-06-13T17:55:41.000111Z

yup

dm3 2016-06-13T17:56:02.000112Z

then you either need a fixture to save the app state before tests/restore after

dm3 2016-06-13T17:56:20.000113Z

maybe could use Yurt for that?

onetom 2016-06-13T17:56:20.000114Z

at least thats how i understand cursive's test support is supposed to work

dm3 2016-06-13T17:56:27.000115Z

yep, probably works that way

onetom 2016-06-13T17:57:26.000116Z

it would be great if it could send stuff into a test pod of course, but unfortunately i have no idea what cursive is really doing in the background...

dm3 2016-06-13T17:58:14.000117Z

I'd think it just sends a form to the repl

onetom 2016-06-13T17:58:48.000118Z

maybe we should interrogate mr fleming on that end but im not sure it worth harassing him, since this issue doesn't seem to move forward: https://github.com/cursive-ide/cursive/issues/692

dm3 2016-06-13T17:59:56.000120Z

he might be able to explain if it's possible to make a REPL connection for test evaluation

dm3 2016-06-13T18:00:15.000122Z

separately from the "main" project's REPL connection

dm3 2016-06-13T18:00:31.000123Z

I doubt such a feature already exists

onetom 2016-06-13T18:05:27.000124Z

maybe we should ask him how does he manages state, so this feature is useful for him...

onetom 2016-06-13T18:07:32.000125Z

looking into yurt in the mean time. i remember i read about it before but probably just before sleep... http://www.dotkam.com/2016/01/31/yurt-mounts-local-real-estate/ > 504 Gateway Time-out

onetom 2016-06-13T18:30:00.000127Z

@tolitius: you said: > with boot clean is no longer the problem, but boot watch speak test is just really niice, since it just works for you in a different REPL with no dev cluttering. and in the yurt-mounts-local-real-estate article: > The way I do it today is simply running: >

boot watch speak test
> in a different REPL. but how boot watch speak test is a REPL? you mean different JVM process?

tolitius 2016-06-13T18:31:08.000128Z

right, just running boot watch speak test in a different terminal window

tolitius 2016-06-13T18:31:22.000129Z

which is a different JVM, yes

onetom 2016-06-13T18:33:03.000130Z

ok, thx for the clarification

tolitius 2016-06-13T18:33:50.000131Z

sure, I wish I could help you more with IntelliJ's setup, but I don't use it

onetom 2016-06-13T18:36:53.000132Z

no worries, i really appreciate you spent your time on enlightening me!

onetom 2016-06-13T18:37:39.000134Z

and of course thanks for mount and yurt too! 🙂

tolitius 2016-06-13T18:47:50.000135Z

sure, always welcome

onetom 2016-06-13T19:47:39.000139Z

as i was going thru the mount tests and also you example apps and i see this pattern everywhere: https://github.com/tolitius/stater/blob/master/smsio/test/app/test/app.clj#L14-L21 there is no exception handling for proper cleanup, like this:

(try
  (mount/start)
  ...
  (is ...)
  (finally
    (mount/stop))
without such wrapping one mistake can force you to restart the test process, because there will be a web-server started which would cause subsequent tests to fail with "Address already in use" errors, even after you fix the mistake.

onetom 2016-06-13T19:51:35.000141Z

just provide an extra parameter to http/post on L19 and you will see the next test (`swapping-with-state`) will fail too

onetom 2016-06-13T19:53:38.000142Z

removing the extra param should make the tests pass again, but instead of 1 error, you will get 2 and wading through the reams of log messages, you can discover the "Address already in use" error

onetom 2016-06-13T20:01:03.000146Z

there is this in mount-lite which seems to mitigate the problem without the try-finally block but im not sure it's enough either: https://github.com/aroemers/mount-lite/blob/master/test/mount/lite_test.clj#L21