On Sat, Jun 7, 2008 at 3:16 PM, David Chelimsky <dchelimsky at gmail.com> wrote:
>> I started with user stories, but the conversion to english was
>> difficult for something largely developer-facing. "When I get
>> /widgets/:id" where :id is actually determined behind the scenes did
>> not read well, and a lot of my expectations were tough to express in
>> sentence form. I've had a lot of success with stories in the
>> application that is related to this API, but they don't seem to fit
>> well here.
>> Can you post an example or two? I'd like to see what's not working for you.
> No promises I can offer up anything better, but just curious.
I've since rm'd what I wrote, but imagine the case where I need to
create a widget, and then I'd like to spec what Widgets#show should
return to me:
Given a green widget named Panel
When I get the JSON representation of the widget
Then it should include its buttons
And it should not include the widget's super secret name
There's nothing inherently wrong with this -- I actually rather like
it. Reasonably succinct, and a nice high-level overview. But notice
that it doesn't really document the API, which is the goal of my
specs. No mention that the widget is at /widgets/1. If I were to
mention the URL, I'd have to use something like the /widgets/:id I
mentioned, where :id is a bare string in the step name, but filled in
with whatever id I happened to get when I created a widget in step #1.
Nor is it very clear about what "should include its buttons" means.
Again, that's a good thing if I were documenting behavior of something
closer to an application, but it's awkward here.
Cf. to:
widget = create_widget(:name => 'Panel', :color => 'green')
3.times { create_button(:widget => widget) }
obj = get_json('/widgets/' + widget.id)
obj['buttons'].length.should == 3
obj.should_not have_key('super-secret-name')
(I would actually split these up into separate examples, but you get the idea)
Given well chosen example group/example names, it feels like this will
be more useful when another developer opens them up to learn how to
consume the API. And the specdocs have ended up being almost identical
to the stories for the purposes of at-a-glance understanding.
> The IntegrationExampleGroup should work. Let's try to figure out why you're
> getting bleed into the other groups.
The issue was that my other specs are for the models, which are shared
between two applications in a plugin. Thus, the specs are living in
plugins/mylib/spec/integration/models -- integration here opposed to
the unit tests we have in spec/unit, as they lean on other plugins
like will_paginate. That directory then matches :integration and they
rightfully try to use the IntegrationExampleGroup. Just an unfortunate
overlap of terminology. For now I've just opted to rename the
:integration type key to :api, but hopefully I'll come up with a
better name for spec/integration. Open to suggestions. =)
Works like a charm now, I can use autotest to run them alongside our
other specs, and it accomplishes everything I set out for. Big wins
all around.
k