Re: Midje: a different slant on clojure testing
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
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
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
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
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
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
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