Rails 4: 如何重置测试数据库?

我在 Rails 4上,注意到我的一些 RSpec 测试失败了,因为我的一些测试重构使用了 before 过滤器(可能是因为事务)。这篇文章描述了一个类似的问题:

在某些运行之后没有清除 Rails 测试数据库

代替使用 DatabaseCleanergem,是否有 rake 命令来清除测试数据库?我相信 rake db:test:prepare在 Rails 4中是不被推荐的。此外,如果在事务之前像

`post :create, user: Fabricate.attributes_for(:user)`

是持久的,是否有另一种重构方法来避免手动清除测试数据库的需要?

92855 次浏览

You can add an after filter deleting all the entries from the concerned tables.

An overkill solution would be:

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

You could make this all in a rake task and run that.

Another solution from here is to include the following your spec_helper.rb file

config.after :all do
ActiveRecord::Base.subclasses.each(&:delete_all)
end

Disclaimer: I have not tested this and you should read the SO post as it may not work in all situations.

That being said, I would recommend using the database cleaner gem to avoid situations such as this.

It can be:

(For rails Rails 5+)

bundle exec rails db:reset RAILS_ENV=test

For previous versions

bundle exec rake db:reset RAILS_ENV=test

In theory this ActiveRecord::Migration.maintain_test_schema! should do the trick. Put it in rails_helper.rb

I ended up writing a simple rake task that drops/migrates (or drops & migrates) all test and development databases, depending on the command executed.

It includes functionality to prompt the user as to whether they would like to continue when an error occurs, and uses Open3's popen3 method (such that we can access stdin, stdout and stderr; and any failed commands don't result in the rake task's process aborting (unlike when using system)).

Hopefully this helps someone. :)

https://github.com/xtrasimplicity/rake_all_db_helper/

edit: This will need to be manually executed from your shell, whenever you would like to clear your database, however.

Sometimes you might need to run this command (optional)

rails db:environment:set RAILS_ENV=test

But for sure to wipe out your test database should be as easy as:

rails db:drop db:create db:migrate RAILS_ENV=test

If you don't want to seed the test database (undesirable in my case), try this:

bundle exec rails db:drop db:create db:migrate RAILS_ENV=test

It will 1. drop, 2. create, and 3. migrate (but not seed) the test database.