[LRUG] Writing readable feature tests with RSpec

Sam Livingston-Gray geeksam at gmail.com
Thu Jul 31 14:31:16 PDT 2014


On Thu, Jul 31, 2014 at 12:29 PM, Murray Steele <murray.steele at gmail.com>
wrote:

>
> On 30 July 2014 17:32, Sam Livingston-Gray <geeksam at gmail.com> wrote:
>
>> You might also find yourself wanting to separate out responsibilities by
>> topic area, so that you wind up writing step code like:
>>
>> step_driver.given.i_am_logged_in_as 'sales_rep'
>> step_driver.when.i_have_net_revenue '$20,000'
>> step_driver.when.commissions_are_calculated
>> step_driver.then.i_receive_payout_of '$5'
>>
>
> I don’t get the benefit of this; all that step_driver.[giv|[w|t]h]en seems
> sort of noisy.  Why would you do that instead of just something like:
>
> i_am_logged_in_as 'sales_rep'
> i_have_net_revenue '$20,000'
>
> calculate_commissions
>
> i_should_receive_payout_of '$5’
>

Over the years, I've learned that the less of my code lives in Cucumber's
domain, the happier I am.  I view step definitions as a quick translation
layer between Gherkin and a sensible Ruby API that I can refactor to suit
my evolving needs.  In contrast, Ruby step definitions strongly resist
refactoring, and pushing the problem out to a bunch of modules that all get
included into World is only slightly better.  Both situations feel a lot
like PHP to me:  everything is available in one global namespace, and I've
found that that makes it very easy to wake up and find oneself in
dependency hell.

Admittedly, you could probably get rid of the "step_driver" in my example
and just define #given, #when, and #then methods directly on World; you
could also drop the g/w/t versions and rely on your ability to name methods
in a way that communicates whether they're arranging, acting, or asserting.

I actually wound up with a slightly different breakdown on a recent
project; in that, my example would look more like:

step_driver.misc.log_in_with_role 'sales_rep'
step_driver.commissions_actual.assign_net_revenue '$20,000'
step_driver.commissions.calculate_for_current_month
step_driver.commissions.verify_payout '$5'

I admit, I’m not exactly clear on what problem Paul was originally
> describing, nor am I clear anymore if we’re talking about cucumber or rspec
> features.
>

I've forgotten the problem as well, but code like this can be reused
between cucumber or rspec if you're into that sort of thing.  Or, at some
point whoever's maintaining my app decides they really don't like Cucumber,
it won't be completely out of the question for them to port the tests to
their test/spec framework du jour.

I don't seriously anticipate either situation, but I do still occasionally
work in an app that's stuck using an old version of Shoulda, which
sucks—we've actually recreated our own version of RSpec's .let
functionality to make those tests slightly less awful to write.  So that
concern isn't *completely* theoretical.  :)

If we’re talking cucumber, then it doesn’t seem so awful as the actual step
> name is what we’ll see in the test so these extra objects and methods are
> not in the way.  However, if we’re talking rspec features then I don’t
> understand the motivation for introducing the line noise as it reduces the
> readability of the spec.
>
> I’m sure there’s a good reason and I’m just missing something.
>
> Forgive the use of the “should” in my re-write, but I couldn’t think of a
> better word to indicate that the final method is an assertion.  Perhaps
> this is enough motivation for the noise?
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lrug.org/pipermail/chat-lrug.org/attachments/20140731/1231b72a/attachment-0003.html>


More information about the Chat mailing list