Problem using `rake test` - ruby-on-rails

I wonder how to setup testing in my rails apps. When I run rake test, first thing odd, it launch a bunch of CREATE TABLE against my dev. database (hum.. do not like this..). So I launch rake test RAILS_ENV=test and I even try bundle exec rake test RAILS_ENV=test. Now, the CREATE TABLE is against my test database but all fails with this error :
** Execute test:units
test/unit/category_test.rb:5:in `test': unknown command 't' (ArgumentError)
from test/unit/category_test.rb:5:in `<class:CategoryTest>'
I have used basic generator in Rails 3 and do not change anything. So I have this in caterogy_test.rb :
require 'test_helper'
class CategoryTest < ActiveSupport::TestCase
# Replace this with your real tests.
test "the truth" do
assert true
end
end
I use Rails 3.0.7 and basic config.
Any ideas ?
EDIT
I am becoming crazy, made a lot of tries, neither seems to work. When I start a new application with a few things, rake test works fine but when I try this on my current one, it launch always against my dev. db and do not work at all. I have tried to edit the test files, to revert them back, try to remove/setup test db with different ways, try different rake version, compare a lot of things on one side my current application and on the other a brand new one... Found nothing.. Help !
EDIT 2
Sounds lame, but is it normal that rake does the same thing than rake test ?
EDIT 3
Sounds odds, while I continue to work on what's wrong, I realize that every-time I run rake test, it does stuff on the dev environment and not the test one (watching the logs). It does this on my computer OSX and on our server FreeBSD for all the Rails 3.0.7 apps. Are you sure rake test is supposed to work on the test environment by default ?
EDIT 4
Please help!
EDIT 5 - SUMMARY
When running rake test in my computer or on our server in Rails 3.0.7 with different apps it does the following :
run CREATE TABLE and INSERT INTO migration against the dev. db.
do not empty the dev. db.
development.log gets written not the test.log
also an issue with the error unknowm comman 't' with one specific app.
EDIT 6 - db config
Nothing change from the default yet : https://gist.github.com/1006199
EDIT 7
rake db:test:prepare --trace -> nothing break (but keep printing (first_time)
https://gist.github.com/1007340
With RAILS_ENV="test" for rake, everything goes fine. It write on the test logs.
ruby -I test test/unit/category_test.rb same erros than with rake, but no write on the dev. or test logs.

a bunch of unorderd answers:
the "CREATE TABLE" statements usually means that your test_db is created from scratch (by default, before test task, a db:migrate is launched). are you sure they're called on dev_db?
also check your config/database.yml to see if there's some typo (eg: using same table for test and dev environments)
it looks like there's an error in some of your migration files (that 't' error remember blocks in migrations).
"rake test" is the default task, that's why it's run when you just launch "rake" without arguments.
EDIT:
according on what I see on edits, from 5 and above, it looks like you have some issue with environment files. so try to double-check:
* config/environments/test.rb
* config/application.rb
* config/environment.rb
if with RAILS_ENV="test", everything goes fine, then I'm almost sure you have changed some default behaviour in your app (configs, env variables, any particular gem?)
also, in your test/test_helper.rb, add RAILS_ENV='test' at the beginning of file, this should force test environment.

I had that same error message, except to me it said: in `test': unknown command 'i' (ArgumentError).
The 'fix' or 'workaround' was to simply use:
$> bundle exec rake test
instead of using 'rake test'

Related

What is the correct way to run Rails tests without invoking the development environment?

I have an Rails app, with some initializer code which must be executed when the app is running in development mode. However, this initializer code must not be executed when running tests.
I have established that
$ rake test
causes the app to be run in development mode, which invokes the initializer code and therefore breaks my tests. This is expected behaviour apparently (see: https://github.com/rails/rails/issues/9801).
What is the correct command to run my Rails app tests without starting the app in development mode?
Does your test_helper.rb file look like the default? It should start with:
ENV["RAILS_ENV"] = "test"
Try running the rake task with an explicit environment:
rake test:units RAILS_ENV=test
If you don't specify an environment, development is assumed, in my experience. And while the test database still gets the fixture data inserted into it, stuff from the development environment still gets referenced for some reason.
You need to have a line at the start of the test_helper.rb file that says
Rails.env = "test"
You can't use
ENV["RAILS_ENV"] = "test"
because it will fail to clear the cached value that returns from calls to Rails.env.

Rails can't execute rake task

Rails won't fire off a rake command from my controller because it can't find rake. I know this because I experienced this in my dev environment and fixed it by giving it the absolute path to rake. However this solution isn't working my production environment.
Things I know:
I can run the rake task rom cli
I can run it through irb with a: system "rake ..."
I can't find any errors!
Rakes:
/usr/lib/ruby/1.9.1/rake
/usr/lib/ruby/gems/1.9.1/bin/rake
/usr/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake
/usr/lib/ruby/gems/1.9.1/gems/rake-0.9.2/bin/rake
/usr/lib/ruby/gems/1.9.1/gems/rake-0.9.2.2/lib/rake
/usr/lib/ruby/gems/1.9.1/gems/rake-0.9.2.2/bin/rake
/usr/lib/ruby/gems/1.9.1/gems/rake-0.8.7/lib/rake
/usr/lib/ruby/gems/1.9.1/gems/rake-0.8.7/bin/rake
/usr/bin/rake
/var/lib/gems/1.8/bin/rake
/var/lib/gems/1.8/doc/rake-0.9.2.2/rdoc/lib/rake
/var/lib/gems/1.8/gems/rake-0.9.2.2/lib/rake
/var/lib/gems/1.8/gems/rake-0.9.2.2/bin/rake
/var/lib/gems/1.8/gems/rake-0.8.7/lib/rake
/var/lib/gems/1.8/gems/rake-0.8.7/bin/rake
/var/lib/gems/1.8/gems/sprockets-2.3.1/lib/rake
How in the heck do I go about troubleshooting this???
The rake task I was calling in production was failing because of my attempt to dump it's contents into a log with logger disabled.
system "rake invite INVITE_ID=5 RAILS_ENV=production >> /root/log/rake.log &"
Thanks for all your help...sorry for being so vague. I was just looking for quick responses hoping I was doing something stupid. Which I was. I SWEAR I tried it without the log entry...probably moving too fast like I always do.
Also, just to answer a couple questions. The rake task I'm using is an internal tool I use myself for some maintenance and want to simply offload that task to my coworker who uses an app I've built. There's no need to industrialize it with a scheduler, etc...

rake db:schema:dump show no fields with rails 3.2.3 and SQL Server 2008

I am migrating an app from rails 2.3.8 to 3.2.3. The 'rake db:schema:dump' works fine in rails 2.3
but generates only the tables names with no column names in rails 3.2.
Even for the app to connect successfully through the console, I had to change config/application.rb to include
ActiveRecord::Base.table_name_prefix = 'dbo.'
Do I need to do something different for the rake task to pick up these prefixes? Or is something else causing the missing column names problem?
Further clarification:
I am looking for rake db:schema:dump because the programmers on site stopped using migrations and started making changes to the db directly. Now I am trying to restart using migrations. The first step recommended in the process is to use the schema dump as the starting point. Also, (and I am not sure) it is needed for the tests to rebuild the test db from the development db.
Short answer:
db:schema:dump isn't the right thing to use, but you can add a few lines of code to your Rakefile to get the outcome you want.
Longer answer:
The scuttlebutt is that the task db:schema:dump is actually not supposed to dump anything more than the structure. (I know, it's a misnomer.) It's analagous to db:structure:dump, except that the one gives you an .rb file, and the other gives you a .sql file.
You can create your own dumping rake task by appending the following code to your Rakefile:
For SQL 2008
task :mydump do
ActiveRecord::Base.connection.execute(
"dbcc traceon(2544, -1) \n go \n dbcc traceon(2546, -1) \n go \n dbcc stackdump"
)
end
Using the SQL server itself to create the dump (which is what the forgoing code does) limits you because the dump will always go to your log directory; you cannot specify otherwise.
If you use SqlDumper or some other utility, you will have more freedom. You can call such a utility from your rake task by executing it as through from the command line, using the system method. (See the example for MySQL below, which uses the mysqldump utility.)
(I have not tested the forgoing code, not having an installation of SQL 2008, myself, but the raw SQL code for creating a dump from with the SQL server is explained on this blog.)
Running the rake task
Then on your command line, call rake mydump or rake mydump RAILS_ENV=production.
For MySQL
You could do something similar for MySQL with the following:
task :mydump do
config = Rails.configuration.database_configuration[Rails.env]
system "mysqldump -h #{config["host"]} -u #{config["username"]} -p#{config["password"]} #{config["database"]} > db/dump.sql"
end

rails test database errors with postgresql on OSX

So I have recently migrated to postgresql, and have been having issues with my test database creation. Whenever I run a rake task it seems to destroy my ability to access the test database that I have created. For example, if I run the following command
createdb -Ouser -Eutf8 example_test
I can run tests perfectly, however if I run a rake task I will get the following error:
.rvm/gems/ruby-1.9.2-p180#standard/gems/activerecord-3.1.0/lib/active_record/connection_adapters/postgresql_adapter.rb:991:in `initialize': FATAL: database "example_test" does not exist (PGError)
If I create a new test database like so:
createdb -Ouser -Eutf8 example2_test
Everything will work again, until I have to run a rake task. Does anyone know what this issue could be?
Fixed the bug, by finding the following blog post about the topic: http://katrinaowen.com/2011/01/05/using-postgresql-with-rails-3-cucumber-and-rspec
In short, this was a bug with creating databases with rspec installed, view the link and run the commands to get it to work on your system.
Perhaps you can look at log/development.log to see why the database is being dropped? And look at the rake task code itself to see what it is doing.
Usually the test database is generated via rake db:test:prepare based on config/database.yml

How do I prepare test database(s) for Rails rspec tests without running rake spec?

After significant troubleshooting, I figured out that I needed to run rake spec once (I can abort with control-c) before I can run rspec directly (e.g. on a subset of our specs). We are running Rails 3.0.7 and RSpec 2.5.0.
Clearly, rake is running some important database setup tasks / code (we have custom code in the root level rails Rakefile and possibly other places).
How can I run the rake test database setup tasks / code without running rake spec?
In addition to being able to run rspec on a subset of files, I am using specjour to spread our specs across multiple cores (haven't had success with spreading them across the LAN yet), but I see the same behavior as for running rspec directly: I need to run rake spec on each test database (assuming two cores) before specjour works:
rake spec TEST_ENV_NUMBER=1
control-c (after tests start)
rake spec TEST_ENV_NUMBER=2
control-c (after tests start)
specjour
Note: my config/database.yml has this entry for test (as is common for the parallel testing gems):
test:
adapter: postgresql
encoding: unicode
database: test<%=ENV['TEST_ENV_NUMBER']%>
username: user
password:
parallel_tests seems to set up its databases correctly, but many of our specs fail.
I should also mention that running specjour prepare causes Postgres to log errors that it can't find the databases, but it creates them (without tables). On a subsequent run, no errors are logged, but also no tables are created. It is possible that my whole issue is simply a bug in prepare, so I reported it on github.
I think that I can run arbitrary code on each specjour test database by setting Specjour::Configuration.prepare in .specjour/hooks.rb, so if there's any rake tasks or other code that I need to run, it may work there.
I would recommend dropping your test database, then re-create it and migrate:
bundle exec rake db:drop RAILS_ENV=test
bundle exec rake db:create RAILS_ENV=test
bundle exec rake db:schema:load RAILS_ENV=test
After these steps you can run your specs:
bundle exec rspec spec
gerry3 noted that:
A simpler solution is to just run rake db:test:prepare
However, if you're using PostgreSQL this wont work because the rails environment gets loaded, which opens a database connection. This causes the prepare call to fail, because the DB cannot be dropped. Tricky thing.
I had a similar problem setting up the CI system at work, so I gradually worked up a system to handle this. It may not be the best solution, but it works for me in my situation and I'm always on the lookout for better ways to do things.
I have a test database that I needed setup, but also needed seeded data loaded for our tests to work.
The basics of troubleshooting rake tasks is to run rake with the --trace option to see what is happening under the hood. When i did this, I found that running rake spec did a number of things that I could replicate (or modify as I saw fit) in a custom rake task.
Here's an example of what we do.
desc "Setup test database - drops, loads schema, migrates and seeds the test db"
task :test_db_setup => [:pre_reqs] do
Rails.env = ENV['RAILS_ENV'] = 'test'
Rake::Task['db:drop'].invoke
Rake::Task['db:create'].invoke
result = capture_stdout { Rake::Task['db:schema:load'].invoke }
File.open(File.join(ENV['CC_BUILD_ARTIFACTS'] || 'log', 'schema-load.log'), 'w') { |f| f.write(result) }
Rake::Task['db:seed:load'].invoke
ActiveRecord::Base.establish_connection
Rake::Task['db:migrate'].invoke
end
This is only an example, and specific to our situation, so you'll need to figure out what needs to be done to get your test db setup, but it is quite easy to determine using the --trace option of rake.
Additionally, if you find the test setup is taking too long (as it does in our case), you can also dump the database into .sql format and have the test database pipe it directly into mysql to load. We save several minutes off the test db setup that way. I don't show that here because it complicates things substantially -- it needs to be generated properly without getting stale, etc.
HTH
The provided solutions all require to load the Rails environment, which is, in most cases, not the desired behaviour due to very large overhead and very low speed. DatabaseCleaner gem is also rather slow, and it adds another dependency to your app.
After months of chagrin and vexation thanks to reasons vide supra, I have finally found the following solution to be exactly what I need. It's nice, simple and fast. In spec_helper.rb:
config.after :all do
ActiveRecord::Base.subclasses.each(&:delete_all)
end
The best part about this is: It will only clear those tables that you have effectively touched (untouched Models will not be loaded and thus not appear in subclasses, also the reason why this doesn't work before tests). Also, it executes after the tests, so the (hopefully) green dots will appear right away.
The only downside to this is that if you have a dirty database before running tests, it will not be cleaned. But I doubt that is a major issue, since the test database is usually not touched from outside tests.
Edit
Seeing as this answer has gained some popularity, I wanted to edit it for completeness: if you want to clear all tables, even the ones not touched, you should be able to do something like the "hacks" below.
Hack 1 - pre-loading all models for subclasses method
Evaluate this before calling subclasses:
Dir[Rails.root.join("app", "models", "**", "*.rb")].each(&method(:require))
Note that this method may take some time!
Hack 2 - manually truncating the tables
ActiveRecord::Base.connection.tables.keep_if{ |x| x != 'schema_migrations' }
will get you all table names, with those you can do something like:
case ActiveRecord::Base.configurations[Rails.env]["adapter"]
when /^mysql/, /^postgresql/
ActiveRecord::Base.connection.execute("TRUNCATE #{table_name}")
when /^sqlite/
ActiveRecord::Base.connection.execute("DELETE FROM #{table_name}")
ActiveRecord::Base.connection.execute("DELETE FROM sqlite_sequence where name='#{table_name}'")
end
It appears that in Rails 4.1+, the best solution is simply to add ActiveRecord::Migration.maintain_test_schema! in your rails_helper after require 'rspec/rails'.
i.e. you don't have to worry about having to prepare the database anymore.
https://relishapp.com/rspec/rspec-rails/docs/upgrade#pending-migration-checks
In a spring-ified Rails 4 app, my bin/setup is usually augmented to contain
puts "\n== Preparing test database =="
system "RAILS_ENV=test bin/rake db:setup"
This is very similar to leviathan's answer, plus seeding the test DB, as
rake db:setup # Create the database, load the schema, and initialize with the seed data
(use db:reset to also drop the database first)
As the comment mentions, if we want to drop the DB first, rake db:reset does just that.
I also find that this provides more feedback when compared to rake db:test:prepare.
I started by dropping my test database
rake db:drop RAILS_ENV=test
when trying to create a new test database I ran into an issue because my user account was not the same as the account that owns the databases so I created the database in PostgreSQL instead.
type psql in the command prompt and then run the below to create a test database that uses an account other than your own.
CREATE DATABASE your_database_name OWNER your_db_owner;
then run your migrations in the test environment.
rake db:migrate RAILS_ENV=test

Resources