TDD and lein

348 views
Skip to first unread message

andrea crotti

unread,
Jan 8, 2015, 6:32:44 AM1/8/15
to clo...@googlegroups.com
Hi guys,

I'm starting to use Clojure a bit more seriously, I knew already Lisp a
bit and Haskell, in plus I've been using Emacs for a long time so
luckily it's not as hard, and it's a lot of fun.

I'm using Emacs + Cider for development and it works wonderfully,
however I have a few problems/questions trying to do TDD.

1. Isn't it possible to make Lein more verbose?

It's often quite slow and it would be nice to know what is going
on, I can stand the slowness but at least tell me something :D

2. When is exactly that I need to run again "lein test" (which is
painfully slow) and when just rerunning the tests from the same REPL
suffice?

I thought only when changing dependencies, but I had different
experiences so I'm not too sure about the rule.

And what command exactly is Cider triggering when I run the tests?
It would be nice to be able to see somewhere more information like:
- compiling file x
- running tests for y with command z

3. Does incremental compilation work well/make sense for Clojure?
I found something but the fact that it's not done straight away in
Leiningen makes me think it's maybe not much used?

Thanks a lot, and congratulations to all the developers for the great language!

Robin Heggelund Hansen

unread,
Jan 8, 2015, 6:41:08 AM1/8/15
to clo...@googlegroups.com
The reason lein is initially slow, has to do with Clojures bootstrapping process, which is slow. People tend to avoid starting clojure programs repeatedly, and thus do alot of work from the repl, or using leiningen plugins which keeps running and listens for changes.

Take a look at lein-test-refresh for tdd:


It detects when you change your code, incrementally compiles and re-runs the tests. It runs your tests everytime you save a file :)

Udayakumar Rayala

unread,
Jan 8, 2015, 7:24:50 AM1/8/15
to clo...@googlegroups.com
Not sure if you are doing this, you can run the tests in cider itself. This is much quicker than running "lein test" outside particularly when you are doing TDD. 

I use clojure.test so every deftest method is a function which you can run to see if the test passes or fails. Or you can run run-tests for running all or tests under a namespace.

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Phillip Lord

unread,
Jan 8, 2015, 8:11:32 AM1/8/15
to Udayakumar Rayala, clo...@googlegroups.com

CPU is cheap these days, why not do both?

I tests within CIDER when I want to. But I normally run lein test on
every file change (using a inotify script, but there's probably a nicer
way). This crashes a lot, for instance, when I save a half finished
change, but it also tells me when I have messed up what I think is a
trivial change.

Obviously, I don't do this on laptops running on batteries. But on a
desktop with multi-core and a second screen, it's helpful.

Udayakumar Rayala <uday....@gmail.com> writes:

> Not sure if you are doing this, you can run the tests in cider itself. This
> is much quicker than running "lein test" outside particularly when you are
> doing TDD.
>
> I use clojure.test so every deftest method is a function which you can run
> to see if the test passes or fails. Or you can run run-tests
> <https://clojuredocs.org/clojure.test/run-tests> for running all or tests
--
Phillip Lord, Phone: +44 (0) 191 208 7827
Lecturer in Bioinformatics, Email: philli...@newcastle.ac.uk
School of Computing Science, http://homepages.cs.ncl.ac.uk/phillip.lord
Room 914 Claremont Tower, skype: russet_apples
Newcastle University, twitter: phillord
NE1 7RU

Colin Yates

unread,
Jan 8, 2015, 8:59:59 AM1/8/15
to clo...@googlegroups.com
If you want to automate any "lein X" process then lein auto is the thing to use. However, there are a few runners which will monitor changes and then run the tests whilst maintaining a lein process so they are really quick.

I personally use https://github.com/jakepearson/quickie, just start "lein quickie" in a console and everytime I change something it runs (all|related?) tests.

In terms of when the process must be restarted, a non-exhaustive list I've found is:
 - changing anything in project.clj
 - changing existing defmulti signatures

Hope that helps.

andrea crotti

unread,
Jan 8, 2015, 9:20:56 AM1/8/15
to clo...@googlegroups.com
Ah great that's what I wanted, I'll try later.
Does it give some feedback on what it's compiling and what is going on?

I would use just cider in theory but I had some errors with namespaces
(probably my fault) and more importantly it seemed that it didn't
always recompiled things that were changed (again probably my fault).

So in short only changing dependencies should require a new "lein
test" or "lein deps"?

And this useful plugins do you normally put them in your
./lein/profiles.clj or in every project you have?

thanks a lot

Colin Yates

unread,
Jan 8, 2015, 9:31:07 AM1/8/15
to clo...@googlegroups.com
Not sure if you know about them but the following are great resources for finding libraries:

 - http://www.clojure-toolbox.com/
 - https://github.com/technomancy/leiningen/wiki/Plugins
 - http://clojure-libraries.appspot.com/
 - https://github.com/trending?l=clojure (to keep up with the cool kids ;))

Malcolm Sparks

unread,
Jan 8, 2015, 9:32:32 AM1/8/15
to clo...@googlegroups.com
LISP systems work better when they are continually up-and-running. Take Emacs for example. Clojure systems aren't much different. 

I prefer to think of lein more as a launch tool than a build tool.

I don't think anyone has mentioned it on this thread yet, but lots of people are using Stuart Sierra's component workflow for precisely this reason - you can make changes and see the effects very quickly simply by typing (reset) into the REPL. See https://github.com/stuartsierra/component

For a working example of incremental compilation, see http://modularity.org/templates/dashboard.html - it will recompile your ClojureScript and Less css files incrementally, and can do so because it can keep context between resets. It's possible to add 'test' components which will run your tests after every reset. I don't have any templates demonstrating that yet, but I have seen people do it.

Ashton Kemerling

unread,
Jan 8, 2015, 2:21:44 PM1/8/15
to clo...@googlegroups.com
I've had good luck with lein prism to cut out any annoying lein startup time. Mixed in with cider when I want to run one test works nicely for me. 

https://github.com/aphyr/prism/

--Ashton

Sent from my iPhone

Dave Della Costa

unread,
Jan 9, 2015, 12:21:14 AM1/9/15
to clo...@googlegroups.com
One more suggestion as you mentioned wanting to see more output,
although this may be different from what you were asking--but still
worth knowing about:

https://github.com/pjstadig/humane-test-output

Cheers,

DD

andrea crotti

unread,
Jan 9, 2015, 7:15:29 AM1/9/15
to clo...@googlegroups.com
Thank you all for the great suggestions I'll start using some of these
libraries.

I tried now again with cider and found out what I needed to do.
Apparently if I change any file I have to first do a M-x cider-refresh
and then running the tests will reflect the situation.

Can that not be automated for every save file?
Could be a simple hook on save file that calls that, isn't there
something like this already?

Colin Yates

unread,
Jan 9, 2015, 8:10:07 AM1/9/15
to clo...@googlegroups.com
Hi Andrea, have you checked the doc at
https://github.com/clojure-emacs/cider? It as a bunch of very useful
shortcuts, including the ability to send either eval current buffer,
the current form or the outer most form.
> You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/sIo7SjKpYVU/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages