GithubHelp home page GithubHelp logo

test.check's Introduction

test.check

test.check is a Clojure property-based testing tool inspired by QuickCheck. The core idea of test.check is that instead of enumerating expected input and output for unit tests, you write properties about your function that should hold true for all inputs. This lets you write concise, powerful tests.

test.check used to be called simple-check.

Releases and Dependency Information

Leiningen

[org.clojure/test.check "0.5.9"]

Maven

<dependency>
  <groupId>org.clojure</groupId>
  <artifactId>test.check</artifactId>
  <version>0.5.9</version>
</dependency>

If you'd like to try a SNAPSHOT version, add the sonatype repository to your project.

Version numbers

test.check version numbers start where simple-check left off: 0.5.7.

Documentation

Migrating from simple-check

In order to migrate from simple-check to test.check, you'll need to do two things:

  • Update project.clj

    In your project.clj replace [reiddraper/simple-check "0.5.6"] with [org.clojure/test.check "0.5.9"] (note: your version numbers may be different).

  • Update namespace declarations

    Update your namespaces: simple-check.core becomes clojure.test.check (note the dropping of 'core'). Everything else you can simply replace simple-check with clojure.test.check. Let's make it easy:

    find test -name '*.clj' -print0 | xargs -0 sed -i.bak \
    -e 's/simple-check.core/clojure.test.check/' \
    -e 's/simple-check/clojure.test.check/'

    Review the updates.

Examples

Let's say we're testing a sort function. We want to check that that our sort function is idempotent, that is, applying sort twice should be equivalent to applying it once: (= (sort a) (sort (sort a))). Let's write a quick test to make sure this is the case:

(require '[clojure.test.check :as tc])
(require '[clojure.test.check.generators :as gen])
(require '[clojure.test.check.properties :as prop])

(def sort-idempotent-prop
  (prop/for-all [v (gen/vector gen/int)]
    (= (sort v) (sort (sort v)))))

(tc/quick-check 100 sort-idempotent-prop)
;; => {:result true, :num-tests 100, :seed 1382488326530}

In prose, this test reads: for all vectors of integers, v, sorting v is equal to sorting v twice.

What happens if our test fails? test.check will try and find 'smaller' input that still fails. This process is called shrinking. Let's see it in action:

(def prop-sorted-first-less-than-last
  (prop/for-all [v (gen/not-empty (gen/vector gen/int))]
    (let [s (sort v)]
      (< (first s) (last s)))))

(tc/quick-check 100 prop-sorted-first-less-than-last)
;; => {:result false, :failing-size 0, :num-tests 1, :fail [[3]],
       :shrunk {:total-nodes-visited 5, :depth 2, :result false,
                :smallest [[0]]}}

This test claims that the first element of a sorted vector should be less-than the last. Of course, this isn't true: the test fails with input [3], which gets shrunk down to [0], as seen in the output above. As your test functions require more sophisticated input, shrinking becomes critical to being able to understand exactly why a random test failed. To see how powerful shrinking is, let's come up with a contrived example: a function that fails if its passed a sequence that contains the number 42:

(def prop-no-42
  (prop/for-all [v (gen/vector gen/int)]
    (not (some #{42} v))))

(tc/quick-check 100 prop-no-42)
;; => {:result false,
       :failing-size 45,
       :num-tests 46,
       :fail [[10 1 28 40 11 -33 42 -42 39 -13 13 -44 -36 11 27 -42 4 21 -39]],
       :shrunk {:total-nodes-visited 38,
                :depth 18,
                :result false,
                :smallest [[42]]}}

We see that the test failed on a rather large vector, as seen in the :fail key. But then test.check was able to shrink the input down to [42], as seen in the keys [:shrunk :smallest].

To learn more, check out the documentation links.

clojure.test Integration

The macro clojure.test.check.clojure-test/defspec allows you to succinctly write properties that run under the clojure.test runner, for example:

(defspec first-element-is-min-after-sorting ;; the name of the test
         100 ;; the number of iterations for test.check to test
         (prop/for-all [v (such-that not-empty (gen/vector gen/int))]
           (= (apply min v)
              (first (sorted v)))))

Release Notes

Release notes for each version are available in CHANGELOG.markdown. Remember that prior to version 0.5.7, test.check was called simple-check.

See also...

Other implementations

Papers

Contributing

We can not accept pull requests. Please see CONTRIBUTING.md for details.

License

Copyright © 2014 Rich Hickey, Reid Draper and contributors

Distributed under the Eclipse Public License, the same as Clojure.

test.check's People

Contributors

alandipert avatar alexbaranosky avatar also avatar cemerick avatar ericnormand avatar gfredericks avatar hypirion avatar johnwalker avatar miner avatar puredanger avatar reiddraper avatar seliopou avatar si14 avatar tcrayford avatar ztellman avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.