On Feb 25, 2008, at 8:30 AM, David Chelimsky wrote: > On Mon, Feb 25, 2008 at 6:23 AM, Chuck Remes > <[EMAIL PROTECTED]> wrote: >> Thanks for asking this question. This is exactly what I was going >> to write, >> but you beat me to it! >> >> (Sorry for the top-post; just following the last responder.) >> >> cr >> >> >> >> On Feb 25, 2008, at 3:30 AM, Matthijs Langenberg wrote: >> Question is, would you duplicate the specs for all the classes that >> include >> a certain module (through shared behaviour for example), or would >> you use >> one set of specs for just the module, and specify that a class should >> include that module? > > Matthijs - I'd throw the same question back to you. Have you tried > both approaches? How have they worked out for you? > > I won't wait for your answer :). But I am curious about other people's > experiences with this. > > I can tell you this from my own experience - I tend to use shared > groups for this for a couple of reasons. One, I like to see the specs > for each object.
I thought I'd share my experiences with the group. Please recall I'm new at BDD/TDD so I may get some of the terminology wrong or whatever. So I have a class that, by itself, doesn't do anything. Concrete subclasses are necessary to flesh out a few characteristics before the parent class code can perform its magic. This is an abstract class which I'm told isn't the Ruby Way, so I'm looking at turning it into a module (a topic for another message). Originally, I was curious how to refactor my classes (and tests). I decided to write a second concrete subclass to see what kind of problems I might run into. I figured *any* problem I encountered was just more information for me to figure out the correct direction. The second subclass started out normally enough. I spec'd some behavior unique to that subclass. So far, so good. Then it occurred to me that I had no idea if the parent class was really being exercised by my new tests; turns out it wasn't being exercised. To resolve this I started adding some tests to make sure I covered the original behavior of the parent class. Now I had code duplication. The parent class tests and my *first* subclass were duping some of the same behavior. Looking into the examples directory I saw the concept of #shared_examples_for. I refactored my tests using shared examples. Most of these went into the parent class (perhaps soon to be a module). All the tests in my subclasses then focused exclusively on the behavior unique to that specific class while the describe blocks called #it_should_behave_like for shared behaviors. This DRY'ed the code up considerably. An added benefit was some test breakage I ran across while refactoring the tests. My second subclass had some rather tight coupling to the tests, so when I made it shared the subclass test broke. It forced me to rethink some of the test and class design to loosen the coupling. Ultimately it led to a better class api. So, that's my rambling summary. Kudos to you if you read this far. My next goal is to DRY up some of my 'before (:each)' blocks. I continually do the same setup operations across #describe blocks (@buf = Buf.new; @msg = blah, etc). It looks like I may want to define subclasses of a parent Spec::ExampleGroup so the subclasses can inherit some of the #before setup. I'd love to hear experiences from others on this technique. Lastly, I thought I'd say a word on the resulting class code. This BDD project was a learning experience. I rewrote a set of classes that I had originally written the old-fashioned way; puzzle through the logic in my head, write the code, and then debug the crap out of it until it worked. The original classes are rather short (LOC) with only a few methods (3 or 4). The classes I wrote via BDD are longer, maybe by 40% in terms of LOC. Plus, I now have around 10 methods none of which exceeds 5 lines of "real" code. It's more readable, more logical, and *far* easier to subclass. I'm now a believer. YMMV. cr _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users