Testing confusion

ok, i’ve written a fairly feature rich rails app and right now i’m
catching up with myself by writing the tests for the damned thing.

currently getting the unit tests out of the way, but i have written one
functional test also…

here’s my problem… when i run rake test one of my test units flunks
horribly with a bunch of exceptions of the type “RuntimeError: Called
id for nil, which would mistakenly be 4 – if you really wanted the id
of nil, use object_id” … but when i run the test on its own it passes
with flying colors…

anybody know how this can be? i was under the impression that the tests
are completely isolated from each other.

thanks in advance,

stuart

Hi Stuart,

Whenever I’ve had difference in behavior from running individual tests
as
opposed to the rake command they’ve usually been 1 of 2 things:

  1. The database isn’t populated with the test data (you need to run rake
    at
    least once)
  2. The fixture declarations aren’t correct. Make sure you’re loading all
    the
    related objects that you’re using in your tests and that the
    relationships
    are all correct.

Hope that helps,
-Michael

When this has happened to me it has usually been one of 2-3 things:

  1. Fixtures. If you don’t have fixtures :foos in your testcase then the
    changes you make to table foos won’t be rolled back when your test is
    done, leaving the database in a state you don’t expect
  2. class variables, globals etc… These aren’t ‘reset’ after each test:
    You source files are loaded once and then all the tests are run.
    Slightly related is a problem we once had: we had some code with some
    external dependancy, and we forgot to have the appropriate
    require_dependency ‘blah’ in the controller, and so when you ran this
    one test case you would get a failure.
    This library was also used in another controller, for which we had
    remembered the require_dependancy, so if tests ran in the ‘right’ order
    then by the time the controller missing the require_dependency ran the
    library had already been loaded and so the tests ran fine

Hope that gives you some things to look at,

Fred

thanks for the input guys… so far still haven’t figured this one out…
i did learn some things about testing though with your help. any other
ideas?

stuart

That reminds of another issue I’ve seen before.
By default each test runs inside it’s own database transaction which is
rolled back at the end of the test.
The corollary is that if your test commits that transaction then at the
end of the test you won’t get that roll back.

In addition to an actual commit statement there are (at least on mysql)
a certain number of statements that cause an implicit commit (full list
available on mysql’s website), these tend to be things like create
table, drop index, etc…
Any test containing one of those will screw up the transactional
fixtures.

You can work round this by turning off transactional fixtures for that
test case.
In my particular case, the offending table was essentially a scratch
table, so my tests look something like

def test_foo
do_the_thing_implicitly_comitting_the_transaction
ActiveRecord::Base.connection.begin_db_transaction
#do rest of test
end

The newly created transaction ensures that everything else will be
rolled back at the end of the test

Fred

still trying to resolve this issue, but i have uncovered something
interesting. the issue is definetly that 2 of the fixtures just aren’t
getting along together. rake works fine with all test and either one of
the culprits, but if the 2 are in the same test suite they start to
complain.

still not sure how to remedy this or even what’s going on… i tried
changing the filenames and see if it would change the order that they
ran in and possibly rescue the test suite from the errors… no luck

i think i need more information about what exactly is going on between
unit tests… i don’t have any globals, class variables etc… i’ve
double checked that all fixtures that are needed are there (if i was
missing one wouldn’t the ruby test/unit/test.rb fail??)

really trying to get down to the bottom of this… any other ideas?

thanks,
stuart