【发布时间】:2016-10-25 11:08:20
【问题描述】:
我有两个使用相同数据库的 Rails 应用程序。一个应用通过迁移来管理数据库,而另一个只是访问它。
由于某种原因,当我在不管理数据库的应用程序中使用 RSpec 运行测试时,它会在运行测试之前删除数据库。但是因为这个应用程序不知道如何重新创建数据库,所以所有的测试都会失败。
如何告诉 RSpec 不要删除数据库,直接使用它?
【问题讨论】:
标签: ruby-on-rails rspec
我有两个使用相同数据库的 Rails 应用程序。一个应用通过迁移来管理数据库,而另一个只是访问它。
由于某种原因,当我在不管理数据库的应用程序中使用 RSpec 运行测试时,它会在运行测试之前删除数据库。但是因为这个应用程序不知道如何重新创建数据库,所以所有的测试都会失败。
如何告诉 RSpec 不要删除数据库,直接使用它?
【问题讨论】:
标签: ruby-on-rails rspec
如果你不需要迁移数据库你可以重新定义 rspecs-rails
spec:prepare这样的任务:
lib/tasks/patch_rspec_rails.rb
Rake::Task["spec:prepare"].clear
namespace :spec do
task :prepare do
ENV['RACK_ENV'] = ENV['RAILS_ENV'] = 'test'
end
end
原来的spec:prepare任务调用test:prepare,它设置了数据库。
任务test:prepare 存在于Rails 4.0(或者可能更早)。这个任务也存在于 Rails 5.0 中。它是 railsties 添加测试相关设置的钩子。您可以使用rake -W test:prepare 检查其定义。那
任务被击中,你可以通过rake --trace spec查看。
ActiveRecord uses this task 检查迁移状态并设置数据库。
如果不调用此任务,则不会删除或创建任何 db。
但请注意,当其他一些 gem 使用 test:prepare 作为钩子来插入测试时,它将不起作用。
编辑:
从 Rails 4.1 开始,您可以在 config/environments/test.rb 中设置 config.active_record.maintain_test_schema = false。这样,Rails 不应再尝试迁移您的测试模式。
【讨论】:
Rake::Task["test:prepare"].invoke 的调用,它只是运行迁移,然后只有在声明了该任务时——这意味着Rails 4.1.0 之前的版本。对于 Rails 4.1.0 及更高版本,该调用甚至不会发生。
test:prepare 以钩子 (github.com/rails/rails/blob/4-0-stable/railties/lib/rails/…) 的形式存在。在 Rails 5 中也存在这个任务(rake -W test:prep)。 ActiveRecord 通过检查未决迁移 (github.com/rails/rails/blob/4-2-stable/activerecord/lib/…) 扩展了此任务。在此任务中,也会发生下降。当test:prepare 未被调用时,不会删除或创建数据库。您必须确保测试数据库存在,但这是问题给出的。
rake -W spec,我自己的 spec:prepare 任务的调用方式与 MRI ruby 中的调用方式相同。
ActiveRecord::Migration.maintain_test_schema! 的帮助。
理想情况下,RSpec 应该重新初始化数据库以进行测试,以确保您的环境处于可靠、可预测的状态。
您可以为不管理数据库的 Rails 应用程序执行 rake db:schema:dump 以生成 schema.rb,然后 RSpec 将使用它 - 当然要确保您的 database.yml 测试配置没有指向您的实时数据库。
我知道这在技术上不是您问题的解决方案,但它应该可以防止导致您的测试失败的潜在问题。
【讨论】: