70

On Rails 4.0.0.rc1, Ruby 2.0.0, after I run a migration, I see the following error when I try to run a test through rspec:

/Users/peeja/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0.rc1/lib/active_record/migration.rb:376:in `check_pending!': Migrations are pending; run 'rake db:migrate RAILS_ENV=test' to resolve this issue. (ActiveRecord::PendingMigrationError)

That doesn't seem right. No one migrates their test database, do they? They db:test:prepare it, which—to be fair—I've forgotten to do. So I run rake db:test:prepare and run my rspec command again…and see the same error.

If I actually rake db:migrate RAILS_ENV=test, the error does in fact go away.

What's going on? Is this new in Rails 4?

abraham
  • 46,583
  • 10
  • 100
  • 152
Peeja
  • 13,683
  • 11
  • 58
  • 77

7 Answers7

78

As of Rails 4.1, the rake db:test:* tasks are deprecated. Instead, your (test|spec)_helper.rb should include:

ActiveRecord::Migration.maintain_test_schema!

This means that your test database will get the correct schema every time your tests run, whether you run them from a Rake task or not.

Peeja
  • 13,683
  • 11
  • 58
  • 77
  • Thanks for that one, I've actually missed that one when 4.1 got released I guess. – jipiboily Oct 23 '14 at 01:25
  • 2
    This is correct and is the best way to me to keep up to date your test database. The error being that _you have pending migrations to run_. But if anyone don't want to follow this great workaround, I suggest you delete the Test Database and run afresh `rake db:create RAILS_ENV=test` to re-create your test database, and the run `rake db:migrate RAILS_ENV=test` just to migrate the test database. I do this often when am yet to write tests for my application. – Afolabi Olaoluwa Sep 01 '16 at 21:10
  • 1
    I can see this line in `tests_helper.rb` in rails 5 out of box – Abhilash Feb 25 '17 at 04:21
  • Be careful with this. If you have multiple test database connections and do not have migration files for all them, ActiveRecord::Migration.maintain_test_schema! will not load the development schema into the into the test schema for those connections and you will still have to load it manually. – jlesse Mar 31 '17 at 21:31
  • BTW I couldn't get this to work with `Test::Unit` (e.g. in `test/test_helper.rb`) – Dorian Oct 16 '17 at 09:50
31

Looks like rake test:prepare works, not sure what db:test:prepare now does.

Kris
  • 19,188
  • 9
  • 91
  • 111
  • Wow. Hit it on the head. Thanks! https://gist.github.com/Peeja/5831155 Now to file a Rails bug… – Peeja Jun 21 '13 at 13:33
  • 1
    Huh. When I first posted that I missed that `test:prepare` *is* calling (depending on) `db:test:prepare`. All the good stuff seems to happen outside of `db:test:prepare`, though. Here's the Rails code: https://github.com/rails/rails/blob/067e1505d4e054df566e065f4faf11ee4b430a3d/activerecord/lib/active_record/railties/databases.rake#L399 – Peeja Jun 21 '13 at 13:39
  • It looks like the database is created from 'schema.rb' in `db:test:load` which `test:prepare` calls after `db:test:prepare`. But it also looks like `db:test:load` is invoked directly from from `db:test:prepare`. – Kris Jun 23 '13 at 20:30
  • I see that in the code, but I'm pretty sure that a (successful) `Rake::Task#invoke` shows up in the `rake --trace` output, and I don't see it actually happening. Curious. – Peeja Jun 24 '13 at 14:26
21

You can also try

rake db:migrate RAILS_ENV=test

which works as

db:test:prepare

does:)

meejoe
  • 235
  • 2
  • 2
  • 9
    It doesn't, actually. `rake db:migrate RAILS_ENV=test` will migrate the test database. `rake db:test:prepare` will (would) load the schema into the test database, which is faster and less error-prone. – Peeja Sep 23 '14 at 13:50
11

I still have trouble sometimes in sorting this problem out when I just follow one person's answer so I have thrown a couple together to get better results. Here are the steps I take, not sure which ones are unnecessary, but it works in the end.

  1. add ActiveRecord::Migration.maintain_test_schema! to the top of the test_helper.rb file.
  2. rake test:prepare
  3. rake db:migrate
  4. rake db:migrate RAILS_ENV=test

Then when I run bundle exec rake test I get clean results every time with no pending migrations. (This is what I do right after generating the scaffold the first time). Someone feel free to correct me if you know for sure that one of these steps is absolutely not necessary, but this is how I make sure it works every time.

SilasOtoko
  • 133
  • 2
  • 9
3

I've found I have this problem when using chruby to manage my ruby versions. Rails calls bin/rails db:test:prepare via the system command. This doesn't take advantage of chrubys $PATH env var, so it runs as whatever the system ruby is, and fails because of missing gems typically. Unfortunately, I don't currently have a good solution for this.

Jesse Brown
  • 709
  • 4
  • 4
  • 2
    Wow, how did you find it out? I'm also using `chruby` and `ActiveRecord::Migration.maintain_test_schema!` simply doesn't work for me. How did you debug it? Any fixes? – Paweł Gościcki Nov 06 '16 at 23:53
0

It's hard to provide an answer for your case given the information you provided.

In my case it failed to "maintain the schema" (spec/rails_helper.rb, ActiveRecord::Migration.maintain_test_schema!). Because I used the postgres database (running in a docker container). In this case there are 2 solutions:

  • switch to a separate database (something other than postgres)
  • use bin/rails db:migrate RAILS_ENV=test

To give you some more details, what maintain_test_schema! does is it runs bin/rails db:test:prepare if there are pending migrations.

x-yuri
  • 16,722
  • 15
  • 114
  • 161
-1

You can try to set variable BEFORE command, like this. This statement solved my problem:

RAILS_ENV=test rake db:migrate
Unkas
  • 3,522
  • 2
  • 19
  • 23