<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Jul 30, 2014 at 7:51 AM, Paul Battley <span dir="ltr"><<a href="mailto:pbattley@gmail.com" target="_blank">pbattley@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">State within one feature feels a lot easier to deal with than hidden state<br>

in @variables across different definition files.</blockquote><div><br></div><div>You don't need to use @variables.  Okay, technically, you need to use *one*, but it can be something like @shared_state = {}, and then everything else can be more explicit about how it interacts with that shared state.  Making it a Hash allows you to use the marvelous Hash#fetch for exploding as soon as things aren't as you expect (e.g., step A sets @color = 'fff' and step E asks for @colour), rather than returning a nil that will *eventually* explode.  ("Nobody expects the Spanish Inqui...NoMethodError!  Our primary weapon is whiny nil!")</div>
<div><br></div><div>In a project I started at a previous job (that was then extensively refactored and documented by a coworker), we referred to a user's "mental model" and used it to update state between steps:  <a href="https://github.com/jwilger/kookaburra/blob/master/lib/kookaburra/mental_model.rb">https://github.com/jwilger/kookaburra/blob/master/lib/kookaburra/mental_model.rb</a></div>
<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
I found myself ordering steps so that I could reuse them without<br>
aliasing them to deal with given/and then/and when/and, which feels<br>
like a bad motivation. That led me to think that perhaps I could<br>
create no-op given/when/then/and methods (i.e. given_i_do_something -><br>
given i_do_something) - except, of course, that all but one of those<br>
is a reserved word in Ruby. given_/when_/then_/and_, perhaps? Or<br>
precondition/action/outcome? </blockquote><div><br></div><div>One possibility:  define a top-level method.  Call it whatever you like; for purposes of argument, I'll just use 'foo'.  Make that method return an object with:</div>
<div><br></div><div>def given ; self ; end</div><div>def when ; self ; end</div><div>def then ; self ; end</div><div><br></div><div>Then define all of your test helpers on that object.  All of these will now invoke the same method without your having to think about what prefix goes on the method name:</div>
<div><br></div><div>foo.given.i_do_something</div><div>foo.when.i_do_something</div><div>foo.then.i_do_something</div><div><br></div><div>If you later find yourself putting other responsibilities on the object returned by #foo, you might want to have its given/when/then methods return some other object instead of self.  You might also find yourself wanting to separate out responsibilities by topic area, so that you wind up writing step code like:</div>
<div><br></div><div>step_driver.given.i_am_logged_in_as 'sales_rep'</div><div>step_driver.when.i_have_net_revenue '$20,000'</div><div>step_driver.when.commissions_are_calculated</div><div>step_driver.then.i_receive_payout_of '$5'</div>
<div><br></div><div>To swipe a line from a recent Katrina Owen article about refactoring:  guess how I know this.  ;></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
That feels like a step along the<br>
dangerous path to precedence hacks and pseudo-English Ruby - I already<br>
feel that RSpec is a bit too far that way, and every time I see<br>
something like "expect(foo).to be true" I'm a little surprised that it<br>
works.<br></blockquote><div><br></div><div>Really?  That's far better than the gyrations RSpec originally went through to make the #should method available on literally everything in the system (and even then, it still didn't work everywhere).  While in a windmill-tilting mood a few years back, I once wrote a gem to quarantine RSpec's Kernel#should methods so that my team didn't accidentally use them in a context where they, well, should_not_have.  <a href="https://github.com/geeksam/cordon">https://github.com/geeksam/cordon</a></div>
<div><br></div><div>Upon learning that RSpec had introduced the #expect syntax and was deprecating Kernel#should, I (a) was extremely amused, (b) thought "damn, that's a much better name than #assert_that" (which I had used in the aforementioned gem), and (c) resolved to give RSpec another try.</div>
<div><br></div><div>I guess what I'm saying is that I can see how that construct seems a bit silly when looked at with fresh eyes, but for RSpec, it's such a huge step back toward sanity that it didn't occur to me to look at it that way!  :D  (See also:  "the Overton window".)</div>
</div></div></div>