Unit test question

In development and production, I’ve got postgresql constraints that
prevent deleting a CaseManager if there is a Client that belongs to that
CaseManager.

In unit tests…and obviously in my testing db, those restrictions don’t
get added.

Is it wrong to test for deleting dependent records in unit tests?

Craig

Craig W. wrote:

In development and production, I’ve got postgresql constraints that
prevent deleting a CaseManager if there is a Client that belongs to that
CaseManager.

In unit tests…and obviously in my testing db, those restrictions don’t
get added.

Is it wrong to test for deleting dependent records in unit tests?

Craig

Craig -

Are you creating the constraints outside of your migrations? If you
create your constraints in your migrations (using EXECUTE) then your
test db should get built with them.

See:
http://www.robbyonrails.com/articles/2005/11/11/rails-migrations-and-postgresql-constraints

Change your schema dumping to :sql - the ruby schema dumper doesn’t
know about foreign key constraints etc…

Fred

On Jun 5, 2008, at 9:04 AM, Craig W. wrote:

“fk_cp_case_manager” for relation “clients” already exists

and this constraint does exist in development db and production db but
still doesn’t exist in test db.

and so I tried to run rake test:functionals with the schema_dumper
setting to sql instead of ruby and it failed too…

So I’m confused.

Craig

Try just: rake test
or even: rake

These cause the db:test:clone task to run.
(you could do: rake db:test:clone test:units )

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

On Thu, 2008-06-05 at 01:55 -0700, Frederick C. wrote:

Change your schema dumping to :sql - the ruby schema dumper doesn’t
know about foreign key constraints etc…


OK did that…but when I run rake test:units

I see…

psql:db/development_structure.sql:2071: ERROR: constraint
“fk_cp_case_manager” for relation “clients” already exists

and this constraint does exist in development db and production db but
still doesn’t exist in test db.

and so I tried to run rake test:functionals with the schema_dumper
setting to sql instead of ruby and it failed too…

So I’m confused.

Craig

Cayce B. wrote:

Craig W. wrote:

Is it wrong to test for deleting dependent records in unit tests?

Are you creating the constraints outside of your migrations? If you
create your constraints in your migrations (using EXECUTE) then your
test db should get built with them.

And to answer the question: Yes, test it. Tests could cover every moving
part.

Better, write a test that fails, before you write this EXECUTE logic to
pass it.

(But why not just use :dependent => :destroy?)

Craig W. wrote:

psql:db/development_structure.sql:2071: ERROR: constraint
“fk_cp_case_manager” for relation “clients” already exists

and this constraint does exist in development db and production db but
still doesn’t exist in test db.

rake RAILS_ENV=test db:migrate:reset

?

(And is the RAILS_ENV=test needed?)

The test database is often a clone of the development schema, so maybe
you
should switch your schema to .sql format like Fred said.

However, I would never put business logic in the schema if this would
prevent me
from using SQLite3 to run super-fast tests…

On Thu, 2008-06-05 at 06:26 -0700, Phlip wrote:

Craig W. wrote:

psql:db/development_structure.sql:2071: ERROR: constraint
“fk_cp_case_manager” for relation “clients” already exists

and this constraint does exist in development db and production db but
still doesn’t exist in test db.

rake RAILS_ENV=test db:migrate:reset


it doesn’t appear that this is possible in Rails 1.2.6

(And is the RAILS_ENV=test needed?)

The test database is often a clone of the development schema, so maybe you
should switch your schema to .sql format like Fred said.


I did

However, I would never put business logic in the schema if this would prevent me
from using SQLite3 to run super-fast tests…


it’s a thought but right now, I’m still working on things.

Craig

On Thu, 2008-06-05 at 06:23 -0700, Phlip wrote:

And to answer the question: Yes, test it. Tests could cover every moving part.

Better, write a test that fails, before you write this EXECUTE logic to pass it.

(But why not just use :dependent => :destroy?)


because a CaseManager has_many clients so I couldn’t use dependent =>
destroy

Thanks

Craig

On Thu, 2008-06-05 at 05:34 +0200, Cayce B. wrote:

Craig

Craig -

Are you creating the constraints outside of your migrations? If you
create your constraints in your migrations (using EXECUTE) then your
test db should get built with them.

See:
http://www.robbyonrails.com/articles/2005/11/11/rails-migrations-and-postgresql-constraints


Yes…all of my constraints were added inside of migrations but no, the
test db tables seem to have none of the constraints but the development
and production tables all do. I presume that is because the migrations
were specifically executed in both modes.

Craig

On Wed, 2008-06-04 at 17:48 -0700, Craig W. wrote:

In development and production, I’ve got postgresql constraints that
prevent deleting a CaseManager if there is a Client that belongs to that
CaseManager.

In unit tests…and obviously in my testing db, those restrictions don’t
get added.

Is it wrong to test for deleting dependent records in unit tests?


OK simplifying my problem…

$ grep schema config/environment.rb

Use Active Record’s schema dumper instead of SQL when creating the

test database
#config.active_record.schema_format = :ruby
config.active_record.schema_format = :sql

so my schema_format is sql

$ rake db:schema:dump
(in /home/craig/svn-new/th-db/branches/phase5)

but there’s no constraints in schema.rb

Why?

Craig

On 5 Jun 2008, at 15:53, Craig W. wrote:

so my schema_format is sql

$ rake db:schema:dump
(in /home/craig/svn-new/th-db/branches/phase5)

but there’s no constraints in schema.rb

because the :sql schema dumper doesn’t dump into schema.rb (it dumps
into development.sql). Maybe the sql dumper for postgres is screwing
up, but it is certainly the case that with mysql this does result in
the test db having the appropriate foreign key constraints.

Fred

On Thu, 2008-06-05 at 15:56 +0100, Frederick C. wrote:

In unit tests…and obviously in my testing db, those restrictions
#config.active_record.schema_format = :ruby
into development.sql). Maybe the sql dumper for postgres is screwing
up, but it is certainly the case that with mysql this does result in
the test db having the appropriate foreign key constraints.


I’m still on 1.2.6 - does this make a difference?

I don’t get a development.sql file as a result but I do get an updated
file db/schema.rb

curiously enough…

rake db:test:clone_structure creates a file db/development_structure.sql
that does indeed contain all of the constraints.

Craig

On 5 Jun 2008, at 16:06, Craig W. wrote:

CaseManager.

Use Active Record’s schema dumper instead of SQL when creating the

curiously enough…

rake db:test:clone_structure creates a file db/
development_structure.sql
that does indeed contain all of the constraints.

I’m not quite awake today. If i recall correctly schema:dump (by
definition) does a ruby schema dump into schema.rb, clone_structure
does an sql structure dump into development_structure.sql
The config setting controls what is done and used when

Fred

On Thu, 2008-06-05 at 16:28 +0100, Frederick C. wrote:

In development and production, I’ve got postgresql constraints that
OK simplifying my problem…
(in /home/craig/svn-new/th-db/branches/phase5)
I don’t get a development.sql file as a result but I do get an updated
definition) does a ruby schema dump into schema.rb, clone_structure
does an sql structure dump into development_structure.sql
The config setting controls what is done and used when


OK - you’re confirming what I am seeing.

My problem is that running tests such as ‘rake test:functionals’ or
‘rake test’ drops the db and recreates it from schema.rb and the
postgresql constraints aren’t in schema.rb and don’t get dumped to
schema.rb so I’m struggling here.

Craig

On Thu, 2008-06-05 at 08:34 -0700, Craig W. wrote:

On Wed, 2008-06-04 at 17:48 -0700, Craig W. wrote:

$ rake db:schema:dump

I’m not quite awake today. If i recall correctly schema:dump (by
definition) does a ruby schema dump into schema.rb, clone_structure
does an sql structure dump into development_structure.sql
The config setting controls what is done and used when


OK - you’re confirming what I am seeing.

My problem is that running tests such as ‘rake test:functionals’ or
‘rake test’ drops the db and recreates it from schema.rb and the
postgresql constraints aren’t in schema.rb and don’t get dumped to
schema.rb so I’m struggling here.


OK thinking that I can just insert my constraints at the bottom of
schema.rb - I am trying to run them in ‘script/console test’

execute ‘ALTER TABLE ONLY assessments ADD CONSTRAINT
fk_associations_personnel FOREIGN KEY (personnel_id) REFERENCES
personnels(id);’
NoMethodError: undefined method `execute’ for #Object:0xb809f9a8
from (irb):58

and they don’t seem to work at the bottom of schema.rb (before the final
‘end’) either.

but they work inside of migrations…

I need a hand here

Craig

[Please trim your quotes, to make your posts easy to read. And whoever
is adding
cruft to the Subject line please trim it too!]

Craig W. wrote:

My problem is that running tests such as ‘rake test:functionals’ or
‘rake test’ drops the db and recreates it from schema.rb and the
postgresql constraints aren’t in schema.rb and don’t get dumped to
schema.rb so I’m struggling here.


OK thinking that I can just insert my constraints at the bottom of
schema.rb - I am trying to run them in ‘script/console test’

You are trying “too hard” to do things the wrong way. The right way is
to add
indexes with add_index, and then to enforce further constraints with
Ruby code,
not necessarily with database code.

If you simply must do things like this, do not write on schema.rb (or
integrate
it into your Version Controller). It is an automatic, write-only file.
Same with
development.sql.

execute ‘ALTER TABLE ONLY assessments ADD CONSTRAINT
fk_associations_personnel FOREIGN KEY (personnel_id) REFERENCES
personnels(id);’
NoMethodError: undefined method `execute’ for #Object:0xb809f9a8

.execute is not a method of the Ruby God Object. It’s a method of either
ActiveRecord::Base or ActiveRecord::Base.connection.

but they work inside of migrations…

That’s because the migrator inherits the right ActiveRecord:: stuff.
But…

Testing is more important than putting this or that constraint into the
database. Do whatever it takes to provide your tests with a simple
database
that they can beat on. Leave this fine-tuning for later, after you have
enough
real data in your database that you can detect the real slow spots!

On Thu, 2008-06-05 at 06:41 -0700, Craig W. wrote:


Yes…all of my constraints were added inside of migrations but no, the
test db tables seem to have none of the constraints but the development
and production tables all do. I presume that is because the migrations
were specifically executed in both modes.


It occurs to me now as I’m thinking about it…that I did completely run
migrations on my test db and it had all of the table constraints in my
migrations. My unit tests all worked.

Then when I moved on to functional tests and then finally did
rake test:functionals
that it dropped the db and recreated it - I presume from my schema.db
which doesn’t have any of the postgres constraints that are in my
migrations, which is why my unit tests now fail.

So I guess my issue is to figure out how to get the constraints back and
keep them.

Craig

On Thu, 2008-06-05 at 19:09 -0700, Phlip wrote:

You are trying “too hard” to do things the wrong way. The right way is to add
indexes with add_index, and then to enforce further constraints with Ruby code,
not necessarily with database code.

If you simply must do things like this, do not write on schema.rb (or integrate
it into your Version Controller). It is an automatic, write-only file. Same with
development.sql.


I do actually enforce things in controller code (i.e., you can’t
‘destroy’ a CaseManager that has clients but that method doesn’t kick in
with unit tests. That’s why I asked at the start of the thread if I am
doing things wrong here.

If there is a way to ‘protect’ me from deleting a CaseManager that has a
Client within the model, I’ve not figured a way to do that…(Class
CaseManager has_many :clients - Class Client belongs_to :case_manager)

Maybe I’m just too dumb but it seems to me that the table constraints
within postgres not only protect me from dumb actions in other software
applications but also protected me from failing to catch bad ‘destroy’
actions that had related records in rails.

execute ‘ALTER TABLE ONLY assessments ADD CONSTRAINT
fk_associations_personnel FOREIGN KEY (personnel_id) REFERENCES
personnels(id);’
NoMethodError: undefined method `execute’ for #Object:0xb809f9a8

.execute is not a method of the Ruby God Object. It’s a method of either
ActiveRecord::Base or ActiveRecord::Base.connection.


clearly

but they work inside of migrations…

That’s because the migrator inherits the right ActiveRecord:: stuff. But…

Testing is more important than putting this or that constraint into the
database. Do whatever it takes to provide your tests with a simple database
that they can beat on. Leave this fine-tuning for later, after you have enough
real data in your database that you can detect the real slow spots!


I have a bunch of data in my production db and my development db is my
production db from January and migrated up to current. I am going
backwards by trying to institute testing.

I have my controller tests virtually up to date and they work. I had
unit tests working when I was running migrations on my test db.

The unit tests broke when I did things like ‘rake test:functionals’ or
‘rake db:test:clone’ etc. which give all appearance to drop the test db
and recreate it from schema.rb (I’m surmising that this is what is
occurring). With that, I lost the postgres ‘CONSTRAINTS’ which I was
relying upon in some of my unit tests. If this is a bad concept to test
for…then I will remove them.

At the start of this thread I asked… and still haven’t a clue why:

  • testing like ‘rake test:functionals’ or ‘rake test:units’ acts as user
    postgres when I don’t specify user postgres anywhere in database.yml at
    all. This completely defies explanation…I even went through my plugins
    and removed the postgres user from all plugin tests.

  • none of the commands like ‘rake db:test:clone’ or ‘rake
    db:test:clone_structure’ actually clone the development db including
    things like ‘CONSTRAINTS’ (and I presume TRIGGERS but I am not using
    them at the moment).

  • using a postgres schema for testing seems pointless and counter
    productive. I’ve given that up completely. Someone suggested sqllite for
    test db which does make sense and I may end up going that route.

Thanks Phlip (and Frederick/Cayce/Rob)

Craig

  • using a postgres schema for testing seems pointless and counter
    productive. I’ve given that up completely. Someone suggested sqllite for
    test db which does make sense and I may end up going that route.

Although there is an argument to say that your test environment should
be close to the production environment. You don’t want to find
yourself writing code that works fine in sqlite, all tests pass
etc… but which doesn’t in postgres.
It’s also a fact that rails validations etc… cannot guarantee
integrity. Only the database can do that. And if your production
environment enforces that but your tests don’t then you could be
building up to a problem: imagine that somewhere you accidentally
leave a dangling reference. The test database has no constraints and
doesn’t care. The day you click that button in production postgres
throws a wobbly because of a foreign key violation.
I still don’t get why it doesn’t work though. You indicate that
development_structure.sql (which is produced using pg_dump_ contains
the constraints and all rake db:test:clone_structure does is pipe that
file into psql so it’s really odd that it’s not working. If you know
postgres well you could check the rake tasks to check they are
invoking pg_dump and psql appropriately. With the :sql setting
schema.rb should be touched at all and yet it is, which is just plain
odd.
Anyway, rake db:test:clone_structure should create
development_structure.sql and load it into the test db, but if that’s
not working it’s beyond me why,

Fred