Re: Midje: a different slant on clojure testing

2010-12-16 Thread .Bill Smith
Thank you for sharing Midje with us.  I too would like to hear how it 
relates to clojure.test.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Midje: a different slant on clojure testing

2010-12-16 Thread Brian Marick

On Dec 16, 2010, at 12:21 AM, Shantanu Kumar wrote:
 1. Is there any example app that demonstrates how to use Midje?

The introduction to the basic feature set is here:
https://github.com/marick/Midje/blob/master/examples/sweet-examples/basic/test/basic/core_test.clj

As a simple example, I converted the tests from Mark McGranaghan's sample 
compojure app from clojure.test to midje. The converted app is here:

https://github.com/marick/Midje/tree/master/examples/sweet-examples/adder-webapp

To compare the sets of tests, look in these two places:
https://github.com/mmcgrana/adder/blob/master/test/adder/core_test.clj
https://github.com/marick/Midje/blob/master/examples/sweet-examples/adder-webapp/test/adder/core_test.clj

(Looking at my example, I see the treatment of helper functions is out of date. 
I'll go and update it.)

 2. Why would I use Midje instead of clojure.test? (Perhaps you can
 also blog about it with an example using clojure.test and Midje.)


Midje supports top-down development, whereas clojure.test doesn't. I have a 
three-part example of top-down development here:
http://www.exampler.com/blog/2010/06/10/tdd-in-clojure-a-sketch-part-1/

(Note the example predates Midje. The shape of the code samples is the same 
(arrows, placeholders with names like ...cell...), but names have changed. 
know is now called fact, etc.)

I think Midje syntax is more readable because it matches the way we're used to 
seeing examples of code: the code, then some delimiter, then the results. Look 
at the examples in /Programming Clojure/. From p. 50:

  (into [] (take 5 (iterate dec 5)))
= [5 4 3 2 1]

(As I've been converting my tests from clojure.test to Midje, I've also noticed 
that they become terser.)

I find the test failures easier to interpret, especially when I use chatty 
checkers (which was inspired by Phlip's assert{2.0} for Ruby 
http://www.oreillynet.com/ruby/blog/2008/02/assert2.html)

-
Brian Marick, Artisanal Labrador
Contract programming in Ruby and Clojure
Author of /Ring/ (forthcoming; sample: http://bit.ly/hfdf9T)
www.exampler.com, www.exampler.com/blog, www.twitter.com/marick

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Midje: a different slant on clojure testing

2010-12-16 Thread Brian Marick

On Dec 16, 2010, at 12:21 AM, Shantanu Kumar wrote:

 2. Why would I use Midje instead of clojure.test? 


Oh, one other thing: you can mix and match Midje and Clojure.test tests. Midje 
uses the clojure.test reporting mechanism. You can start adding Midje tests to 
your existing test files and change old tests to the new format at your leisure.

(The downside is that if you want the test summaries to be right, you have to 
wrap the Midje tests in #'deftest. Otherwise fact successes and failures aren't 
counted when you do 'lein test'.)

-
Brian Marick, Artisanal Labrador
Contract programming in Ruby and Clojure
Author of /Ring/ (forthcoming; sample: http://bit.ly/hfdf9T)
www.exampler.com, www.exampler.com/blog, www.twitter.com/marick

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Midje: a different slant on clojure testing

2010-12-15 Thread Brian Marick
I'd like to formally announce Midje, a testing framework for Clojure that 
emphasizes ease of use, readability, and relationships among functions.

https://github.com/marick/Midje

Midje is at 0.8.1. I'd bump it to 1.0. but I don't want to freeze the interface 
to some of the newer features just yet. 

Here's a simple example:

(fact (+ 1 1) = 2)

I use the word fact because Clojure is a functional language. State 
modification should be rare. That means that most code will always produce the 
same value: when you write tests, you state facts about a function that readers 
can generalize from. (In mathematical terminology, Midje facts are propositions 
with no variables that encourage readers to assume universally-quantified 
propositions.)

Midje makes it easy to use functions other than equality to check results:

(facts 
 (first (primes-greater-than-2)) = odd? 
 (some-complicated-function) = (in-any-order [1 2 3]))

Midje lets you alternate between bottom-up (REPL-based) and top-down design. In 
the latter, you claim facts about functions that are true *provided* facts 
about not-yet-written functions are true. That looks like this:

(fact
 (alive-in-next-generation? ...cell...) = truthy
   (provided 
(alive? ...cell...) = false
(neighbor-count ...cell...) = 3))

The above is an example I wrote in one of Corey Haine's Code Retreat workshops. 
It lets me worry about the properties of aliveness in Conway's life before I 
worry about the concrete representation of the Life board. 

The ...cell... notation shows what I call metaconstants. I've long thought 
that useful tests live somewhere between concreteness and abstraction. 
Metaconstants let you say of data Assume nothing about this data except what's 
explicitly stated here. In my programming, I've found metaconstants far 
preferable to creating complicated data structures (via fixtures, object 
mothers, and the like). It's been a big help in test maintenance. (Most of my 
experience with this has been in Ruby, but it seems to apply to Clojure too.)

Midje contains other features you might expect from a test framework. For 
example, when you have to use state, it gives you a way to set it up or tear it 
down:

 (fact
   (against-background (before :checks (swap! test-atom (constantly 0
   (swap! test-atom inc) = 1
   (swap! test-atom dec) = -1)

(background (around :facts (sql/with-connection db ?form)))

I've worked up an emacs interface, and there are features I'd like other test 
frameworks to steal (like chatty checkers). 


It will make me happy if you try Midje.

-
Brian Marick, Artisanal Labrador
Contract programming in Ruby and Clojure
Author of /Ring/ (forthcoming; sample: http://bit.ly/hfdf9T)
www.exampler.com, www.exampler.com/blog, www.twitter.com/marick

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Midje: a different slant on clojure testing

2010-12-15 Thread Ken Wesson
On Wed, Dec 15, 2010 at 6:37 PM, Brian Marick mar...@exampler.com wrote:
 I'd like to formally announce Midje, a testing framework for Clojure that 
 emphasizes ease of use, readability, and relationships among functions.

    https://github.com/marick/Midje

 Midje is at 0.8.1. I'd bump it to 1.0. but I don't want to freeze the 
 interface to some of the newer features just yet.

Cool.

 Midje makes it easy to use functions other than equality to check results:

    (facts
     (first (primes-greater-than-2)) = odd?
     (some-complicated-function) = (in-any-order [1 2 3]))

So, a predicate is called on the result instead of tested for equality
with the result?

And you have something like

(defn in-any-order [s]
  (let [ss (into #{} s)]
(fn [x] (= ss (into #{} x)

and perhaps other functions that return predicates for use as above?

 Midje contains other features you might expect from a test framework. For 
 example, when you have to use state, it gives you a way to set it up or tear 
 it down:

     (fact
       (against-background (before :checks (swap! test-atom (constantly 0
       (swap! test-atom inc) = 1
       (swap! test-atom dec) = -1)

Why not use (reset! test-atom 0) above?

    (background (around :facts (sql/with-connection db ?form)))

This doesn't seem to be wrapping anything. What determines its scope?

Perhaps I should visit the URL and see if there's more in-depth
documentation. :)

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Midje: a different slant on clojure testing

2010-12-15 Thread Brian Marick

On Dec 15, 2010, at 6:05 PM, Ken Wesson wrote:
 Midje makes it easy to use functions other than equality to check results:
 
(facts
 (first (primes-greater-than-2)) = odd?
 (some-complicated-function) = (in-any-order [1 2 3]))
 
 So, a predicate is called on the result instead of tested for equality
 with the result?

Yes. The use of #'odd? as a checker is just showing off. I'm not sure I've ever 
actually used a Clojure function as a checker in real life. I always use one of 
Midje's predefined checkers:

https://github.com/marick/Midje/wiki/Checkers

 
 Midje contains other features you might expect from a test framework. For 
 example, when you have to use state, it gives you a way to set it up or tear 
 it down:
 
 (fact
   (against-background (before :checks (swap! test-atom (constantly 0
   (swap! test-atom inc) = 1
   (swap! test-atom dec) = -1)
 
 Why not use (reset! test-atom 0) above?

For a very subtle reason: I didn't think of it.

 
(background (around :facts (sql/with-connection db ?form)))
 
 This doesn't seem to be wrapping anything. What determines its scope?

#'background's scope is the entire namespace (or, I should say, from the point 
it occurs in a file until the end of a file). It's useful for my emacs 
midje-mode, where a keypress sends an individual fact to the repl for checking. 
(In this case, before the fact is checked, it'll be wrapped with the connection 
form.) 

You can also wrap multiple facts with (against-background...)  (Putting 
against-background inside a fact is another shorthand that makes sending a 
single fact to the repl work better.)

The whole story about backgrounds is here:
https://github.com/marick/Midje/wiki/Setup%2C-Teardown%2C-and-State
https://github.com/marick/Midje/wiki/Background-prerequisites

-
Brian Marick, Artisanal Labrador
Contract programming in Ruby and Clojure
Author of /Ring/ (forthcoming; sample: http://bit.ly/hfdf9T)
www.exampler.com, www.exampler.com/blog, www.twitter.com/marick

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Midje: a different slant on clojure testing

2010-12-15 Thread Shantanu Kumar
This looks really interesting. Two obligatory questions:

1. Is there any example app that demonstrates how to use Midje?
2. Why would I use Midje instead of clojure.test? (Perhaps you can
also blog about it with an example using clojure.test and Midje.)

Regards,
Shantanu

On Dec 16, 7:01 am, Brian Marick mar...@exampler.com wrote:
 On Dec 15, 2010, at 6:05 PM, Ken Wesson wrote:

  Midje makes it easy to use functions other than equality to check results:

     (facts
      (first (primes-greater-than-2)) = odd?
      (some-complicated-function) = (in-any-order [1 2 3]))

  So, a predicate is called on the result instead of tested for equality
  with the result?

 Yes. The use of #'odd? as a checker is just showing off. I'm not sure I've 
 ever actually used a Clojure function as a checker in real life. I always use 
 one of Midje's predefined checkers:

 https://github.com/marick/Midje/wiki/Checkers



  Midje contains other features you might expect from a test framework. For 
  example, when you have to use state, it gives you a way to set it up or 
  tear it down:

      (fact
        (against-background (before :checks (swap! test-atom (constantly 
  0
        (swap! test-atom inc) = 1
        (swap! test-atom dec) = -1)

  Why not use (reset! test-atom 0) above?

 For a very subtle reason: I didn't think of it.



     (background (around :facts (sql/with-connection db ?form)))

  This doesn't seem to be wrapping anything. What determines its scope?

 #'background's scope is the entire namespace (or, I should say, from the 
 point it occurs in a file until the end of a file). It's useful for my emacs 
 midje-mode, where a keypress sends an individual fact to the repl for 
 checking. (In this case, before the fact is checked, it'll be wrapped with 
 the connection form.)

 You can also wrap multiple facts with (against-background...)  (Putting 
 against-background inside a fact is another shorthand that makes sending a 
 single fact to the repl work better.)

 The whole story about backgrounds is 
 here:https://github.com/marick/Midje/wiki/Setup%2C-Teardown%2C-and-Statehttps://github.com/marick/Midje/wiki/Background-prerequisites

 -
 Brian Marick, Artisanal Labrador
 Contract programming in Ruby and Clojure
 Author of /Ring/ (forthcoming; 
 sample:http://bit.ly/hfdf9T)www.exampler.com,www.exampler.com/blog,www.twitter.com/marick

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en