[LRUG] Writing readable feature tests with RSpec

Andrew Premdas apremdas at gmail.com
Thu Jul 31 15:00:23 PDT 2014


On 31 July 2014 22:31, Sam Livingston-Gray <geeksam at gmail.com> wrote:

> 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.
>

Agreed


>  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.
>

No, World is one of the most misunderstood things about cucumber. I believe
it was a concious design decision to make World a single global space. The
idea of a single space is based on the understanding that viable
applications have clearly stated non-ambigous concepts. One of the main
points of writing features is to say what these concepts are and why they
are important. Putting your Ruby API in the single World namespace imposes
the discipline that in this single namespace you must be able to clearly
differentiate each key concept by its name. It also requires that you limit
the number of concepts and therefore the size of your API to something that
is manageable. Both of these are highly desirable. Of course this API which
the step definitions utilize can delegate further, but I'd question whether
its wise to let this further delegation leak into the actual step
definitions.

All best

Andrew

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?
>>
>
> _______________________________________________
> Chat mailing list
> Chat at lists.lrug.org
> Archives: http://lists.lrug.org/pipermail/chat-lrug.org
> Manage your subscription: http://lists.lrug.org/options.cgi/chat-lrug.org
> List info: http://lists.lrug.org/listinfo.cgi/chat-lrug.org
>
>


-- 
------------------------
Andrew Premdas
blog.andrew.premdas.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lrug.org/pipermail/chat-lrug.org/attachments/20140731/e0df2372/attachment.html>


More information about the Chat mailing list