Anyone?
-------- Original Message --------
Subject: Functional test problem
Date: Wed, 14 Jun 2006 19:49:03 +0100
From: Chris T <ctmailinglists@gmail.com>
Reply-To: ctmailinglists@gmail.com
To: rails@lists.rubyonrails.org
Embarrassingly late (apps already well advanced), have decided top get
to grips with testing and am having a week hopefully covering everything
I''ve already coded (so far it''s been worth it -- found a
couple of bugs
might not have found otherwise).
But having a bit of a prob with a functional test. I''m trying to
enumerate through through a list of users in a fixtures file, and test
against each one, but it''s doing something very weird. Here''s
the basics
of the test
def test_index_user
User.find(:all).each do |user|
get :index, {}, {:user => user.id}
assert_response :success
assert_tag :tag => "div",
:attributes => {
:id => "usermenu"
},
:content => /Hello\s#{user.login}/
end
end
What''s happening is that it''s failing, saying:
expected tag, but no tag found matching {:tag=>"div",
:content=>/Hello\sarthur/, :attributes=>{:id=>"usermenu"}}
in:
....#dump of tags including..
<div id=\"usermenu\">\r\nHello quentin
...
</div>
...
quentin is the first fixture in users, arthur is the second. It seems
like the get :index is not successfully putting the new user id in the
session.
Can anyone help me understand what''s going on?
Chris T wrote:> Anyone? > > -------- Original Message -------- > def test_index_user > User.find(:all).each do |user| > get :index, {}, {:user => user.id} > assert_response :success > assert_tag :tag => "div", > :attributes => { > :id => "usermenu" > }, > :content => /Hello\s#{user.login}/ > end > end > > What''s happening is that it''s failing, saying: > > expected tag, but no tag found matching {:tag=>"div", > :content=>/Hello\sarthur/, :attributes=>{:id=>"usermenu"}} in: > ....#dump of tags including.. > <div id=\"usermenu\">\r\nHello quentin > ... > </div> > ... > quentin is the first fixture in users, arthur is the second. It seems > like the get :index is not successfully putting the new user id in the > session. > > Can anyone help me understand what''s going on?Here''s some possible ides, they are of the "it takes someone else to suggest a stupid idea variety" though... so I''m not sure how likely they''ll be. 1. Have you confirmed that the page works as desired in the browser (perhaps the welcome message was hard-coded?) 2. Have you done anything "weird" with caching that might somehow be causing the test environment to cache the results of the pages? 3. if you unroll the loop, does it still fail? -- Posted via http://www.ruby-forum.com/.
Eric
Thanks for the suggestions. Actually it is working in the browser.
After a bit of digging, I thought the problem might be with the
current_user method which wasn''t being updated with the change in
session[:user], so posted the query on Railsweenie hoping Rick might be
able to help (as the author of acts_as_authenticated). This is what he
said (which makes sense):
You can''t call a controller method multiple times in a functional
test. Instance variables like @controller, @request, and @response
don''t get recycled. So, since the same controller instance is
sticking around, that means the same @current_user is too.
Not sure if there''s a good way to achieve what I''m trying to
do -- it''s
not particular the Hello user I want to test, but I want to test the
number of items each user sees of a particular kind). Do separate tests
for each case? Or loop through a test rather than the controller method?
Or could (should?) I use integration tests (which i haven''t yet
investigated)?
Still quite new to this whole testing lark. Never had anything like this
in php ;-)
Eric D. Nielsen wrote:> Chris T wrote:
>
>> Anyone?
>>
>> -------- Original Message --------
>> def test_index_user
>> User.find(:all).each do |user|
>> get :index, {}, {:user => user.id}
>> assert_response :success
>> assert_tag :tag => "div",
>> :attributes => {
>> :id => "usermenu"
>> },
>> :content => /Hello\s#{user.login}/
>> end
>> end
>>
>> What''s happening is that it''s failing, saying:
>>
>> expected tag, but no tag found matching {:tag=>"div",
>> :content=>/Hello\sarthur/,
:attributes=>{:id=>"usermenu"}} in:
>> ....#dump of tags including..
>> <div id=\"usermenu\">\r\nHello quentin
>> ...
>> </div>
>> ...
>> quentin is the first fixture in users, arthur is the second. It seems
>> like the get :index is not successfully putting the new user id in the
>> session.
>>
>> Can anyone help me understand what''s going on?
>>
>
> Here''s some possible ides, they are of the "it takes someone
else to
> suggest a stupid idea variety" though... so I''m not sure how
likely
> they''ll be.
>
> 1. Have you confirmed that the page works as desired in the browser
> (perhaps the welcome message was hard-coded?)
>
> 2. Have you done anything "weird" with caching that might
somehow be
> causing the test environment to cache the results of the pages?
>
> 3. if you unroll the loop, does it still fail?
>
>
>
Chris T wrote:> Eric > > Thanks for the suggestions. Actually it is working in the browser. > After a bit of digging, I thought the problem might be with the > current_user method which wasn''t being updated with the change in > session[:user], so posted the query on Railsweenie hoping Rick might be > able to help (as the author of acts_as_authenticated). This is what he > said (which makes sense): > > You can''t call a controller method multiple times in a functional > test. Instance variables like @controller, @request, and @response > don''t get recycled. So, since the same controller instance is > sticking around, that means the same @current_user is too. >Interesting, so it was "almost" a caching type issue...> Not sure if there''s a good way to achieve what I''m trying to do -- it''s > not particular the Hello user I want to test, but I want to test the > number of items each user sees of a particular kind). Do separate tests > for each case? Or loop through a test rather than the controller method? > Or could (should?) I use integration tests (which i haven''t yet > investigated)?I tend to subscribe to the ~1 assertion per test approach. Controller tests already start to push that to 2-4 assertions so I definitely wouldn''t combined tests for different aspects of the same functionality into one test. So yes, I''d break up the test to separate cases. Are you trying to test that the Model retreived the correct number of things (in which case that would probably belong in a unit test of the model, not the controller), or is there some controller side logic that affects the list before rendering that you need to test? Or are you testing that a list renders properly, perhaps with some alternate text for cases where there are no elements? From a list viewpoint, when I''m being pendantic in my tests, I''ll commonly take an induction-based approach and write a test for each of the following: base cases (empty list, one item list) inductive case (assume it works for n, prove that it works for n+1) Note, some testers talk about testing 0,1,2 and calling it "inductive", but unless the test case for 2 is written properly its not inductive. An inductive test case looks like: def test_inductive_step_for_foo current_result = foo.method_to_test foo.add next_foo assert_equal current_result+correct_delta, foo.method_to_test end (of course method names, variables, and mechanism for combining current_result and correct_delta will vary, but the key point is that _transformation_ from one state to the next is correct, not merely that each state is correct.) Eric -- Posted via http://www.ruby-forum.com/.
Eric D. Nielsen wrote:> Chris T wrote: > >> Eric >> >> Thanks for the suggestions. Actually it is working in the browser. >> After a bit of digging, I thought the problem might be with the >> current_user method which wasn''t being updated with the change in >> session[:user], so posted the query on Railsweenie hoping Rick might be >> able to help (as the author of acts_as_authenticated). This is what he >> said (which makes sense): >> >> You can''t call a controller method multiple times in a functional >> test. Instance variables like @controller, @request, and @response >> don''t get recycled. So, since the same controller instance is >> sticking around, that means the same @current_user is too. >> >> > > Interesting, so it was "almost" a caching type issue... > > >> Not sure if there''s a good way to achieve what I''m trying to do -- it''s >> not particular the Hello user I want to test, but I want to test the >> number of items each user sees of a particular kind). Do separate tests >> for each case? Or loop through a test rather than the controller method? >> Or could (should?) I use integration tests (which i haven''t yet >> investigated)? >> > > I tend to subscribe to the ~1 assertion per test approach. Controller > tests already start to push that to 2-4 assertions so I definitely > wouldn''t combined tests for different aspects of the same functionality > into one test. So yes, I''d break up the test to separate cases. > >Think you''re prob right here.> Are you trying to test that the Model retreived the correct number of > things (in which case that would probably belong in a unit test of the > model, not the controller), or is there some controller side logic that > affects the list before rendering that you need to test? > >No , it''s not that (see below). Interestingly, though, I did on another controller have some functionality which the process of writing a test for led me to put the logic into the model, where it more properly belonged. +1 for tests helping to structure things better> Or are you testing that a list renders properly, perhaps with some > alternate text for cases where there are no elements? From a list > viewpoint, when I''m being pendantic in my tests, I''ll commonly take an > induction-based approach and write a test for each of the following: > base cases (empty list, one item list) > inductive case (assume it works for n, prove that it works for n+1) >Yes, it''s one of those case. Will try this out> Note, some testers talk about testing 0,1,2 and calling it "inductive", > but unless the test case for 2 is written properly its not inductive. > An inductive test case looks like: > def test_inductive_step_for_foo > current_result = foo.method_to_test > foo.add next_foo > assert_equal current_result+correct_delta, foo.method_to_test > end > (of course method names, variables, and mechanism for combining > current_result and correct_delta will vary, but the key point is that > _transformation_ from one state to the next is correct, not merely that > each state is correct.) > > Eric > >Thanks for the suggestions. Much appreciated
I found that you can just recreate a controller before you want to login with other user in the same test. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---