Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Accelerating the Agent Economy

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    Ramblurr

    clojure-test-check

    Ramblurr/clojure-test-check
    Coding

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Property-based testing with clojure.test.check. Use when writing generative tests, creating custom generators, or debugging shrinking behavior...

    SKILL.md

    test.check

    Property-based testing generates random test data to verify properties hold across many inputs. Instead of specific test cases, define universal properties.

    Core Pattern

    (require '[clojure.test.check :as tc]
             '[clojure.test.check.generators :as gen]
             '[clojure.test.check.properties :as prop])
    
    (def my-property
      (prop/for-all [v (gen/vector gen/small-integer)]
        (= (count v) (count (reverse v)))))
    
    (tc/quick-check 100 my-property)
    ;; => {:result true, :pass? true, :num-tests 100, ...}
    

    clojure.test Integration

    (require '[clojure.test.check.clojure-test :refer [defspec]])
    
    (defspec sort-is-idempotent ;; 100 optional  iterations value here
      (prop/for-all [v (gen/vector gen/small-integer)]
        (= (sort v) (sort (sort v)))))
    

    Important! Prefer NOT to supply an iterations, prefer the framework defaults

    Essential Generators

    Generator Produces
    gen/small-integer Integers bounded by size
    gen/large-integer Full range integers
    gen/nat Non-negative integers
    gen/boolean true/false
    gen/string Strings
    gen/keyword Keywords
    (gen/vector g) Vectors of g
    (gen/tuple g1 g2) Fixed heterogeneous vectors
    (gen/elements coll) Random element from coll
    (gen/one-of [g1 g2]) Choose generator randomly

    See references/cheatsheet.md for complete generator reference.

    Generator Combinators

    fmap - Transform generated values:

    (gen/fmap sort (gen/vector gen/small-integer))  ; sorted vectors
    (gen/fmap set (gen/vector gen/nat))             ; sets from vectors
    

    such-that - Filter values (use sparingly, only for likely predicates):

    (gen/such-that not-empty (gen/vector gen/boolean))
    

    bind - Chain generators (value from first determines second):

    (gen/bind (gen/not-empty (gen/vector gen/small-integer))
              #(gen/tuple (gen/return %) (gen/elements %)))
    

    let - Macro combining fmap/bind:

    (gen/let [a gen/nat
              b gen/nat]
      {:sum (+ a b) :a a :b b})
    

    Custom Record Generators

    (defrecord User [name id email])
    
    (def user-gen
      (gen/fmap (partial apply ->User)
                (gen/tuple gen/string-alphanumeric
                           gen/nat
                           (gen/fmap #(str % "@example.com") gen/string-alphanumeric))))
    

    Recursive Generators

    (def json-like
      (gen/recursive-gen
        (fn [inner] (gen/one-of [(gen/list inner)
                                 (gen/map gen/keyword inner)]))
        (gen/one-of [gen/small-integer gen/boolean gen/string])))
    

    Shrinking Failures

    When a test fails, test.check automatically shrinks to minimal failing case:

    ;; Fails on vectors containing 42
    (tc/quick-check 100
      (prop/for-all [v (gen/vector gen/small-integer)]
        (not-any? #{42} v)))
    ;; :fail [[-35 -9 42 8 31 ...]]  <- original failure
    ;; :shrunk {:smallest [[42]]}    <- minimal case
    

    Critical Pitfalls

    Avoid gen/bind when gen/fmap suffices - bind hampers shrinking:

    ;; Bad: shrinks poorly
    (gen/let [n (gen/fmap #(* 2 %) gen/nat)]
      (gen/vector gen/large-integer n))
    
    ;; Good: shrinks well
    (gen/fmap #(cond-> % (odd? (count %)) pop)
              (gen/vector gen/large-integer))
    

    Use gen/large-integer for real integer testing - small-integer/nat cap at ~200.

    Run at least 100 tests - Size cycles through 0-199, fewer tests means poor coverage.

    Don't use such-that for unlikely predicates - Will timeout. Use fmap to construct valid values instead.

    See references/advanced.md for sizing/shrinking details.

    Common Property Patterns

    Roundtrip: (= x (decode (encode x))) Idempotence: (= (f x) (f (f x))) Invariant preservation: (= (count v) (count (sort v))) Commutativity: (= (f a b) (f b a)) Model comparison: (= (my-impl x) (reference-impl x))

    See references/examples.md for generator recipes.

    Recommended Servers
    Postman
    Postman
    OpenZeppelin
    OpenZeppelin
    EduBase
    EduBase
    Repository
    ramblurr/nix-devenv
    Files