Re: [rspec-users] Preconditions
On 9/8/07, Ben Mabey [EMAIL PROTECTED] wrote: What was the motivation behind taking that tutorial down, BTW? I really like and benefited from it when I was starting to learn rspec. Was it just a maintenance issue as far as updating the tutorial to the current API (DSL)? That was part of the deal. The other part was that I thought it would be more demonstrative to have something w/ two or more classes dealing w/ interactions. Just never got around to it. We should probably resurrect the Stack tutorial in the mean time. ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Preconditions
On 9/8/07, Wincent Colaiuta [EMAIL PROTECTED] wrote: El 8/9/2007, a las 2:15, Pat Maddox escribió: * Descriptions should be broken up based on the required fixture. I don't split them up until I actually have to. For example, if I'm writing a Stack class. I'd probably start off with [snip] For a simple spec like this it's okay. We could factor out the Stack.new call, and there's one other smell, but we'll get to that in a minute. Now what if we want to peek the stack? [snip] Now we've got clear duplication in three places: (1) The constructor (2) Call to add_item (3) the 'it' specifier! It's clear that the fixture for should not be empty and should let you peek are the same. They're also different from the should be empty so we split them up: [snip] There are two key benefits to that. The first is that it's obvious where new specifications need to go. The behavior for #pop whether a stack is empty or has an item is going to be different. Also if you need some behavior that changes with 3 items, you can probably figure out that you should create a new description. An even bigger benefit is that it minimizes the brain processing required to figure out a spec. If you create the fixture in the setup and don't vary it, it's trivial to scan through some simple expectations. This has to do with the smell that I alluded to earlier, which was the call to add_item. Ideally your example will contain just one expectation and no other setup. This reduces the concepts that change from example to example. Change is where bugs pop up most of the time. So if you're doing setup in an example, then you probably want to split it out from the current description. In fact, in real life I would have split the descriptions up immediately after writing the should not be empty example. Brilliantly written example, very clear! +1 Cheers, Wincent ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users To give credit where it's due, I'm pretty sure that's from my memory of the early examples on rspec.rubyforge.org. Pat ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Preconditions
On 9/8/07, Pat Maddox [EMAIL PROTECTED] wrote: On 9/8/07, Wincent Colaiuta [EMAIL PROTECTED] wrote: El 8/9/2007, a las 2:15, Pat Maddox escribió: * Descriptions should be broken up based on the required fixture. I don't split them up until I actually have to. For example, if I'm writing a Stack class. I'd probably start off with [snip] For a simple spec like this it's okay. We could factor out the Stack.new call, and there's one other smell, but we'll get to that in a minute. Now what if we want to peek the stack? [snip] Now we've got clear duplication in three places: (1) The constructor (2) Call to add_item (3) the 'it' specifier! It's clear that the fixture for should not be empty and should let you peek are the same. They're also different from the should be empty so we split them up: [snip] There are two key benefits to that. The first is that it's obvious where new specifications need to go. The behavior for #pop whether a stack is empty or has an item is going to be different. Also if you need some behavior that changes with 3 items, you can probably figure out that you should create a new description. An even bigger benefit is that it minimizes the brain processing required to figure out a spec. If you create the fixture in the setup and don't vary it, it's trivial to scan through some simple expectations. This has to do with the smell that I alluded to earlier, which was the call to add_item. Ideally your example will contain just one expectation and no other setup. This reduces the concepts that change from example to example. Change is where bugs pop up most of the time. So if you're doing setup in an example, then you probably want to split it out from the current description. In fact, in real life I would have split the descriptions up immediately after writing the should not be empty example. Brilliantly written example, very clear! +1 Cheers, Wincent ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users To give credit where it's due, I'm pretty sure that's from my memory of the early examples on rspec.rubyforge.org. Thanks for that Pat. We pulled that tutorial down a while ago but you can get the textile source for it like so: svn export svn://rubyforge.org/var/svn/rspec/tags/REL_0_8_0/doc/src/tutorials Cheers, David Pat ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Preconditions
David Chelimsky wrote: On 9/8/07, Pat Maddox [EMAIL PROTECTED] wrote: On 9/8/07, Wincent Colaiuta [EMAIL PROTECTED] wrote: El 8/9/2007, a las 2:15, Pat Maddox escribió: * Descriptions should be broken up based on the required fixture. I don't split them up until I actually have to. For example, if I'm writing a Stack class. I'd probably start off with [snip] For a simple spec like this it's okay. We could factor out the Stack.new call, and there's one other smell, but we'll get to that in a minute. Now what if we want to peek the stack? [snip] Now we've got clear duplication in three places: (1) The constructor (2) Call to add_item (3) the 'it' specifier! It's clear that the fixture for should not be empty and should let you peek are the same. They're also different from the should be empty so we split them up: [snip] There are two key benefits to that. The first is that it's obvious where new specifications need to go. The behavior for #pop whether a stack is empty or has an item is going to be different. Also if you need some behavior that changes with 3 items, you can probably figure out that you should create a new description. An even bigger benefit is that it minimizes the brain processing required to figure out a spec. If you create the fixture in the setup and don't vary it, it's trivial to scan through some simple expectations. This has to do with the smell that I alluded to earlier, which was the call to add_item. Ideally your example will contain just one expectation and no other setup. This reduces the concepts that change from example to example. Change is where bugs pop up most of the time. So if you're doing setup in an example, then you probably want to split it out from the current description. In fact, in real life I would have split the descriptions up immediately after writing the should not be empty example. Brilliantly written example, very clear! +1 Cheers, Wincent ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users To give credit where it's due, I'm pretty sure that's from my memory of the early examples on rspec.rubyforge.org. Thanks for that Pat. We pulled that tutorial down a while ago but you can get the textile source for it like so: svn export svn://rubyforge.org/var/svn/rspec/tags/REL_0_8_0/doc/src/tutorials Cheers, David Pat ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users What was the motivation behind taking that tutorial down, BTW? I really like and benefited from it when I was starting to learn rspec. Was it just a maintenance issue as far as updating the tutorial to the current API (DSL)? -Ben ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Preconditions
On 9/7/07, Geoffrey Wiseman [EMAIL PROTECTED] wrote: On 9/7/07, Pat Maddox [EMAIL PROTECTED] wrote: describe MyModel, when saved twice do This is the key point I hadn't considered; makes sense, as long as you make sure that there's a context wherein the specification that it should have a certain number of revisions. Thanks! Realized this afternoon that I need to use finer-grained 'test methods' than I'm used to. In some ways the it blocks are closer to assertions than to test methods in Test::Unit, in some ways. Totally. I highly recommend Dave Astels' One Expectation per Example article [1]. A couple separate points: * RSpec kicks ass because you can specify behavior on whatever level you want. You can use Story Runner to specify a feature, exercising a vertical slice of your entire app. You can get really fine-grained and specify what happens when a method runs. * Descriptions should be broken up based on the required fixture. I don't split them up until I actually have to. For example, if I'm writing a Stack class. I'd probably start off with describe Stack do it should be empty do Stack.new.should be_empty end end Then I want to write a spec for when I've added an item. describe Stack do it should be empty do Stack.new.should be_empty end it should not be empty after adding an item do s = Stack.new s.add_item :foo s.should_not be_empty end end For a simple spec like this it's okay. We could factor out the Stack.new call, and there's one other smell, but we'll get to that in a minute. Now what if we want to peek the stack? describe Stack do it should be empty do Stack.new.should be_empty end it should not be empty after adding an item do s = Stack.new s.add_item :foo s.should_not be_empty end it should let you peek at the top after adding an item do s = Stack.new s.add_item s.peek.should == :foo end end Now we've got clear duplication in three places: (1) The constructor (2) Call to add_item (3) the 'it' specifier! It's clear that the fixture for should not be empty and should let you peek are the same. They're also different from the should be empty so we split them up: describe Stack, empty do it should be empty do Stack.new.should be_empty end end describe Stack, with one item do before(:each) do @stack = Stack.new @stack.add_item :foo end it should not be empty do @stack.should_not be_empty end it should let you peek at the top do @stack.peek.should == :foo end end There are two key benefits to that. The first is that it's obvious where new specifications need to go. The behavior for #pop whether a stack is empty or has an item is going to be different. Also if you need some behavior that changes with 3 items, you can probably figure out that you should create a new description. An even bigger benefit is that it minimizes the brain processing required to figure out a spec. If you create the fixture in the setup and don't vary it, it's trivial to scan through some simple expectations. This has to do with the smell that I alluded to earlier, which was the call to add_item. Ideally your example will contain just one expectation and no other setup. This reduces the concepts that change from example to example. Change is where bugs pop up most of the time. So if you're doing setup in an example, then you probably want to split it out from the current description. In fact, in real life I would have split the descriptions up immediately after writing the should not be empty example. So I went from my first crack, closer to: describe Customer, xml do before do # set up customer end it should generate valid summary xml do # generate summary xml # a bunch of shoulds about the xml end it should generate valid full xml do # generate full xml # a bunch of shoulds end end To something like this: describe Customer, full xml do before do # set up customer full xml end it should have a root node of customer do @doc.root.name.should == 'customer' end it should contain a customer id it should have a name and address #etc end describe Customer, summary xml do # etc. end So I guess I'm still learning the mindset in places. Although you could ahve test methods like that in Test::Unit, most of the time you wouldn't bother simply because of the shared setup. But when the blocks affect how the spec is described, it's far more important to have fine-grained elements, I think. There's nothing in Test::Unit that prohibits you from writing tests with the same granularity that you can achieve with RSpec. However I have noticed that it can feel unnatural to do so, whereas RSpec of course highly encourages it. Actually, on that note -- what's the normal way to share a setup across multiple behaviors, a helper method in an includeable module?
Re: [rspec-users] Preconditions
On 9/7/07, David Chelimsky [EMAIL PROTECTED] wrote: Actually, on that note -- what's the normal way to share a setup across multiple behaviors, a helper method in an includeable module? You can include callable methods in modules, but they have to be called from within the spec. Alternative is shared behaviours: http://rspec.rubyforge.org/documentation/index.html (scroll down a bit). I've already got some shared behaviors, they're great; nice way to use a unit-level assertions n higher-level tests for instance without breaking DRY. Hadn't really thought about using these just for setup; the syntax would look a little weird what with it_should_behave_like, but it's still a thought. -- Geoffrey Wiseman ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users