Tests fine, but fail under rake

Hi there,

So I have an odd error at the moment that only occurs when I run tests
via rake. It’s happening with two tests now. Under a simple ruby run,
the tests are fine, e.g.:

D:\User\Code\ruby\prometheus>ruby
test\functional\story_comments_controller_test
.rb
Loaded suite test/functional/story_comments_controller_test
Started

Finished in 2.37 seconds.

9 tests, 65 assertions, 0 failures, 0 errors

However when I run rake I get this:

  1. Error:
    test_search(StoryCommentsControllerTest):
    ActionView::TemplateError: Couldn’t find Story without an ID AND (status
    = ‘approved’)
    On line #2 of app/views/story_comments/list.rhtml

1: <%unless params.has_key?(:search_terms)%>
2: <%= render_component(:controller => ‘stories’, :action => ‘show’,:id
=> params[:id], :params=>{:context=>‘small’})%>
3: <%else%>

Now the weird thing is, it that this line 2 of list.rhtml shouldn’t get
processed at all for this test:

def test_search
get :search, {:params => {:search_terms =>‘comment’}}, @session

assert_response :success
assert_template ‘list’
end

so running the test without rake produces the correct result, whereas
running with rake leads to this error. I get another similar template
based error under rake that also doesn’t occur when run without rake.

Has anybody seen anything similar? Have any idea how to fix this?

Many thanks in advance.
CHEERS> SAM

I was having some odd problems with fixtures over the weekend. Are you
using
them? When I manually deleted all data and reloaded then the tests
passed. I
was going to do some investigation to see if it was just me or a bug
somewhere but I haven’t had time yet.

Let me know if manually creating new fixture data in your setup() method
helps.

  • Byron

Hi Byron,

I am using fixtures - although the success or failure of this test
should be unrelated to them, i.e. the test in question doesn’t rely on
the presence or absence of data in the database.

Just in case I tried removing the fixtures from that functional test and
re-ran under rake and simple ruby command line. The presence or absence
of fixtures did not appear to have any effect on the test in question,
although interestingly the set of errors I got under rake was different
from what I got on the command line (i.e. in other tests where I would
expect fixtures to effect things), which suggests that as you say rake
and fixtures have some problems, but it doesn’t account for the
particular problem I am having.

Many thanks for your input.

CHEERS> SAM

I am still discovering new things about Raking tests myself, but I ran
into
some tests that would pass individually, but fail under rake a while
back.

In my situation is was because the developement and testing databases
were
out of sync. I believe that rake uses the schema from development to
initialize the testing db, but when you run tests individually, it does
not.

matt

Sam,

Your first post had an error on a retrieval… if the test_destroy was
called first and the fixtures aren’t properly resetting then this could
be
the problem.

  • Byron

Hi Byron,

Byron S. wrote:

Your first post had an error on a retrieval… if the test_destroy was
called first and the fixtures aren’t properly resetting then this
could be the problem.

It did, but the retrieval error comes not from the absence in the
database, but from a segment of code being called when there isn’t a
parameter being passed in necessary for it’s completion. The relevant
code is as follows:

1:<%unless params.has_key?(:id)%>
2: <%= render_component(:controller => ‘stories’, :action => ‘show’,:id
=> params[:id], params=>{:context=>‘small’})%>
3: <%else%>
4:

<%=@description%>


The point is that in absence of the id parameter, the line 2 shouldn’t
be executed at all, and it isn’t when the test runs standalone -
however, under rake, it does get executed, and I can’t work out why …

When the test does work (ruby command line or even using the rake
loader) I’ve checked the log and the incoming request is:

Processing StoryCommentsController#search (for 0.0.0.0 at 2006-02-07
19:36:43) [GET]
Parameters: {“action”=>“search”, “controller”=>“story_comments”,
“params”=>{“search
_terms”=>“comment”}}

while if I run the entire suite of tests with the rake_loader I get the
error, but the incoming request is identical:

Processing StoryCommentsController#search (for 0.0.0.0 at 2006-02-07
19:40:25) [GET]
Parameters: {“action”=>“search”, “controller”=>“story_comments”,
“params”=>{“search
_terms”=>“comment”}}

Anyhow, I just tried something else which is switching the test in the
template to the following:

<%unless params[:id].nil?%>

and the test now runs under all conditions. Clearly there is a
difference between params.has_key?[:id] and params[:id].nil? but it is
still strange that the former should be evaluated as true under one
testing environment, and not the other.

CHEERS> SAM

Hi Matthew,

Thats an interesting point about the databases. My impression is that
rake runs the equivalent of the rake task “clone_structure_to_test”
before running the tests. I’m not sure that the development schema in
db/development_structure.sql is involved, but I would be happy to be
corrected on this. [although I did just note that the
development_structure.sql file did appear to have been modified
following a rake test that I just tan]

I’ve managed to solve by first rake weirdness by adjusting the way a
conditional check was made - nothing to do with fixtures or the database
(see my other mail). Another weirdness seems to be that I can run these
sometimes failing tests fine with the rake loader, e.g.

d:/ruby/bin/ruby -Ilib;test
“d:/ruby/lib/ruby/gems/1.8/gems/rake-0.6.2/lib/rake/rake_test_loader.rb”
“test/unit/stories_controller_test.rb”

but they fail when the whole battery of tests is included (I don’t have
to run rake to get the failure - just the above command line with the
rake_test_loader).

My latest weirdness comes from a template failing to receive a variable,
which it does fine as a single rake loaded item, but fails when all the
other tests are added.

I can even log the creation of the variable all the way to where the
mailer class assigns it, and it’s there all present and correct, except
when some threshold number of tests are added to rake:

  1. Error:
    test_admin_preview_create(StoriesControllerTest):
    ActionView::TemplateError: You have a nil object when you didn’t expect
    it!
    The error occured while evaluating nil.title
    On line #1 of app/views/story_mailer/notify.rhtml
1: <%[email protected]%>
2: By: <%[email protected]_name%>
3: <%[email protected]%>

here’s the code that generates it:

def notify(controller,users,story,sent_at = Time.now)
@subject =
‘[’+CommunitySystem::CONFIG[:app_name]+’:story] '+ story.title
@body[‘story’] = story
logger.info 'notify_body_story: '+ @body[‘story’].inspect
@body[‘controller’] = controller

and here’s the logger output, showing the presence of the variable:

notify_body_story: #<Story:0x4b19370 @new_record=false,
@errors=#<ActiveRecord::Errors:0x4ae2260 @base=#<Story:0x4b19370 …>,
@errors={}>, @new_record_before_save=false, @attributes={“photo”=>nil,
“status”=>“approved”, “depttitle”=>“General”, “title”=>“what its about”,
“id”=>4, “caption”=>nil, “summary”=>“short but sweet”, “posted”=>Tue Feb
07 20:22:07 2006, “detail”=>“fine grained”, “authorid”=>1000006},
@story_comments=[]>

Now this works absolutely fine under all conditions, except if there are
more than about 12 tests being passed into the rake_loader. I’ve tested
previously and it doesn’t seem to matter which other tests they are,
just that once the number of incoming tests exceeds 11 or 12, then this
failure pops up.

Sorry to give you quite so much details, but I’m partly documenting this
to the list, because it is all so strange, and I’d like to think others
having the same problem will take some solace in that they are not
alone.

CHEERS> SAM

I am trying to populate a select() popup menu with all of the
currently entered options from the database. My thinking is that I
would search the database for all records, then call my “get_options”
with the name of the field as an argument.

def list
@assets = Asset.find(:all)
get_options(@assets,“asset_type”)
end

private
def get_options(items,field)
@options = []
items.each do |@item|
@options << @item.field
end
@options = @options.sort.uniq
end

This doesn’t work. However, if I replace:

   @options << @item.field

with:

   @options << @item.asset_type

(…where “asset_type” is the name of a field in the database) it
does work. Now, I’m trying to follow the DRY principles, but I can’t
figure out how to pass the field name to “get_options”. I could
write a dozen or so “get_options_asset_type”,
“get_options_serial_number” and the like and it would work, but this
is an opportunity for me to learn. How am I supposed to do this?

  • Peter

I am trying to populate a select() popup menu with all of the
currently entered options from the database. My thinking is that I
would search the database for all records, then call my “get_options”
with the name of the field as an argument.

def list
@assets = Asset.find(:all)
get_options(@assets,“asset_type”)
end

private
def get_options(items,field)
@options = []
items.each do |@item|
@options << @item.field
end
@options = @options.sort.uniq
end

This doesn’t work. However, if I replace:

   @options << @item.field

with:

   @options << @item.asset_type

(…where “asset_type” is the name of a field in the database) it
does work. Now, I’m trying to follow the DRY principles, but I can’t
figure out how to pass the field name to “get_options”. I could
write a dozen or so “get_options_asset_type”,
“get_options_serial_number” and the like and it would work, but this
is an opportunity for me to learn. How am I supposed to do this?

  • Peter

Hi –

On Fri, 10 Feb 2006, Peter T Bosse II wrote:

private
@options << @item.field
do this?
You can use send:

@options << @item.send(field)

You could tighten up the method a bit if you like (untested rewrite
follows):

def get_options(items,field)
@options = items.map {|item| item.send(field) }.sort.uniq
end

(I’ve changed @item to item as it wasn’t clear why that would need to
be an instance variable.)

David


David A. Black ([email protected])
Ruby Power and Light (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! Ruby for Rails