I haven't yet written any property-based tests. I would like to investigate using them, but haven't so far
property-based tests are interesting, but often I find that I they simply cause me to re-implement something in a different way and test that both implementations generate the same results given equally spec-conformant inputs
which can seem wasteful, but might be a good "laying-bare" of what testing actually is...
that is a very keen insight
much of the stuff I've recently tested would require a non-trivial generator to make the inputs as internally consistent as my hand-crafted data
yeah, and crafting that generator would probably be a long way towards reimplementing your core logic (i'm guessing)
precisely
For me, tests are most useful for testing the edges of a pure data model.
@nate and I end up with a lot of simulation style logic, so we have to handle different events that affect the state. Itβs all a pure reducing-style data model.
The functions take the state and an event and return the new state.
Like what we talked about in our first couple of episodes on Tic Tac Toe.
Tests are great to ensure certain properties are preserved by the state transforms.
Yeah, that all makes sense to me, I think. It can be a fine line not crossing those edges and ending up testing the database/API on the other side of that line though.
but I think you're right that the edges are the place to look for where testing might be valuable, or particularly hairy blobs of logic (pure functions)
i've been working with someone who's been telling me that we write tests when we can't understand something, so we should probably just understand it better
Agreed. Tests are a tool to make sure code keeps on working, not to understand it. Fiddle code is a great tool for understanding code.
on the topic of rich comments containing tests, i have been using this a bit: https://github.com/sogaiu/alc.x-as-tests one can put simple tests within rich comments like this:
(comment
(- 1 1)
;; => 0
,)
there is a "runner" mode which can execute these tests@sogaiu That's neat! I could see that being useful for simple tests or getting some tests going quickly. Do you use code folding in your development environment? One of the reasons why I created separate "fiddle" files was to get the non-production code into its own place.
This is interesting. Reminds me of Stuart Halloway's https://github.com/cognitect-labs/transcriptor
OMG. I just learned how I could use commas to keep that last paren on a separate line!!! π
ah, that keeps it from jumping up to after 1)
?
@neumann indeed i do use code-folding for comment blocks when using emacs. still trying to get that to work well in neovim but haven't had much luck there π fwiw, in emacs i do something like:
(add-hook 'clojure-mode-hook
(lambda ()
(hs-minor-mode)
(setq hs-hide-comments-when-hiding-all nil)
(setq hs-block-start-regexp "\\s(comment")))
@nate yes, this definitely takes inspiration from stuart halloway's transcriptor. i don't know if you've taken a look at mal, but i just noticed in the last few days that its test files do something similar.
@genekim i learned about the "door stop" technique in #parinfer -- though there folks were using other constructs such as []
to achieve the same end.
i have been collecting good uses for the comma in clojure -- it appears it's got more to it than at first glance.
this particular use of "preventing the editor from moving things around" i also use for formatting part of cond
forms and a few other places.
@neumann ah i forgot to mention -- one of my ulterior motives is to try to get simple / illustrative uses to live close to definitions. so i decided to try having the examples / tests live in the same file as the definitions. i'm not trying to have a comprehensive testing system -- it's supposed to be light and informative. geared toward explorative phases of development. i wrote a version for the janet programming language first before making a port to clojure. in both implementations, separate files are generated containing tests and these can be used as a starting point for more traditional testing if desired.
@sogaiu I have folding working in neovim. I'll dig up the proper config bits when I'm at my terminal again.
@nate wow, that'd be great! looking forward to it :)
@sogaiu I use https://github.com/gberenfield/cljfold.vim, with this in my vimrc:
let g:clojure_foldwords = "def,defn,defmacro,defmethod,defschema,defprotocol,defrecord"
@nate thanks! i gave that a try using "comment" as the value. unfortunately, the fold somehow seems to "swallow" defns that follow comment blocks. fwiw, here is a relatively minimal section of code that demos it here:
(ns my.ns)
(comment
(+ 1 1)
;; =>
)
(defn my-fn
[]
:my-value)
any ideas about this?
(it also seems to match on "comment-block?" which by sheer coincidence happened to be in the file i tested.)interesting
perhaps put another new line between the end comment paren and the defn?
I've found the cljfold to be a little eager sometimes
the extra line did it! thanks π on a side note, i've been looking at nvim-treesitter recently. they seem to have plans for some folding, so perhaps there will be other options before long.
indeed
for any interested parties, i jotted down some of the situations i've found the comma to be useful in: https://gist.github.com/sogaiu/d8d2b9765bef37f645211d4d5df1d7c8 happy to hear about other uses too :)
@sogaiu I like your idea of putting illustrative uses of a function near to the function. That is indeed handy. @nate is definitely more hooked on code folding than I am, but I can see how folding helps to eliminate some of the visual noise associated with mixing the function code and the example code.
i haven't found anything other than folding so far, but perhaps there are other alternatives (or will be at some point). at the moment i'm happy at least this option exists π on a side note, i've also experimented with applying folding to long strings such as docstrings. i'm usually grateful for docstrings those but also find that those can interfere with my code reading process sometimes.