testing

Testing tools, testing philosophy & methodology...
bringe 2018-06-02T19:23:40.000088Z

I'm just getting started with unit testing in clojure (I've done some in JS and C#) and I'm wondering about something I'm not quite sure how to phrase. So in FP we build small pure functions and other functions build on those, etc. So I'm wondering if our tests should call the chain of functions we also have tests for in creating the expected value, or if the expected value should always be the output of those sub functions. Let me give an example of what I'm working with. One moment.

bringe 2018-06-02T19:27:13.000077Z

Now for the second, do I make the expected value the entire output (map) of calling build-get-request or do I call build-base-request and merge the added key value pairs onto it to make the expected value or do I explicitly give it the entire expected output? Not sure if I'm being clear...

seancorfield 2018-06-02T19:30:21.000032Z

To be honest, these are small enough and simple enough that I probably wouldn't bother writing unit tests for them.

bringe 2018-06-02T19:31:06.000022Z

Well, I have more complex cases that build on those.

seancorfield 2018-06-02T19:31:35.000061Z

I might write specs for the data, tho' (and then possibly a couple of property-based tests based on the functions).

bringe 2018-06-02T19:32:41.000092Z

I see. I'll do more reading about property-based tests as I'm new to clojure testing in general. Btw, thanks for your work on expectations. 👍

seancorfield 2018-06-02T19:32:53.000111Z

Glad you like it 🙂

bringe 2018-06-02T19:33:11.000014Z

Much better output for failures

seancorfield 2018-06-02T19:34:53.000020Z

Yes, unfortunately I've had to sacrifice some of that with the clojure.test integration in Expectations. Hoping to bring it back at some point. But tooling, such as #cursive has a lot of expectations of clojure.test output so I'm still hammocking some of that...

seancorfield 2018-06-02T19:36:44.000069Z

Going to back to your comment about "small pure functions" -- that's why a lot of the small stuff in Clojure really doesn't need tests: many of the functions are very simple and obviously correct by inspection.

dottedmag 2018-06-02T19:39:29.000090Z

There are many ways to write correct-by-inspection-but-horribly-wrong-in-a-corner-case functions.

dottedmag 2018-06-02T19:39:34.000056Z

Especially dealing with numbers.

seancorfield 2018-06-02T19:41:46.000097Z

@dottedmag Fair point, and with actual computation, yes, I'd want at least some boundary tests or property tests.

seancorfield 2018-06-02T19:44:20.000105Z

@brandon.ringe Since you're using Expectations, I'd suggest something like:

(expect (more-of {:keys [url] :as data}
                 {:method "GET" :accept :json :as :json} (in data)
                 string? url)
        (from-each [url ["<http://foo.com>" "<https://google.com>"]]
          (build-get-request url)))
as a more general test

bringe 2018-06-02T19:45:05.000010Z

I see.

seancorfield 2018-06-02T19:45:33.000012Z

That gets you closer to what a property-based test, using test.check, might look like: isolate the invariant part from the rest.

seancorfield 2018-06-02T19:46:57.000021Z

If you had generatable specs for method and URL, you could use s/exercise to generate random, but compliant, test data as a next step.

seancorfield 2018-06-02T19:48:06.000135Z

(overkill for these simple functions but steps toward property-based testing for more complex stuff)

bringe 2018-06-02T19:51:13.000101Z

Interesting. I have not even gotten into spec yet. This is my first clojure project. I have much to learn.

seancorfield 2018-06-02T19:53:15.000057Z

"Always Be Learning" 🙂

👍 1
seancorfield 2018-06-02T19:53:40.000075Z

I started learning Clojure back in 2010 and have been using it in production since 2011 -- and I'm forever learning new stuff!