weavejester / eftest

Fast and pretty Clojure test runner
424 stars 40 forks source link

Datomic db values (and other large potentially-expandable values) produce a horrific console spew if included in test failure data #91

Open TuggyNE opened 1 year ago

TuggyNE commented 1 year ago

Using e.g. Datomic's support for transient in-memory databases in tests, along with test.check's property-based testing and (I strongly suspect) the failure data added by tools like test.chuck's for-all macro produces a perfect storm with eftest. Unlike lein test or other tools (including Calva's REPL), if the output happens to contain a Datomic DB, it will print out all the data in that. Even for a transient DB, that's a staggering amount, thousands of lines.

Representative:

(ns sample-test
  (:require
   [clojure.test.check.clojure-test :refer [defspec]]
   [clojure.test.check.generators :as gen]
   [com.gfredericks.test.chuck.properties :refer [for-all]]
   [datomic.api :as d]))

(defn test-state-db []
  (let [schemas [] ; Concatenation of relevant schemas omitted
        conn-str (str "datomic:mem://" (random-uuid))
        _ (d/create-database conn-str)
        conn (d/connect conn-str)]
    @(d/transact conn schemas)
    (d/db conn)))

(defn db-dependent-gen "Generator notionally based on database value" [db]
  gen/any)

(defspec test-db-things
  (let [base-db (test-state-db)]
    (for-all
     [v1 gen/any ; Something sensible
      :let [txns [] ; Various test-specific transactions based on v1 etc
            post-tx-db (:db-after (d/with base-db txns))]
      v2 (db-dependent-gen post-tx-db)]
     (not= v1 v2))))

The output of lein test :only sample-test/test-db-things is something like this:

FAIL in (test-db-things) (sample_test.clj:19)
expected: {:result true}
  actual: {:shrunk
           {:total-nodes-visited 20,
            :depth 9,
            :pass? false,
            :result false,
            :result-data nil,
            :time-shrinking-ms 8,
            :smallest
            [{v1 [],
              txns [],
              post-tx-db datomic.db.Db@1ac0e28c,
              v2 []}]},
           :failed-after-ms 4,
           :num-tests 1,
           :seed 1679008946391,
           :fail
           [{v1 (),
             txns [],
             post-tx-db datomic.db.Db@97460d9e,
             v2 ()}],
           :result false,
           :result-data nil,
           :failing-size 0,
           :pass? false,
           :test-var "test-db-things"}

Ran 1 tests containing 1 assertions.
1 failures, 0 errors.

The output of eftest for that is in the hundreds of kilobytes.

Calva solved a very similar problem without, I believe any Datomic-specific special-casing.