• This repository has been archived on 09/Nov/2017
  • Stars
    star
    162
  • Rank 232,284 (Top 5 %)
  • Language
    Clojure
  • License
    Eclipse Public Li...
  • Created over 14 years ago
  • Updated over 11 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

(archived) New test framework for Clojure

Lazytest

** Not under active development **

** Latest stable release is on the stable branch **

Lazytest: Generic testing backend for Clojure

by Stuart Sierra, http://stuartsierra.com/

Copyright (c) Stuart Sierra, 2010. All rights reserved. The use and distribution terms for this software are covered by the Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can be found in the file LICENSE.html at the root of this distribution. By using this software in any fashion, you are agreeing to be bound by the terms of this license. You must not remove this notice, or any other, from this software.

One Backend, Many Testing Styles

Lazytest aims to be a generic library that can support many different modes and styles of testing. It defines a few generic representations for executable tests (see "Lazytest Internals", below). Any testing code that can be compiled into these representations can take advantage of Lazytest's running and reporting tools.

Getting Started with Leiningen

Note: These instructions require JDK 6.

Copy the sample project in modules/sample-leiningen-project

Put your app sources in src/ and your test sources in test/

Then run:

lein clean
lein deps
java -cp "src:test:classes:lib/*" lazytest.watch src test

And watch your tests run automatically whenever you save a file.

Type CTRL+C to stop.

To run your tests just once and stop, run:

java -cp "src:test:classes:lib/*" lazytest.main src test

Getting Started with Maven

Copy the sample project in modules/sample-maven-project

Put your app sources in src/main/clojure/ and your test sources in src/test/clojure/

Then run:

mvn lazytest:watch

And watch your tests run automatically whenever you save a file.

Type CTRL+C to stop.

To run your tests just once and stop, run:

mvn lazytest:run

Testing with 'deftest'

The lazytest.deftest namespace is a drop-in replacement for the clojure.test library. Each test is a function defined with the deftest macro, making assertions with the is macro:

 (ns examples.readme.deftest
   (:use [lazytest.deftest :only (deftest it thrown? thrown-with-msg?)]))

 (deftest t-addition-with-integers
   ;; arbitrary code may be executed here
   (is (= 4 (+ 2 2)))
   (is (= 7 (+ 3 4))))

Testing with 'describe'

The lazytest.describe namespace mimics the behavior-driven testing style popularized by libraries such as RSpec.

Use the describe macro to create a group of tests. Start the group with a documentation string.

(ns examples.readme.groups
  (:use [lazytest.describe :only (describe it)]))

(describe "This application" ...)

If you put a symbol before (or instead of) the string, the full name of the Var or Class to which that symbol resolves will be prepended to the doc string:

(describe + "with integers" ...)
;; resulting doc string is "#'clojure.core/+ with integers"

Within a describe group, use the it macro to create a single test example. Start your example with a documentation string describing what should happen, followed by an expression to test what you think should be true.

(describe + "with integers"
  (it "computes the sum of 1 and 2"
    (= 3 (+ 1 2)))
  (it "computes the sum of 3 and 4"
    (= 7 (+ 3 4))))

Each it example may only contain one expression, which must return logical true to indicate the test passed or logical false to indicate it failed.

Nested Test Groups

Test groups may be nested inside other groups with the testing macro, which has the same syntax as describe but does not define a top-level Var:

(ns examples.readme.nested
  (:use [lazytest.describe :only (describe it testing)]))

(describe "Addition"
  (testing "of integers"
    (it "computes small sums"
      (= 3 (+ 1 2)))
    (it "computes large sums"
      (= 7000 (+ 3000 4000))))
  (testing "of floats"
    (it "computes small sums"
      (> 0.00001 (Math/abs (- 0.3 (+ 0.1 0.2)))))
    (it "computes large sums"
      (> 0.00001 (Math/abs (- 3000.0 (+ 1000.0 2000.0)))))))

Arbitrary Code in an Example

You can create an example that executes arbitrary code with the do-it macro. Wrap each assertion expression in the lazytest.expect/expect macro.

(ns examples.readme.do-it
  (:use [lazytest.describe :only (describe do-it)]
        [lazytest.expect :only (expect)]))

(describe "Arithmetic"
  (do-it "after printing"
    (expect (= 4 (+ 2 2)))
    (println "Hello, World!")
    (expect (= -1 (- 4 5)))))

The expect macro is like assert but carries more information about the failure. It throws an exception if the expression does not evaluate to logical true.

If the code inside the do-it macro runs to completion without throwing an exception, the test example is considered to have passed.

Focusing on Individual Tests and Suites

The describe, testing, it, and do-it macros all take an optional metadata map immediately after the docstring.

Adding :focus true to this map will cause only that test/suite to be run. Removing it will return to the normal behavior (run all tests).

When using deftest, you can put :focus true metadata on the symbol name of your test:

(deftest ^:focus my-test
  ...)

Generating Random Test Data

The lazytest.random namespace provides functions for generating random input data for your tests.

Lazytest Internals

The smallest unit of testing is a test case, which is a function (see lazytest.test-case/test-case). When the function is called, it may throw an exception to indicate failure. If it does not throw an exception, it is assumed to have passed. The return value of a test case is always ignored. Running a test case may have side effects. The macros lazytest.describe/it and lazytest.describe/do-it create test cases.

Tests cases are organized into suites. A test suite is a function (see lazytest.suite/suite) that returns a test sequence. A test sequence (see lazytest.suite/test-seq) is a sequence, possibly lazy, of test cases and/or test suites. Suites, therefore, may be nested inside other suites, but nothing may be nested inside a test case. The macros lazytest.describe/describe and lazytest.describe/testing create test suites.

A test suite function may NOT have side effects; it is only used to generate test cases and/or other test suites.

A test runnner is responsible for expanding suites (see lazytest.suite/expand-suite) and running test cases (see lazytest.test-case/try-test-case). It may also provide feedback on the success of tests as they run. Two built-in runners are provided, see lazytest.runner.console/run-tests and lazytest.runner.debug/run-tests.

The test runner also returns a sequence of results, which are either suite results (see lazytest.suite/suite-result) or test case results (see lazytest.test-case/test-case-result). That sequence of results is passed to a reporter, which formats results for display to the user. One example reporter is provided, see lazytest.report.nested/report.

Making Emacs Indent Tests Properly

Put the following in .emacs

(eval-after-load 'clojure-mode
  '(define-clojure-indent
     (describe 'defun)
     (testing 'defun)
     (given 'defun)
     (using 'defun)
     (with 'defun)
     (it 'defun)
     (do-it 'defun)))

More Repositories

1

component

Managed lifecycle of stateful objects in Clojure
Clojure
2,086
star
2

reloaded

Leiningen 2 project template with tools.namespace, profiles, and user.clj
HTML
248
star
3

dependency

A data structure for representing dependency graphs in Clojure
Clojure
222
star
4

clojure-hadoop

Library to aid writing Hadoop jobs in Clojure.
Clojure
157
star
5

class-diagram

Generate & display class hierarchy diagrams for Java classes
Clojure
112
star
6

cljque

(archived) experiments with event streams in Clojure
Clojure
80
star
7

flow

(archived) Function definitions derived from graph declarations.
Clojure
78
star
8

frequencies

Basic statistical computations on frequency maps (histograms) in Clojure
Clojure
72
star
9

mapgraph

Basic in-memory graph database of maps with links
Clojure
66
star
10

dotfiles

my configuration files
Emacs Lisp
53
star
11

parallel-async

Examples of parallel processing with Clojure's core.async
Clojure
50
star
12

component.repl

Development utilities for the Component framework
Clojure
50
star
13

log.dev

Quick-start logging setup for Java or Clojure development
Clojure
43
star
14

clojure-rdf

(archived) RDF-manipulation library for Clojure
Clojure
34
star
15

validate

(archived) Composable data validation functions
Clojure
22
star
16

stacktrace.raw

Undo the effect of Clojure stacktrace pretty-printers
Clojure
20
star
17

clojure-archetype

Maven 2 archetype for Clojure projects
Clojure
17
star
18

clojure.walk2

Reimplementation of clojure.walk with protocols
Clojure
14
star
19

altlaw-backend

Back-end and web site code for www.altlaw.org
Clojure
13
star
20

devbox

Provisioning scripts for my personal development workstation
Shell
13
star
21

need

(archived) Clojure 'need' macro to replace use/require/refer
Clojure
11
star
22

classpath-manager

(archived) Nailgun add-on to run Java classes with configurable classpath
Java
11
star
23

hadoop-maven

(archived) Maven 2 POMs for Apache Hadoop projects
10
star
24

find-on-github

Emacs functions to open current file on GitHub.com
Emacs Lisp
10
star
25

password-store

My fork of 'pass' from http://www.passwordstore.org/
Shell
8
star
26

pairhost

(archived) EC2 remote pairing development environment
Shell
8
star
27

component.pedestal

Pedestal web server wrapper for Component systems
Clojure
8
star
28

org-mode

My copy of the org-mode repo
Emacs Lisp
7
star
29

cljs-formatter

(archived) ClojureScript pretty-printer that utilizes the DOM
Clojure
6
star
30

new-clojure-maven-plugin

(archived) leaner, meaner Clojure Maven plugin
Java
5
star
31

altlaw-pdf

PDF-to-HTML conversion for www.altlaw.org
C++
4
star
32

altlaw-clojure-restlet

Clojure/Restlet integration for AltLaw.org
Clojure
2
star
33

altlaw-vocab

RDF vocabulary for AltLaw.org
2
star
34

pedestal-test-sse-close

Test case for when client closes Pedestal SSE connection
Clojure
1
star
35

altlaw-template

StringTemplate-based rendering library for AltLaw
Clojure
1
star
36

altlaw-crawler

HTTP Web crawler for AltLaw.org
Clojure
1
star
37

clojure-time-trials

(archived) Performance tests for different programming techniques in Clojure
Clojure
1
star
38

buildtest

Testing Maven / Hudson build & release process for Clojure & contrib libraries
1
star
39

altlaw-extract

Data extraction / parsing code for AltLaw.org
Java
1
star
40

altlaw-jruby

Custom JRuby build for AltLaw.org
1
star
41

altlaw-parent

Parent POM for Maven 2 builds of AltLaw projects
1
star