Then I should be on /users/3/posts/8/comments/2/edit

“Then I should be on /users/3/posts/8/comments/2/edit”

What’s the solution for parsing out and matching and arbitrarily deep
nested route?

The problem is actually this:

And I fill in …
And I press “Create Comment”
Then I should be on [the correct page, ie.
/users/3/posts/8/comments/2/edit]

How do you write a step for that?

Gavin H. wrote:

The problem is actually this:

And I fill in …
And I press “Create Comment”
Then I should be on [the correct page, ie.
/users/3/posts/8/comments/2/edit]

How do you write a step for that?

I just saw this second message… My assumption about what you were
testing was off, but the principle remains the same. You should verify
that the application is correct by looking at what the user actually
sees in the response body- not what they see in the URL/address bar.

So, instead of saying “Then I should be on…” can you say something
like “Then I should see…”? Again, does the user really care what the
URL is, or what is actually on the page?

-Ben

On Thu, Apr 9, 2009 at 11:27 PM, Gavin H. [email protected]
wrote:

The problem is actually this:

And I fill in …
And I press “Create Comment”
Then I should be on [the correct page, ie.
/users/3/posts/8/comments/2/edit]

How do you write a step for that?

Personally I try and stay away from step-matchers based on URLs. Do
you really care about what page you’re on?

I would instead check the response for the “Thank you for posting” or
whatever message that you’re probably showing.

If however you want to check the page, do something like
response.url.should == “/blah”


Josh K.
phone: 509-979-1593
email: [email protected]
web: http://joshknowles.com

I’m not sure, cause I’ve never tried to write a step like that.

I would rather do
Then I should see “Editing ‘My sweet comment’”

Even better would be to actually edit the comment and make sure that
it changed. So maybe

When I edit the comment to be “My new comment”
Then I should see “My new comment”
And I should not see “My old comment”

This way you’re testing the feature itself, rather than some
implementation detail such as the current url.

Pat

Gavin H. wrote:

“Then I should be on /users/3/posts/8/comments/2/edit”

What’s the solution for parsing out and matching and arbitrarily deep
nested route?

Hi Gavin,
Let me try to answer your question without actually answering it. :slight_smile:

I generally don’t test my URLs. IMO, for the majority of cases the URL
is merely an implementation detail of the application. For example I
could easily see the URL in your example
(/users/3/posts/8/comments/2/edit) as being “/posts/8/comments/2/edit”
or “/comments/2/edit” or “/posts/the-name/comments/2/edit”. The user
would be fine with all of these cases, they really don’t care one way or
the other. Instead of focusing on an implementation detail of the
application scenarios should be focused on the behaviour that the user
would like to see. In your particular case what the user really cares
about is being able to edit a comment, correct? So, instead of just
verifying that the user is on the right page after clicking on “Edit
Comment”, you should have the user actually fill out the form to edit
the comment. Then verify that the comment is actually updated on the
post’s page after they submit the comment editing form. Off the top of
my head something like this may work:

Scenario: edit comment
Given a post exists named “big news”
And I have made a comment “bad post!” on the “big news” post
And I am viewing the “big news” post

When I change my "bad post!" comment to "Great post!"
And press "Update Comment"

Then I should see "Great Post!"

With this you are just testing the behaviour of the application. (BTW,
you could write the scenario above number of ways and still be testing
the same thing- I’m not sure if I love the way I wrote it…) You could
change your URL naming scheme and this would still pass because the
behaviour hasn’t changed. By embedding the URL in the scenario your URL
scheme is now coupled to your features unnecessarily.

Sorry, for not really answering your question but I think you will thank
me later if you take this approach. :slight_smile:

-Ben

On Apr 10, 2009, at 12:51 AM, Ben M. wrote:

URL is merely an implementation detail of the application. For
out the form to edit the comment. Then verify that the comment is
actually updated on the post’s page after they submit the comment
editing form.

One place I’ve actually been interested in testing URLs was to verify
that the app actually redirected after a form submission. The user
facing reason for this is to verify that the app works as
expected(e.g. doesn’t repost a comment or something) when the user
refreshes to get fresh data. Of course, sticking to what the user
cares about, it would probably be best to have this tested in a
separate scenario for ‘user refreshes page after posting comment’ .

-lenny

Ben, Josh

Makes perfect sense. The user won’t be looking at the URL. He’ll
expect some result on the page, thus we test for that.

Thanks!

Gavin

On Fri, Apr 10, 2009 at 8:49 AM, Lenny M. [email protected] wrote:

Hi Gavin,
the user really cares about is being able to edit a comment, correct? So,
this tested in a separate scenario for ‘user refreshes page after posting
comment’ .

I would just test that at the controller level

it “should redirect to the comment’s article” do
post :create, :article_id => @article.to_param, :comment => {:body =>
“wooo”}
response.should redirect_to(@article)
end

Pat

On Fri, Apr 10, 2009 at 9:40 AM, Pat M. [email protected]
wrote:

I would just test that at the controller level

I would specify that at the controller level.

BAD BDD evangelist :stuck_out_tongue:

On Fri, Apr 10, 2009 at 11:49 AM, Lenny M. [email protected] wrote:

One place I’ve actually been interested in testing URLs was to verify that
the app actually redirected after a form submission.

I can agree with this, and I had a similar need just the other day. I
had an action that redirected to different places depending on whether
a certain box was checked. But I didn’t spec it by checking the
literal text of URL itself. Instead I worked with the paths
functionality that was already in Cucumber’s support directory, and
made it a bit more flexible. Here was my situation:

Scenario: Has an Enclosure
Given I am a contributor
When I go to the create episode page
And I fill in […blah blah, submitting the form…]
Then I should have an episode titled “Any title”
And I should be on the create enclosure page for that episode

…I wanted that “I should be on (foo) for that (bar)” to be general,
so in my application_steps.rb:

Then /^I should be on (.page) for that (.)$/ do |page, element|
current_url.should == path_to(page,
instance_variable_get(“@#{element}”))
end

…And finally, I rewrote the path_to method in paths.rb a bit:

def path_to(page_name, parent_object = nil)
case page_name
[ . . . ]
when /the create enclosure page/i
new_episode_enclosure_url(parent_object)

This all worked, and it worked well. Though of course, going through
the work of specing and building a separate enclosure model made me
decide that it would really work better as a simple Paperclip
attribute inside episode, so I threw all that away… But c’est la
vie. >8->


Have Fun,
Steve E. ([email protected])
ESCAPE POD - The Science Fiction Podcast Magazine
http://www.escapepod.org