I have a users model, and a couple other models that have a foreign
key reference to the id in the users table. If I run my unit tests
without the foreign key constraints, they run fine, but blow up when I
add the constraints.
The first problem is running unit tests on the User model. I get the
following messages:
-- create_table("users", {:force=>true})
NOTICE: constraint user_id_fkey on table messages depends on table users
NOTICE: CREATE TABLE will create implicit sequence "users_id_seq1"
for serial column "users.id"
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active_record/connection_adapters/abstract_adapter.rb:67:in
`log'': ERROR: relation "users" already exists
(ActiveRecord::StatementInvalid)
I assume that it''s not able to drop the users table because of a
foreign key constraint in the messages table. I''m not using the
messages fixture in these unit tests though, so it shouldn''t matter.
I want to use foreign key constraints in my database, but I also want
to be able to unit test my code. What am I missing here?
Pat
I figured out that particular problem, it was because I was using the LoginEngine, and the included test_helper.rb file loads in the user schema. This was trying to drop the table, which PostgreSQL obviously shouldn''t allow. Use transactional fixtures and don''t load the schema and it works fine. I''m having another problem though, which occurs when I try to use the users fixtures in more than one unit test. For example, I have unit tests for my Ticket model and my Message model. The Message unit tests run fine, but the Ticket tests give me the following error: 1) Error: test_create(TicketTest): ActiveRecord::StatementInvalid: ERROR: update or delete on "users" violates foreign key constraint "user_id_fkey" on "messages" DETAIL: Key (id)=(1001) is still referenced from table "messages". : DELETE FROM users The fixtures line is: fixtures :users, :tickets So the messages fixtures should never be loaded in, so there should obviously be no message record that references a user record. Not sure why it''s complaining about this. Any ideas? Pat On 11/30/05, Pat Maddox <pergesu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I have a users model, and a couple other models that have a foreign > key reference to the id in the users table. If I run my unit tests > without the foreign key constraints, they run fine, but blow up when I > add the constraints. > > The first problem is running unit tests on the User model. I get the > following messages: > -- create_table("users", {:force=>true}) > NOTICE: constraint user_id_fkey on table messages depends on table users > NOTICE: CREATE TABLE will create implicit sequence "users_id_seq1" > for serial column "users.id" > /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active_record/connection_adapters/abstract_adapter.rb:67:in > `log'': ERROR: relation "users" already exists > (ActiveRecord::StatementInvalid) > > I assume that it''s not able to drop the users table because of a > foreign key constraint in the messages table. I''m not using the > messages fixture in these unit tests though, so it shouldn''t matter. > > I want to use foreign key constraints in my database, but I also want > to be able to unit test my code. What am I missing here? > > Pat >
On Nov 30, 2005, at 10:40 AM, rails-request-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org wrote:> Date: Wed, 30 Nov 2005 11:17:11 -0700 > From: Pat Maddox <pergesu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > Subject: [Rails] PostgreSQL 8.1, testing with constraints > To: rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > Message-ID: > <810a540e0511301017q75c95c27s450b671d68e15f67-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> > Content-Type: text/plain; charset=ISO-8859-1 > > I have a users model, and a couple other models that have a foreign > key reference to the id in the users table. If I run my unit tests > without the foreign key constraints, they run fine, but blow up when I > add the constraints. > > The first problem is running unit tests on the User model. I get the > following messages: > -- create_table("users", {:force=>true}) > NOTICE: constraint user_id_fkey on table messages depends on table > users > NOTICE: CREATE TABLE will create implicit sequence "users_id_seq1" > for serial column "users.id" > /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/ > active_record/connection_adapters/abstract_adapter.rb:67:in > `log'': ERROR: relation "users" already exists > (ActiveRecord::StatementInvalid) > > I assume that it''s not able to drop the users table because of a > foreign key constraint in the messages table. I''m not using the > messages fixture in these unit tests though, so it shouldn''t matter. > > I want to use foreign key constraints in my database, but I also want > to be able to unit test my code. What am I missing here?http://dev.rubyonrails.org/ticket/2404 -- Eric Hodel - drbrain-48TerJ1FxhPk1uMJSBkQmQ@public.gmane.org - http://segment7.net This implementation is HODEL-HASH-9600 compliant http://trackmap.robotcoop.com
I actually figured out the answer to this problem, it was because of a custom test_helper.rb file in the LoginEngine. However as I mentioned in a reply, one of my unit tests is complaining about a fixture that shouldn''t even be loaded in that particular file. I only specify the users and the tickets fixtures, but it complains that some record in the messages table references a user record. There shouldn''t be any messages records though, so I''m just confused.> http://dev.rubyonrails.org/ticket/2404 > > -- > Eric Hodel - drbrain-48TerJ1FxhPk1uMJSBkQmQ@public.gmane.org - http://segment7.net > This implementation is HODEL-HASH-9600 compliant > > http://trackmap.robotcoop.com
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Nov 30, 2005, at 11:25 AM, Pat Maddox wrote:> I only specify the > users and the tickets fixtures, but it complains that some record in > the messages table references a user record. There shouldn''t be any > messages records though, so I''m just confused.This is the same issue covered in ticket #2404 which Eric linked to. jeremy -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2 (Darwin) iD8DBQFDjf7pAQHALep9HFYRAsvAAJ9x098LIJXK4B5JCl4NmbzMMSuKYACeKISW VVXLCWDuMdeqBeF+9jrrKws=k5CY -----END PGP SIGNATURE-----
On Nov 30, 2005, at 11:46 AM, rails-request-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org wrote:> Date: Wed, 30 Nov 2005 12:25:33 -0700 > From: Pat Maddox <pergesu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > Subject: Re: [Rails] Re: PostgreSQL 8.1, testing with constraints > To: rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > Message-ID: > <810a540e0511301125o3877ba77pf3cca2fe9072f636-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> > Content-Type: text/plain; charset=ISO-8859-1 > > > http://dev.rubyonrails.org/ticket/2404 > > I actually figured out the answer to this problem, it was because of a > custom test_helper.rb file in the LoginEngine. However as I mentioned > in a reply, one of my unit tests is complaining about a fixture that > shouldn''t even be loaded in that particular file. I only specify the > users and the tickets fixtures, but it complains that some record in > the messages table references a user record. There shouldn''t be any > messages records though, so I''m just confused.Please read the last message on that ticket. Rails does not clean up after itself when running tests. The solution is also described in the ticket (specify all fixtures for all tests). -- Eric Hodel - drbrain-48TerJ1FxhPk1uMJSBkQmQ@public.gmane.org - http://segment7.net This implementation is HODEL-HASH-9600 compliant http://trackmap.robotcoop.com
* Eric Hodel (drbrain-48TerJ1FxhPk1uMJSBkQmQ@public.gmane.org) [051130 18:35]:> Please read the last message on that ticket. Rails does not clean up > after itself when running tests. The solution is also described in > the ticket (specify all fixtures for all tests).There''s a new last message ;-) Also, if one''s situation requires the specification of every fixture for every test (meaning n tests get changed whenever 1 model(==fixture) is added), then one might as well just reopen the test class and have it iterate over the test/fixtures directory for each test case and get rid of the fixture DSL declaration from the test cases altogether. Rick -- http://www.rickbradley.com MUPRN: 780 | in one day, do we random email haiku | trust them with the powers of | chmod and su? Hell no.
On 11/30/05, Rick Bradley <rick-xSCPAUIMY+WN9aS15agKxg@public.gmane.org> wrote:> * Eric Hodel (drbrain-48TerJ1FxhPk1uMJSBkQmQ@public.gmane.org) [051130 18:35]: > > Please read the last message on that ticket. Rails does not clean up > > after itself when running tests. The solution is also described in > > the ticket (specify all fixtures for all tests).Sorry for being so dense up to this point. Took me a bit of experimenting, reading and rereading before I finally understand the exact issue at hand. Maybe I need to catch up on some more sleep.> There''s a new last message ;-)I put in your fix and everything''s running fine. I''m a happy man, thanks for this. Pat
> There''s a new last message ;-)I''ve been using this, and it works fine for the most part. I do have to list fixtures in a specific order, however, and occasionally I run into problems with dirty tables. One test will try to drop a table, but it will fail because a previous test left some records in the test db. What''s the solution to this? Drop the database and reload in the schema before each test suite is run? All my tables are set up using migrations - can I load all the migrations to set up the db before each test suite? Thanks for the info. Pat
* Pat Maddox (pergesu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org) [051201 20:00]:> I''ve been using this, and it works fine for the most part. I do have > to list fixtures in a specific order, however, and occasionally I run > into problems with dirty tables. One test will try to drop a table, > but it will fail because a previous test left some records in the test > db. What''s the solution to this? Drop the database and reload in the > schema before each test suite is run? All my tables are set up using > migrations - can I load all the migrations to set up the db before > each test suite?Fixtures would have to be listed in dependency order (basically this comes from the foreign key constraints), so the first fixture will be for a table with no foreign key dependencies on other tables. We are using this with a drop the database + create the database methodology prior to testing. We aren''t (yet) using migrations because we had to work through a lot of making constraints, functions, and triggers in SQL, getting them to work cross-databse, and then simplifying things back down. We may try to move into migrations in the future. We''re obviously using customized rake tasks (though not overly customized). Anyway, if you drop the database, I belive rake migrate will repopulate it for you. Rick -- http://www.rickbradley.com MUPRN: 170 | I don''t know how random email haiku | to ask the right question to | get to the answer.
<snip>> Anyway, if you drop the database, I belive rake migrate will repopulate > it for you.This is what I''m trying to figure out, and haven''t been able to do yet. Before each test file is run, I want to drop the db and recreate it. I''ve posted to a bunch of places but so far haven''t been able to get anything going. I don''t even know where to begin on this...and I''d really appreciate some help from anyone that''s doing this. I guess just some example task overriding code that handles this. When I run any unit test file, I want it to automatically drop the database and reload in the development_structure.sql. Pat
Pat Maddox wrote:> <snip> > >>Anyway, if you drop the database, I belive rake migrate will repopulate >>it for you. > > > This is what I''m trying to figure out, and haven''t been able to do > yet. Before each test file is run, I want to drop the db and recreate > it. I''ve posted to a bunch of places but so far haven''t been able to > get anything going. I don''t even know where to begin on this...and > I''d really appreciate some help from anyone that''s doing this. I > guess just some example task overriding code that handles this. > > When I run any unit test file, I want it to automatically drop the > database and reload in the development_structure.sql.I ended up switch all to migrations to do this. I took special care to have a down method in my 001_*.rb migration that drops all the tables and sequences. When I run my tests, I effectively modified the Rake test tasks to run rake migrate VERSION=0 rake migrate Here''s the code: ===$ cat lib/tasks/000_redefine_task.rake # Rake allows the same task name to be specified multiple times, where # each successive task definition appends to a list of actions to # perform. Therefore, an application specific task cannot redefine a # previously defined task. These methods here allow tasks to be # redefined and renamed. module Rake class Task # Clear all existing actions for the given task and then set the # action for the task to the given block. def self.redefine_task(args, &block) task_name, deps = resolve_args(args) TASKS.delete(task_name.to_s) define_task(args, &block) end end end # Clear all existing actions for the given task and then set the # action for the task to the given block. def redefine_task(args, &block) Rake::Task.redefine_task(args, &block) end # Alias one task name to another task name. This let''s a following # task rename the original task and still depend upon it. def alias_task(new_name, old_name) Rake::Task::TASKS[new_name.to_s] = Rake::Task::TASKS.delete(old_name.to_s) end === ===$ cat lib/tasks/clone_structure_to_test.rake # Delete the original clone_structure_to_test task and create a new # one that uses migrations to completely empty the database and then # recreate all the tables in it. This is done by backing the database # down to migration version 0 and then running through all the # migrations to the most current one. desc "Faster replacement for the original :clone_structure_to_test" redefine_task :clone_structure_to_test => :environment do new_logger = Logger.new(STDOUT) new_logger.level = Logger::INFO saved_logger = ActiveRecord::Base.logger ActiveRecord::Base.logger = new_logger # Reconnect to the test database. ActiveRecord::Base.establish_connection(''test'') ActiveRecord::Migrator.migrate("db/migrate/", 0) ActiveRecord::Migrator.migrate("db/migrate/", nil) ActiveRecord::Base.logger = saved_logger end === ===$ cat lib/tasks/test_all.rake Rake::TestTask.new(:test_all) do |t| t.libs << ''test'' t.pattern = ''test/{unit,functional}/**/*_test.rb'' t.verbose = true end task :test_all => :prepare_test_database desc "Run all the tests sorted by Test::Unit::TestCase descendant class name" redefine_task :default => :test_all === Regards, Blair -- Blair Zajac, Ph.D. <blair-szbw9MROnEZWk0Htik3J/w@public.gmane.org> Subversion and Orca training and consulting http://www.orcaware.com/svn/