2016-10-25 105 views
4

我有两个使用相同数据库的Rails应用程序。一个应用程序通过迁移来管理数据库,但另一个应用程序正在访问它。如何阻止rspec在测试前丢弃测试数据库

由于某些原因,当我在不管理数据库的应用程序中使用RSpec运行测试时,它会在运行测试之前删除数据库。但是,因为这个应用程序不知道如何重新创建数据库,所有的测试都会失败。

我该如何告诉RSpec不要丢弃数据库,就这样使用它?

回答

6

如果您不需要迁移数据库,你可以重新定义rspecs护栏 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,其中设置了分贝。

Rails 4.0(或可能更早)以来存在任务test:prepare。这个任务也存在于Rails 5.0中。这是铁轨添加测试相关设置的一个钩子。你可以用rake -W test:prepare来检查它的定义。那 的任务就是打你可以用rake --trace spec查询。

ActiveRecord uses this task检查迁移状态并设置数据库。

当这个任务没有被调用,没有数据库将被丢弃或创建。

但是请注意,当其他一些宝石使用test:prepare作为钩子插入测试时,它将不起作用。

编辑:

由于Rails的4.1,你可以设置内config/environments/test.rbconfig.active_record.maintain_test_schema = false。这样Rails不应该再尝试迁移你的测试模式。

+0

我有兴趣试图更好地理解你的解决方案,但是我对于如何防止数据库因为schema.rb不存在而被丢弃和重建失败感到有点困惑。从我可以收集的内容中,它只是简单地将调用移除到'Rake :: Task [“test:prepare”]。invoke',它只是运行迁移,然后才声明该任务 - 这意味着pre Rails 4.1.0。对于Rails 4.1.0及更高版本,调用甚至不会发生。 – David

+0

由于Rails 4或更早的版本,测试:prepare'作为一个钩子存在(https://github.com/rails/rails/blob/4-0-stable/railties/lib/rails/test_unit/testing.rake# L66)。在Rails 5中也存在这个任务(rake -W test:prep)。 ActiveRecord通过检查挂起的迁移来扩展此任务(https:// github。COM /导轨/导轨/ BLOB/4-2稳定/ ActiveRecord的/ lib目录/ active_record/railties/databases.rake#L360)。在这个任务中,下降也会发生。当'test:prepare'未被调用时,不会删除或创建数据库。你必须确保测试数据库存在,但这是给出的问题。 – slowjack2k

+0

谢谢你的出色解释:)似乎有一些错误信息在我身边浮动,我甚至更加困惑,因为在我的宝石本身中,这个任务甚至没有被击中。也许值得考虑的是将解释也加入到解决方案中 - 我认为它确实增加了价值。 – David

2

理想情况下,RSpec应该重新初始化数据库进行测试,以确保您的环境处于可靠,可预测的状态。

你可以做的是为不管理数据库的Rails应用程序执行rake db:schema:dump来生成schema.rb然后由RSpec使用 - 当然要确保你的database.yml测试配置不是不指向您的实时数据库。

我知道这在技术上并不是解决您的问题的方法,但应该防止导致您的测试失败的潜在问题。