I've been experimenting with ways to make writing generative integration 
tests a bit easier, and the resultant tests less cluttered with setup code 
and better at expressing their intent. Specifically I wanted to make 
creating and inserting records into a database as part of test setup a lot 
easier and less involved.

I've come up with something I'd appreciate feedback on, as I'm not sure if 
it's a good or a terrible idea! I would normally run a mile from 
introducing complex macros and magic syntax, and this is both of those. 
However I think it does make the tests a lot easier to write and read *once 
you've gotten used to its syntax*.

You can see the code at https://github.com/rsslldnphy/test.calculus - the 
example project can be found in 
https://github.com/rsslldnphy/test.calculus/tree/master/dev/src/example, 
and the test for it in 
https://github.com/rsslldnphy/test.calculus/blob/master/test/example/forums/handlers_test.clj
.

The basic idea is to split the generation of test records from the setting 
up of the relationships between them and then their subsequent insertion 
into the DB, but have all three steps handled for you by a magic (shudder) 
`integration-test` macro. You end up writing tests that look like this:

(tc/use-test-db th/test-db)

(deftest forum-posts-test
  (tc/integration-test "get-posts" 10 ;; uses test.chuck/times for configurable 
number of test runs

    ;; 'fixtures' are specified first. these are records that will be
    ;; generated from user defined generators (specified elsewhere) and 
inserted into the DB before
    ;; the tests are run.
    [:users  [dinesh aamira charlotte shonda hideo]
     :forums [funny-cat-gifs politics clojure-enthusiasts]
     :posts  [my-cat resisting-trump macro-confusion cat-cafes 
parenthesis-overload]]

    ;; 'relationships' follow the fixtures. these trigger the use of
    ;; user-defined functions that set foreign keys/create the join table
    ;; records required to specify the given relationship in the db.
    [:member funny-cat-gifs      dinesh charlotte shonda]
    [:member politics            aamira shonda hideo]
    [:member clojure-enthusiasts dinesh aamira]

    [:author [charlotte funny-cat-gifs]      my-cat]
    [:author [shonda    funny-cat-gifs]      cat-cafes]
    [:author [hideo     politics]            resisting-trump]
    [:author [dinesh    clojure-enthusiasts] macro-confusion]
    [:author [aamira    clojure-enthusiasts] parenthesis-overload]

    ;; 'generators' - any other arbitrary generators that are needed can be
    ;; specified here. these are not really needed for the below test, but are
    ;; just there as an example.
    [x gen/s-pos-int
     y gen/s-pos-int]

    (is (> (+ x y) x))
    (is (> (+ x y) y))

    (is (= (sort-by :post_id [macro-confusion parenthesis-overload])
           (sort-by :post_id (h/get-posts (tc/test-db) clojure-enthusiasts))))))


The keywords in the fixtures section look up generators defined by the user 
- these can be arbitrary test.check generators (in the example project in 
the repo I've used Prismatic Schema, because we haven't yet made the leap 
to clojure.spec where I work... :-)).

The keywords in the relationships section look up simple functions defined 
by the user. You can see examples of both these and the fixtures in the 
example project in the repo at 
https://github.com/rsslldnphy/test.calculus/blob/master/test/example/test/helper.clj

As I say, I'm keen to get feedback. Is this a terrible idea or worth 
pursuing? Are there any pitfalls I should be considering? Does the 
syntax/structure of the integration test setup sort of make sense, or is it 
hopelessly confusing? Any ideas on how to improve it?

Thanks for your time,

Russell

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to